Merge pull request #19671 from holiman/usbfix
account/usbwallet: abort usb enumeration after failures
This commit is contained in:
		@@ -20,6 +20,7 @@ import (
 | 
				
			|||||||
	"errors"
 | 
						"errors"
 | 
				
			||||||
	"runtime"
 | 
						"runtime"
 | 
				
			||||||
	"sync"
 | 
						"sync"
 | 
				
			||||||
 | 
						"sync/atomic"
 | 
				
			||||||
	"time"
 | 
						"time"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/ethereum/go-ethereum/accounts"
 | 
						"github.com/ethereum/go-ethereum/accounts"
 | 
				
			||||||
@@ -64,6 +65,7 @@ type Hub struct {
 | 
				
			|||||||
	// TODO(karalabe): remove if hotplug lands on Windows
 | 
						// TODO(karalabe): remove if hotplug lands on Windows
 | 
				
			||||||
	commsPend int        // Number of operations blocking enumeration
 | 
						commsPend int        // Number of operations blocking enumeration
 | 
				
			||||||
	commsLock sync.Mutex // Lock protecting the pending counter and 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.
 | 
					// NewLedgerHub creates a new hardware wallet manager for Ledger devices.
 | 
				
			||||||
@@ -138,6 +140,10 @@ func (hub *Hub) refreshWallets() {
 | 
				
			|||||||
	if elapsed < refreshThrottling {
 | 
						if elapsed < refreshThrottling {
 | 
				
			||||||
		return
 | 
							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
 | 
						// Retrieve the current list of USB wallet devices
 | 
				
			||||||
	var devices []usb.DeviceInfo
 | 
						var devices []usb.DeviceInfo
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -156,13 +162,17 @@ func (hub *Hub) refreshWallets() {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
	infos, err := usb.Enumerate(hub.vendorID, 0)
 | 
						infos, err := usb.Enumerate(hub.vendorID, 0)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
 | 
							failcount := atomic.AddUint32(&hub.enumFails, 1)
 | 
				
			||||||
		if runtime.GOOS == "linux" {
 | 
							if runtime.GOOS == "linux" {
 | 
				
			||||||
			// See rationale before the enumeration why this is needed and only on Linux.
 | 
								// See rationale before the enumeration why this is needed and only on Linux.
 | 
				
			||||||
			hub.commsLock.Unlock()
 | 
								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
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						atomic.StoreUint32(&hub.enumFails, 0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for _, info := range infos {
 | 
						for _, info := range infos {
 | 
				
			||||||
		for _, id := range hub.productIDs {
 | 
							for _, id := range hub.productIDs {
 | 
				
			||||||
			// Windows and Macos use UsageID matching, Linux uses Interface matching
 | 
								// Windows and Macos use UsageID matching, Linux uses Interface matching
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user