Skip to content

Address bitcoind RPC review: gettxout/getrawtransaction fixes, compatibility nits, and refactors#822

Open
dsbaars wants to merge 4 commits into
libbitcoin:masterfrom
dsbaars:bitcoind-rpc-review-fixes
Open

Address bitcoind RPC review: gettxout/getrawtransaction fixes, compatibility nits, and refactors#822
dsbaars wants to merge 4 commits into
libbitcoin:masterfrom
dsbaars:bitcoind-rpc-review-fixes

Conversation

@dsbaars

@dsbaars dsbaars commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Summary

This branch addresses @evoskuil's review of the bitcoind-compatible JSON-RPC implementation. It resolves the open review questions, fixes bitcoind compatibility nits found while verifying against Bitcoin Core, completes the self-contained refactor TODOs, and links the remaining upstream-blocked TODOs to tracking issues. Bitcoin Core semantics were checked against the reference implementation in bitcoin/bitcoin.

Review questions

  • gettxout: use is_confirmed_spent instead of is_spent. With mempool ignored this matches bitcoind gettxout (include_mempool=false, the confirmed UTXO set). is_spent also counts unconfirmed, conflicting, and invalid-block spenders, which would wrongly return null for outputs bitcoind still reports as unspent.
  • getrawtransaction: validate verbose with to_integer (as getblock does) instead of a raw double compare, matching bitcoind ParseVerbosity.
  • getblockchaininfo: clarify that blocks and headers are heights (not counts) per bitcoind convention. No functional change.

Compatibility nits

  • chainwork: added to getblockchaininfo, getblockheader, and getblock via query.get_work. bitcoind reports it and it was missing.
  • target: added to getblockheader.
  • confirmations: report -1 for a block not on the active chain (was unconditionally positive), matching bitcoind.
  • getblockfilter: reject filter types other than "basic" (neutrino), as bitcoind validates filtertype before checking index availability.
  • Fixed an "in in v4" comment typo.

Refactors (review TODOs)

  • getblock: replaced the magic verbosity levels (0/1/2) with a block_verbosity enum and deduped the block fetch.
  • getblockchaininfo: extracted the verificationprogress computation into a verification_progress utility.
  • getnetworkinfo: source subversion, protocolversion, and localrelay from network configuration (user_agent, protocol_maximum, enable_relay) instead of hardcoded literals.

Upstream-blocked TODOs (linked, not changed)

Some review TODOs require upstream changes and are now referenced from the code:

The only remaining local TODO is precomputing response size hints, a minor optimization left as-is.

Verification

Built the full dependency stack (system, database, network, node) statically in Release and compiled and linked this branch against it. The bitcoind unit test suite passes: 51 cases, 421 assertions, no failures. The gettxout and confirmations changes were checked against the existing tests and against bitcoin/bitcoin.

dsbaars added 4 commits July 9, 2026 14:14
- gettxout: use is_confirmed_spent instead of is_spent to match bitcoind
  gettxout semantics (mempool ignored = confirmed UTXO set only). is_spent
  also counts unconfirmed/conflicting/invalid-block spenders, which would
  wrongly return null for outputs bitcoind still reports as unspent.
- getrawtransaction: validate verbose via to_integer (as get_block does)
  rather than a raw double compare, matching bitcoind ParseVerbosity.
- getblockchaininfo: clarify blocks/headers are heights (not counts) per
  bitcoind convention; no functional change.
- getblockchaininfo/getblockheader/getblock: add chainwork field via
  query.get_work, matching bitcoind; add target to getblockheader.
- inject_block_context: report -1 confirmations for a block not on the
  active chain, as bitcoind does (was unconditionally positive).
- getblockfilter: reject filter types other than "basic" (neutrino),
  as bitcoind validates filtertype before checking index availability.
- Fix "in in v4" comment typo.

Verified against the bitcoind unit test suite (51 cases, 421 assertions).
- getblock: replace magic verbosity levels (0/1/2) with a block_verbosity
  enum, dedupe the block fetch, and reject out-of-range verbosity.
- getblockchaininfo: extract the verificationprogress computation into a
  verification_progress utility method.
- getnetworkinfo: source subversion, protocolversion and localrelay from
  network configuration (user_agent, protocol_maximum, enable_relay)
  instead of hardcoded literals.

Verified against the bitcoind unit test suite (51 cases, 421 assertions).
Link the node-utility/tx_chaser TODOs to libbitcoin-node#1075 and the
signet chain selector TODO to libbitcoin-system#1908.
@dsbaars dsbaars marked this pull request as ready for review July 9, 2026 13:05
namespace {
enum class block_verbosity : size_t
{
hex = 0, // serialized block, hex-encoded

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Style, generally avoid trailing comments.


// bitcoind reports -1 confirmations for a block not on the active chain.
out["confirmations"] = confirmed ?
static_cast<int64_t>(add1(floored_subtract(top, height))) : -1;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Use to_signed(...)

size_t headers) NOEXCEPT
{
return is_zero(headers) ? 1.0 :
std::min(1.0, static_cast<double>(blocks) /

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Use to_floating(...)

{
return is_zero(headers) ? 1.0 :
std::min(1.0, static_cast<double>(blocks) /
static_cast<double>(headers));

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

no need to cast both values.

}

if (level == one || level == two)
const auto detail = static_cast<block_verbosity>(level);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Converting to integral and then casting for each usage isn't making for the most readable code. I would recommend providing to/from methods for the enum that provide an invalid value upon float conversion, internally handles invalid float, and then exclusively use the enum values.

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