From e6df5f8798247533075a625445701113b5fd63d5 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:09 +0800 Subject: [PATCH] account/usbwallet: abort usb enumeration after failures (#19671) --- accounts/usbwallet/hub.go | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/accounts/usbwallet/hub.go b/accounts/usbwallet/hub.go index f2656bdf47..4041359ad3 100644 --- a/accounts/usbwallet/hub.go +++ b/accounts/usbwallet/hub.go @@ -20,6 +20,7 @@ import ( "errors" "runtime" "sync" + "sync/atomic" "time" "github.com/XinFinOrg/XDPoSChain/accounts" @@ -64,6 +65,7 @@ type Hub struct { // TODO(karalabe): remove if hotplug lands on Windows commsPend int // Number of operations blocking enumeration commsLock sync.Mutex // Lock protecting the pending counter and enumeration + enumFails uint32 // Number of times enumeration has failed } // NewLedgerHub creates a new hardware wallet manager for Ledger devices. @@ -138,6 +140,10 @@ func (hub *Hub) refreshWallets() { if elapsed < refreshThrottling { return } + // If USB enumeration is continually failing, don't keep trying indefinitely + if atomic.LoadUint32(&hub.enumFails) > 2 { + return + } // Retrieve the current list of USB wallet devices var devices []usb.DeviceInfo @@ -156,13 +162,17 @@ func (hub *Hub) refreshWallets() { } infos, err := usb.Enumerate(hub.vendorID, 0) if err != nil { + failcount := atomic.AddUint32(&hub.enumFails, 1) if runtime.GOOS == "linux" { // See rationale before the enumeration why this is needed and only on Linux. hub.commsLock.Unlock() } - log.Error("error enumerating USB enumeration: ", "code", err) + log.Error("Failed to enumerate USB devices", "hub", hub.scheme, + "vendor", hub.vendorID, "failcount", failcount, "err", err) return } + atomic.StoreUint32(&hub.enumFails, 0) + for _, info := range infos { for _, id := range hub.productIDs { // Windows and Macos use UsageID matching, Linux uses Interface matching