@@ -128,6 +128,15 @@ func (w *ledgerWallet) offline() bool {
128
128
return w .version == [3 ]byte {0 , 0 , 0 }
129
129
}
130
130
131
+ // failed returns if the USB device wrapped by the wallet failed for some reason.
132
+ // This is used by the device scanner to report failed wallets as departed.
133
+ func (w * ledgerWallet ) failed () bool {
134
+ w .lock .RLock ()
135
+ defer w .lock .RUnlock ()
136
+
137
+ return w .failure != nil
138
+ }
139
+
131
140
// Open implements accounts.Wallet, attempting to open a USB connection to the
132
141
// Ledger hardware wallet. The Ledger does not require a user passphrase so that
133
142
// is silently discarded.
@@ -231,6 +240,8 @@ func (w *ledgerWallet) heartbeat() {
231
240
w .lock .Lock ()
232
241
if err := w .resolveVersion (); err == usb .ERROR_IO || err == usb .ERROR_NO_DEVICE {
233
242
w .failure = err
243
+ w .close ()
244
+
234
245
fail = err
235
246
}
236
247
w .lock .Unlock ()
@@ -253,15 +264,29 @@ func (w *ledgerWallet) Close() error {
253
264
w .lock .Lock ()
254
265
defer w .lock .Unlock ()
255
266
256
- if err := w .device .Close (); err != nil {
267
+ w .quit = nil
268
+ if err := w .close (); err != nil {
257
269
return err
258
270
}
259
- w .device , w .input , w .output , w .paths , w .quit = nil , nil , nil , nil , nil
260
- w .version = [3 ]byte {}
261
-
262
271
return herr // If all went well, return any health-check errors
263
272
}
264
273
274
+ // close is the internal wallet closer that terminates the USB connection and
275
+ // resets all the fields to their defaults. It assumes the lock is held.
276
+ func (w * ledgerWallet ) close () error {
277
+ // Allow duplicate closes, especially for health-check failures
278
+ if w .device == nil {
279
+ return nil
280
+ }
281
+ // Close the device, clear everything, then return
282
+ err := w .device .Close ()
283
+
284
+ w .device , w .input , w .output = nil , nil , nil
285
+ w .version , w .paths = [3 ]byte {}, nil
286
+
287
+ return err
288
+ }
289
+
265
290
// Accounts implements accounts.Wallet, returning the list of accounts pinned to
266
291
// the Ledger hardware wallet. If self derivation was enabled, the account list
267
292
// is periodically expanded based on current chain state.
0 commit comments