Skip to content

Show the node's reason when a Bitcoin broadcast is rejected - #1547

Merged
0xh3rman merged 1 commit into
mainfrom
hm/bitcoin-broadcast-reason
Oct 14, 2026
Merged

0xh3rman merged 1 commit into
mainfrom
hm/bitcoin-broadcast-reason

Conversation

@0xh3rman

Copy link
Copy Markdown
Collaborator

Part of #1276. Every Bitcoin-family broadcast rejection reached the user as "HTTP error: status 400", so the app never showed why a send failed.

Blockbook answers a rejected sendtx with HTTP 400 and a plain {"error":"..."} body. gem_client only parses the {"error":{"message":...}} shape, so it kept the 400 as ClientError::Http and the node's reason was dropped. The message quoted in #1276 is dynode's normalized broadcast log, not what users saw.

  1. BitcoinClient::broadcast_transaction decodes the rejected body with ClientError::decode_body and returns it as the broadcast result when it carries an error, so the existing mapper shows the node's reason, e.g. -26: insufficient fee, rejecting replacement ...
  2. Any other failure keeps the original ClientError, so the gateway still reads its HTTP status; a structured error body already arrives as ClientError::Response with the node's message
  3. Test covers a plain 400 rejection and an unreadable 502

The root cause of #1276 and the options for preventing it are in the issue thread.

)

Blockbook rejects sendtx with HTTP 400 and a plain {"error":"..."} body. gem_client only reads the {"error":{"message":...}} shape, so it kept the 400 as ClientError::Http and every Bitcoin-family rejection reached the user as "HTTP error: status 400". The text in #1276 is dynode's normalized log line, not what the app showed.

BitcoinClient::broadcast_transaction now decodes a rejected body with ClientError::decode_body and returns it as the broadcast result when it carries an error, so the existing mapper shows the node's reason (for #1276, "-26: insufficient fee, rejecting replacement ..."). Any other failure keeps the original ClientError, so the gateway still reads its HTTP status. A structured error body already arrives as ClientError::Response, whose text is the node's message.

Checks: core just test gem_bitcoin; cargo clippy -p gem_bitcoin --all-features -D warnings.
@0xh3rman
0xh3rman merged commit d53a0ec into main Oct 14, 2026
6 checks passed
@0xh3rman
0xh3rman deleted the hm/bitcoin-broadcast-reason branch October 14, 2026 09:12
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.

1 participant