Skip to content

fix(walletapi): add configurable 10s timeout to RPC calls#25

Open
moralpriest wants to merge 1 commit into
DEROFDN:community-devfrom
moralpriest:fix/walletapi-rpc-call-timeout
Open

fix(walletapi): add configurable 10s timeout to RPC calls#25
moralpriest wants to merge 1 commit into
DEROFDN:community-devfrom
moralpriest:fix/walletapi-rpc-call-timeout

Conversation

@moralpriest

Copy link
Copy Markdown

Add a package-level rpcCallTimeout variable (default 10s) used in Client.Call to 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

  • Add var rpcCallTimeout = 10 \* time.Second package-level variable
  • Wrap Client.Call with context.WithTimeout(context.Background(), rpcCallTimeout)

Notes

  • All DERO RPC calls complete in <1s under normal conditions
  • 10s default provides 10x margin on WiFi/4G, 5x margin on 3G
  • Wallets can override rpcCallTimeout to tune for their platform
  • Consistent with existing var timeout pattern in daemon_connectivity_loop.go

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 Dirtybird99 left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

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:

  1. 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.
  2. DERO.SendRawTransaction now 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.
  3. The largest payloads through this path are DERO.GetBlock/DERO.GetTransaction during 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

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

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)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Suggested change
ctx, cancel := context.WithTimeout(context.Background(), rpcCallTimeout)
ctx, cancel := context.WithTimeout(context.Background(), RPCCallTimeout)

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