fix(walletapi): add configurable 10s timeout to RPC calls#25
Open
moralpriest wants to merge 1 commit into
Open
fix(walletapi): add configurable 10s timeout to RPC calls#25moralpriest wants to merge 1 commit into
moralpriest wants to merge 1 commit into
Conversation
Add a package-level `rpcCallTimeout` variable (default 10s) used in `Client.Call` to prevent RPC calls from hanging indefinitely on half-open WebSocket connections. This is especially important on mobile where NAT timeouts silently kill connections without TCP-level detection. All JSON-RPC calls (GetEncryptedBalance, GetInfo, SendRawTransaction, etc.) complete in <1s under normal conditions; the 10s default provides 10x margin on normal networks and 5x margin on degraded connections. Wallets can override `rpcCallTimeout` to tune for their platform.
Dirtybird99
reviewed
Jul 11, 2026
Dirtybird99
left a comment
There was a problem hiding this comment.
Reviewed against the community-dev base (2cffea05). The timeout pattern is correct (context.WithTimeout + defer cancel() around a unary CallResult), and it has a nice side benefit: Keep_Connectivity's DERO.Ping also flows through Client.Call, so the watchdog ping can no longer hang on a half-open socket either.
Three notes:
- The description says wallets can override
rpcCallTimeout, but it's unexported — consumers importing walletapi (e.g. Engram) can't set it. Suggest exporting it (inline suggestions below) or adding a setter. DERO.SendRawTransactionnow also times out at 10s. A timeout on submit is ambiguous — the daemon may have accepted the tx while the wallet reports failure, which invites a double-send retry from wallet UIs. Worth excluding the send path or documenting the ambiguity.- The largest payloads through this path are
DERO.GetBlock/DERO.GetTransactionduring history restore; on very slow links a hard 10s cap can make restores fail repeatedly. Probably acceptable, but worth a note.
| var daemon_height int64 | ||
| var daemon_topoheight int64 | ||
| var last_event_topoheight_tracked int64 | ||
| var rpcCallTimeout = 10 * time.Second // per-call timeout preventing hangs on dead connections |
There was a problem hiding this comment.
Suggested change
| var rpcCallTimeout = 10 * time.Second // per-call timeout preventing hangs on dead connections | |
| var RPCCallTimeout = 10 * time.Second // per-call timeout preventing hangs on dead connections; consumers may override |
|
|
||
| func (cli *Client) Call(method string, params interface{}, result interface{}) error { | ||
| return cli.RPC.CallResult(context.Background(), method, params, result) | ||
| ctx, cancel := context.WithTimeout(context.Background(), rpcCallTimeout) |
There was a problem hiding this comment.
Suggested change
| ctx, cancel := context.WithTimeout(context.Background(), rpcCallTimeout) | |
| ctx, cancel := context.WithTimeout(context.Background(), RPCCallTimeout) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Add a package-level
rpcCallTimeoutvariable (default 10s) used inClient.Callto prevent RPC calls from hanging indefinitely on half-open WebSocket connections.Problem
On mobile, NAT timeouts silently kill WebSocket connections without TCP-level detection. Without a per-call timeout, any in-flight RPC call blocks the sync loop indefinitely. The only recovery is the 90s stall detector in Engram, but by that time the sync loop has already been frozen for 90+ seconds.
Changes
var rpcCallTimeout = 10 \* time.Secondpackage-level variableClient.Callwithcontext.WithTimeout(context.Background(), rpcCallTimeout)Notes
rpcCallTimeoutto tune for their platformvar timeoutpattern in daemon_connectivity_loop.go