Skip to content

rpcclient: add context.Context support for HTTP POST mode#2506

Draft
seeforschauer wants to merge 6 commits into
btcsuite:masterfrom
seeforschauer:rpcclient-context-support
Draft

rpcclient: add context.Context support for HTTP POST mode#2506
seeforschauer wants to merge 6 commits into
btcsuite:masterfrom
seeforschauer:rpcclient-context-support

Conversation

@seeforschauer

Copy link
Copy Markdown

Change Description

Add context.Context support to rpcclient's HTTP POST mode, allowing callers to cancel or timeout individual RPC calls. Fixes #2499.

Currently, rpcclient methods like GetBlockCount() don't accept a context, which means callers have no way to cancel or set deadlines on individual RPC calls. In HTTP POST mode, handleSendPostMessage uses http.NewRequest without context, and the 10-retry loop doesn't respect external cancellation.

Changes

  • Add ctx field to jsonRequest struct
  • Use http.NewRequestWithContext in handleSendPostMessage when ctx is set
  • Respect context cancellation during retry backoff (select on reqCtx.Done())
  • Add SendCmdWithContext(ctx, cmd) to Client
  • Add GetBlockCountWithContext(ctx) as the first context-aware method variant
  • Existing methods are unchanged — fully backwards compatible

Design decisions

  • SendCmdWithContext mirrors SendCmd with an added ctx parameter
  • When ctx is nil (e.g., from existing SendCmd callers), context.Background() is used as fallback
  • Context cancellation during retry backoff returns immediately instead of waiting for next attempt
  • Additional *WithContext methods for other RPC calls can be added incrementally in follow-up PRs

Steps to Test

go test ./rpcclient/ -run TestGetBlockCountWithContext -v
go test ./rpcclient/ -run TestSendCmdWithContext -v
go test ./rpcclient/ -run TestGetBlockCount_Backwards -v

Pull Request Checklist

Testing

  • Your PR passes all CI checks.
  • Tests covering the positive and negative (error paths) are included.
  • Bug fixes contain tests triggering the bug to prevent regressions.

Code Style and Documentation

  • The change is not insubstantial.
  • The change obeys the Code Documentation and Commenting guidelines, and lines wrap at 80.
  • Commits follow the Ideal Git Commit Structure.
  • Any new logging statements use an appropriate subsystem and logging level.

Add SendCmdWithContext and GetBlockCountWithContext methods that
propagate a context.Context to the underlying HTTP request. This
allows callers to cancel or timeout individual RPC calls.

Changes:
- Add ctx field to jsonRequest struct
- Use http.NewRequestWithContext in handleSendPostMessage
- Respect context cancellation during retry backoff
- Add SendCmdWithContext to Client
- Add GetBlockCountWithContext as the first context-aware method
- Existing methods are unchanged (non-breaking)

Fixes btcsuite#2499
Comment thread rpcclient/chain.go
Comment thread rpcclient/context_test.go Outdated
Comment thread rpcclient/infrastructure.go Outdated
Comment thread rpcclient/infrastructure.go Outdated
Refactor SendCmd to delegate to SendCmdWithContext instead of
duplicating the marshalling logic. SendCmdWithContext is now the
single implementation; SendCmd passes context.Background().

Add a context error check after httpClient.Do in the retry loop
so a cancelled context bails out immediately instead of retrying.

Use camelCase for test function names.
@guibressan

Copy link
Copy Markdown

Diff looks good, tests passing.

Nice work @seeforschauer!

@saubyk saubyk requested a review from kcalvinalvin April 7, 2026 00:15
@saubyk saubyk added this to the v0.25.1 milestone Apr 7, 2026
@seeforschauer

Copy link
Copy Markdown
Author

@Roasbeef all four items addressed — mind taking another look when you get a chance?

@saubyk saubyk requested a review from Roasbeef April 10, 2026 14:30

@kcalvinalvin kcalvinalvin left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Looks good overall. Some minor test related issues that I saw

Comment thread rpcclient/context_test.go Outdated
Comment thread rpcclient/context_test.go
@saubyk saubyk requested a review from kcalvinalvin April 17, 2026 14:30
@seeforschauer

Copy link
Copy Markdown
Author

@kcalvinalvin pls review

…-support

# Conflicts:
#	rpcclient/infrastructure.go
@Roasbeef Roasbeef removed this from the v0.25.1 milestone May 14, 2026
@seeforschauer

Copy link
Copy Markdown
Author

@Roasbeef would you please review once more?

Comment thread address/base58/README.md
## Examples

* [Decode Example](http://godoc.org/github.com/btcsuite/btcd/address/v2/base58#example-Decode)
* [Decode Example](http://godoc.org/github.com/btcsuite/btcd/address/v2/base58#example-Decode)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I get that these are easy (probably automatic) fixes but it does make reviewing a bit more annoying since I believe all the reviewers read git diffs commit by commit

@kcalvinalvin

Copy link
Copy Markdown
Collaborator

The code looks good. Though the tests aren't doing much.

These test all pass even when the context is dropped in GetBlockCountWithConext:

  • TestGetBlockCountWithContextSuccess
  • TestGetBlockCountBackwardsCompatible
  • TestGetBlockCountWithContextRPCError
  • TestHandleSendPostMessageNilCtxFallsBackToBackground

Ran the tests with this code:

[I] calvin@nixos ~/b/b/b/rpcclient ((6e5bb34c)) [1]> git diff
diff --git a/rpcclient/chain.go b/rpcclient/chain.go
index a5cedc64..6381534d 100644
--- a/rpcclient/chain.go
+++ b/rpcclient/chain.go
@@ -301,7 +301,8 @@ func (c *Client) GetBlockCountWithContext(

        cmd := btcjson.NewGetBlockCountCmd()
        return FutureGetBlockCountResult(
-               c.SendCmdWithContext(ctx, cmd),
+               //c.SendCmdWithContext(ctx, cmd),
+               c.SendCmdWithContext(context.Background(), cmd),
        ).Receive()
 }

Like the tests are implementing the handler in the test and is just checking if that works. I don't think that's useful really.

I feel that the actual code is mergeable. The tests... eh.

Another nit is the git commit format. I'd prefer the follow up commits to be amended into the originals. But these aren't a blocker.

@seeforschauer seeforschauer marked this pull request as draft June 5, 2026 09:58
@seeforschauer

Copy link
Copy Markdown
Author

updated

@saubyk

saubyk commented Jun 16, 2026

Copy link
Copy Markdown
Collaborator

Hi @seeforschauer why is this pr in draft status?

@kcalvinalvin

kcalvinalvin commented Jun 23, 2026

Copy link
Copy Markdown
Collaborator

The latest commit ccbcd30 fixes the test problems I pointed out. LGTM.

Still not a fan of the commit order but that's not a stopper

@kcalvinalvin kcalvinalvin left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Looks good

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.

rpcclient: add context.Context support to RPC methods

5 participants