Skip to content

backend: avoid panic on electrum timeout#3902

Merged
strmci merged 1 commit intoBitBoxSwiss:masterfrom
strmci:avoid_panic_on_electrum_timeout
Mar 6, 2026
Merged

backend: avoid panic on electrum timeout#3902
strmci merged 1 commit intoBitBoxSwiss:masterfrom
strmci:avoid_panic_on_electrum_timeout

Conversation

@strmci
Copy link
Collaborator

@strmci strmci commented Mar 2, 2026

Timeouts like server busy - request timed out/context deadline
exceeded can happen on slow or overloaded Electrum backends.
In this flow we should degrade gracefully, not crash the app. This
change removes panic paths in BTC sync/connection handling and
ensures async subscription errors trigger failover instead of being
silently dropped. The backend now marks the account
as fatal/reloads state and keeps the process alive, allowing
recovery (e.g. reset to defaults or switch server).

@benma benma self-requested a review March 3, 2026 08:48
Comment on lines 77 to 109
func (f *failoverClient) HeadersSubscribe(result func(header *types.Header)) {
failover.Subscribe(
failover.SubscribeAlwaysFailover(
f.failover,
func(c *client, result func(*types.Header, error)) {
c.HeadersSubscribe(func(header *types.Header, err error) {
result(header, err)
})
c.HeadersSubscribe(result)
},
func(header *types.Header, err error) {
if err != nil {
// Can only happen if the failover client is closed.
return
}
result(header)
})
}

func (f *failoverClient) RelayFee() (btcutil.Amount, error) {
return failover.Call(f.failover, func(c *client) (btcutil.Amount, error) {
return c.RelayFee()
})
}

func (f *failoverClient) ScriptHashGetHistory(scriptHashHex blockchain.ScriptHashHex) (blockchain.TxHistory, error) {
return failover.Call(f.failover, func(c *client) (blockchain.TxHistory, error) {
return c.ScriptHashGetHistory(scriptHashHex)
})
}

func (f *failoverClient) ScriptHashSubscribe(
setupAndTeardown func() func(),
scriptHashHex blockchain.ScriptHashHex,
result func(status string)) {
failover.Subscribe(
failover.SubscribeAlwaysFailover(
f.failover,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why change only these and not all the other functions, is there something special about these two?

I think the other changes in this PR look reasonable, but I would undo the changes here - I am not aware these endpoints ever caused problems, and changing this could have unintended consequences.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks for catching this. codex went a bit out of scope for this PR, and I missed it, removed.

@strmci strmci force-pushed the avoid_panic_on_electrum_timeout branch from dd52ec1 to 7b8a2bf Compare March 3, 2026 12:54
@strmci strmci changed the title backend: avoid panic on electrum timeout and harden failover backend: avoid panic on electrum timeout Mar 3, 2026
Timeouts like server busy - request timed out/context deadline
exceeded can happen on slow or overloaded Electrum backends.
In this flow we should degrade gracefully, not crash the app. This
change removes panic paths in BTC sync/connection handling and
ensures async subscription errors trigger failover instead of being
silently dropped. The backend now marks the account
as fatal/reloads state and keeps the process alive, allowing
recovery (e.g. reset to defaults or switch server).
@strmci strmci force-pushed the avoid_panic_on_electrum_timeout branch from 7b8a2bf to 08747ee Compare March 6, 2026 11:09
@strmci strmci merged commit 8feece8 into BitBoxSwiss:master Mar 6, 2026
16 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants