Repository navigation
rpc: return bip125-replaceable and getblockstats utxo_size_inc so typed Rust clients decode - #1330
Merged
reardencode merged 2 commits intoOct 30, 2026
Merged
Conversation
getmempoolentry, verbose getrawmempool, and verbose getmempoolancestors / getmempooldescendants left out Core's bip125-replaceable. Typed clients such as bitcoincore-rpc require it, so decoding an entry failed with "missing field `bip125-replaceable`" (reardencode#1255). The field is Core's IsRBFOptIn: true when the transaction or an in-mempool ancestor has an input sequence at or below 0xfffffffd. MempoolHub::signals_bip125 checks the tx and its ancestor set under one read lock. Full RBF still replaces an opt-out transaction, as in Core's feature_rbf.py test_fullrbf, so the field is the signal only. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
getblockstats omitted Core's two coins-DB size stats, and selecting either name was an invalid statistic. Typed clients such as bitcoincore-rpc require both, so get_block_stats failed with "missing field `utxo_size_inc`" (reardencode#1255). The Core functional proxy filled them in from Esplora for rpc_getblockstats.py. Each output adds its serialized CTxOut plus Core v32.1's PER_UTXO_OVERHEAD (40: the outpoint and the packed height and coinbase flag), and each spent prevout subtracts the same. utxo_size_inc_actual adds only outputs that enter the UTXO set, the rule utxo_increase_actual already uses. The reconstruct path has the prevouts in hand. A stamped block reads its input edges in one input.body span and each parent's outputs once, and only when the selected stats include a size stat. The stamped outputs pass now also sums total_out, so each tx's outputs are read once and Query::non_coinbase_total_out loses its last caller. The proxy shim (rpc_blockstats.py) and its self-test are deleted; rpc_getblockstats.py passes against the node alone. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
niteshbalusu11
force-pushed
the
rpc/typed-client-fields
branch
from
October 30, 2026 23:07
7b2493e to
bda5015
Compare
Owner
|
I hate this PR because we don't have a UTXO set, but agreed it's the right compatibility thing to do. Thanks! |
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.
Closes #1255.
bitcoincore-rpc0.19 failed to decodegetmempoolentry/ verbosegetrawmempool(missingbip125-replaceable) andgetblockstats(missingutxo_size_inc). Both fields are now returned.bip125-replaceableongetmempoolentry, verbosegetrawmempool, and verbosegetmempoolancestors/getmempooldescendants. It is Core'sIsRBFOptIn: true when the tx or an in-mempool ancestor has an input sequence at or below0xfffffffd. It is not hardcoded totrueas the issue suggests: Core 32.1 still reportsfalsefor an opt-out tx under full RBF (feature_rbf.pytest_fullrbf), and full RBF here still replaces it.MempoolHub::signals_bip125checks the tx and its ancestor set under one read lock. This overlaps the bip125 part of draft rpc: answers Core clients rely on (captaind / bark on rbitcoin) #1191, which has been idle.getblockstatsutxo_size_inc/utxo_size_inc_actual. Each output adds its serializedCTxOutplusPER_UTXO_OVERHEAD, each spent prevout subtracts the same, and_actualadds only outputs that enter the UTXO set. The overhead is 40, Core v32.1'ssizeof(COutPoint) + sizeof(uint32_t). The issue cites Core 31.1, which counted a spent-flag byte (41). This repo pins v32.1. A stamped block reads its input edges in oneinput.bodyspan read and each parent's outputs once, only when the selected stats include a size stat. The stamped outputs pass also sumstotal_outnow, soQuery::non_coinbase_total_outis gone.rpc_blockstats.pyand its self-test are deleted, andrpc_getblockstats.pyruns against the node alone.Not in this PR:
gettxoutsetinfostays-32601.COMPAT.mdlists it as never: the node keeps no UTXO set to hash or count.Proof: the new assertions fail before each fix and pass after. The mempool journey covers a signaling parent, an opt-out child that inherits
true, an opt-out local tx atfalse, and full RBF replacing that tx.getblockstatspins regtest genesis at 116/0, and the stamped and reconstruct paths both match a tally fromgetblockverbosity 3 prevouts for a block with an OP_RETURN output. Core 32.1'srpc_getblockstats.pypasses locally against the node with the shim removed. My first cut used 41, and this script caught it at height 101 (163/75 instead of 161/74). Local fmt, clippy, deny, ast-grep, ratchets,ci-os-smoke.sh, the harness self-tests, and the workspace tests pass. The exceptions areoutbound_refill_journey, which needs sudo for a netns locally, andtip_accept::two_full_senders_both_enqueue, which failed once under workspace load and passed 8/8 alone and in a fullrbitcoin-netsuite run.This changes the Core functional harness, so it needs the
core-functionallabel. I cannot add labels on this repo.🤖 Generated with Claude Code