API-01–API-04 place owners under the
contracts precedence rule. API-05 is the solo-mining generate
path. API-06 is getnetworkhashps snapshot consistency. API-07 is the
BIP22/BIP23 getblocktemplate extras the pinned corepc type does not model.
API-08 is mainnet template operational gates. API-09 is submitheader.
API-10 is GBT client-rule negotiation. API-11 is submitblock decode.
API-12 is GBT proposal request parsing. API-13 is submitblock uncommitted
witness fill. API-14 is Core v31 submitblock / GBT proposal duplicate
vocabulary. API-15 is BIP22 reject-reason mapping. API-16 is GBT
vbrequired always 0. API-17 is Core CheckWitnessMalleation
reject reasons. API-18 is GBT coinbaseaux.flags. API-19 is
prioritisetransaction dummy/fee_delta arity. API-20 is
prioritisetransaction dust-output refusal. API-21 is GBT proposal /
submitblock duplicate for reorged scripts-valid bodies. API-22 is
getmininginfo omitting unset optional fields. API-23 is
estimatesmartfee Core conf_target and estimate_mode gates. API-24
is generateblock Core txid/raw-tx parse errors.
- Owner:
MANIFESTincrates/rpc/src/manifest.rsis the single source of truth for RPC, REST, and ZMQ external interfaces. - A JSON-RPC method answers only when a non-
Unimplementedrow carries its name. Rows cover JSON-RPC, REST prefixes, and ZMQ topics, each with a status (Implemented,Deviation,Extension,Unimplemented) declared against Bitcoin Core 31.x. - Methods marked
UnimplementedreturnRpcError::MethodNotFound(code-32601).
- docs/rpc-reference.md is a generated file rendered
directly from
MANIFEST. It must not be edited by hand. - Regenerate with:
REGEN_RPC_REFERENCE=1 cargo test -p bitcoin-rs-rpc --test manifest_coverage -- --ignored regenerate_reference crates/rpc/tests/manifest_coverage.rsenforces that the checked-in reference matches the code manifest exactly on every CI run.
- JSON-RPC failures map through
RpcError(crates/rpc/src/error.rs): standard JSON-RPC codes (-32700,-32600..=-32603) and Core codes-3(invalid type),-5(not found),-8(invalid parameter),-9(not connected),-10(initial download),-22(deserialization),-25(verify error), and-26(verify rejected). Core-3,-8, and-22messages are the Core text with no wrapper prefix (InvalidType,InvalidParameter,Deserialization). - The node ships no wallet and holds no private key material. Methods that
would reveal, import, create, or use private keys return
RpcError::MethodNotFound. PSBT combination/finalization and descriptor utilities remain supported as they operate without private keys.
- Multi-record queries across chainstate use optimistic tip fencing or
active-tip verification against
BlockTree. If a reorg occurs during assembly, queries return503 Service Unavailablerather than inconsistent data. - Statistical and script index queries are bounded by
QueryBudgetto prevent memory exhaustion.
- Owner:
MiningControl::generateincrates/mining/src/control.rs, implemented byMiningCoordinator::generate_blocksincrates/node/src/mining.rs. - The operation assembles a fresh candidate (no GBT cache), solves it, then
either submits through
Chainstate::apply_blockor dry-validates throughChainstate::validate_block(ARCH-07). Persistence and tip advancement are conditional onsubmit; validation is not. - Each submitted block is a separate commit. An error after N successful
submissions leaves those N blocks durable. Callers own retry after reading
the applied tip.
nblocksis not capped; the result vector grows one block at a time. generatetoaddressaccepts only a network-valid address, uses mempool package selection, collects fees, and always submits.generateblockaccepts an address or descriptor (require_checksum = false; a supplied checksum is verified). Ranged/multipath descriptors are refused. The transactions array is required (an explicit[]is coinbase-only). Listed order is kept, those fees are not added to the coinbase, 64-character hex is a mempool txid, and decoded raw transactions are included without mempool admission. Extra positional arguments are rejected. Transaction parse errors areAPI-24.
- Owner:
MiningCoordinator::network_hash_psincrates/node/src/mining.rs. Height resolution has one owner:resolve_hash_ps_start. - The method takes the block-tree read lock, then loads one applied-tip snapshot. Height checks and the hash-rate walk use that snapshot and that locked tree, not a second tip load.
nblocks(lookup) must be a positive count or-1(since the last difficulty retarget). Otherwise the RPC is Core-8(RpcError::InvalidParameter) with"Invalid nblocks. Must be a positive number or -1."heightmust be-1(the snapshot tip) or an existing applied-chain height on that snapshot. Heights below-1, above the snapshot tip, or in range but unwalkable from that tip, are Core-8with"Block does not exist at specified height", not a zero hash-rate.- An empty chain with
height == -1estimates0.0. getmininginfo'snetworkhashpsis best-effort from the applied tip and does not use this RPC height-validation error path.
- Owner:
MiningCoordinator::template_from_candidateincrates/node/src/mining.rs; JSON projection incrates/rpc/src/handlers/mining.rsrender_block_template. - Capabilities are the producer’s implemented set (
proposal,longpoll). Client-advertised names are not echoed. submitoldis present after a long-poll wait and omitted otherwise.workidis not emitted.- On signet, the template carries
signetinrules(mandatory) andsignet_challenge. Other networks omitsignet_challenge.
- Owner:
ensure_template_readyincrates/rpc/src/handlers/mining.rs. - Template mode on mainnet requires at least one live peer (
PeerTable) and that the node has left IBD (Context::is_initial_block_download). Failures are Core-9(bitcoin-rs is not connected!) and-10(bitcoin-rs is in initial sync and waiting for blocks...). - Proposal mode does not apply these gates. Networks other than mainnet skip
them, matching Core
IsTestChain().
- Owner:
MiningCoordinator::submit_headerincrates/node/src/mining.rs. RPC decodes the hex and projects the result; it does not admit headers. - Decode failures (invalid hex, fewer than 80 bytes) are Core
-22(Block header decode failed). Extra bytes after an 80-byte header are ignored, matching CoreDecodeHexBlockHeader. - The previous header must already be in the block tree. Otherwise the RPC
returns
-25(Must submit previous header (HASH) first). - Admission uses
accept_headers, the same consensus gate as inbound P2P headers. Duplicates succeed. Invalid headers return-25with Core reject reasons (high-hash,bad-diffbits,time-too-old,time-too-new). - Success is JSON
null. Header-only admission does not apply the block or publish a mining generation.
- Owner:
ensure_client_rules_for_templateandensure_client_supports_mandatory_rulesincrates/rpc/src/handlers/mining.rs. - Template mode requires the client to list
segwit. On signet it also requiressignet. Failures are Core-8with Core's exact messages:getblocktemplate must be called with the segwit rule set (call with {"rules": ["segwit"]})andgetblocktemplate must be called with the signet rule set (call with {"rules": ["segwit", "signet"]}). Signet is checked first, matching Core v31.0src/rpc/mining.cpp. - These checks run before template assembly. Proposal mode skips them.
- After assembly, any remaining mandatory template rule the client omitted
is Core
-8:Support for 'NAME' rule requires explicit client support.
- Owner:
decode_submitted_blockincrates/rpc/src/handlers/mining.rs. Admission stays onMiningControl::submit_block. - Invalid hex or a payload that is not a complete block is Core
-22(Block decode failed), matching CoreDecodeHexBlk. Extra bytes after a complete block are ignored. - A second dummy argument is accepted and ignored (BIP22). A third argument
is JSON-RPC
-32602.
- Owner:
parse_block_template_requestincrates/rpc/src/handlers/mining.rs. - Unknown or non-string
modeis Core-8(Invalid mode). - Proposal mode does not require the client to list the
proposalcapability. Missingdatais Core-3(Missing data String key for proposal) with noinvalid type:prefix. Decode usesdecode_submitted_block(API-11):-22Block decode failed, leftover bytes ignored.
- Owner:
update_uncommitted_block_structuresincrates/mining/src/coinbase.rs, called fromMiningCoordinator::submit_blockincrates/node/src/mining.rs. - When the previous header is known, SegWit is active for the submitted
height, the coinbase already has a BIP141 commitment output, and the
coinbase witness is empty,
submitblockinserts the 32-byte reserved nonce. This matches CoreUpdateUncommittedBlockStructures. - An existing coinbase witness is left unchanged. Proposal mode does not apply this fill.
- Owner:
MiningCoordinator::known_block_resultincrates/node/src/mining.rs. - GBT proposal looks the block hash up first, matching Core
LookupBlockIndex: a scripts-valid body isduplicate(API-21),Invalidisduplicate-invalid, and any other tree entry (including a header-only tip) isduplicate-inconclusive. submitblockmatches Core v31ProcessNewBlock: a scripts-valid body isduplicate. A header admitted bysubmitheaderstill receives the body.
- Owner:
bip22_reject_reasonincrates/node/src/mining.rs. - Proposal and
submitblockproject apply/consensus failures as CoreGetRejectReasonstrings (bad-cb-missing,bad-txnmrklroot,bad-cb-amount,high-hash,time-too-old, …). Operational apply refusals (Shutdown, journal backpressure) stayinconclusive. - Consensus crate Display remains log text. This mapping is the BIP22 wire owner.
- Owner:
MiningCoordinator::version_bits_forincrates/node/src/mining.rs. - Core v31
getblocktemplatehardcodesvbrequiredto 0. Signalling deployments still appear invbavailable; locked-in bits are not OR'd intovbrequired.
- Owner:
check_witness_malleationincrates/consensus/src/verify_block.rs. - Core
CheckWitnessMalleationdistinguishes three BIP22 strings:- commitment present, coinbase witness not a single 32-byte element →
bad-witness-nonce-size - commitment present, reserved nonce well-formed, hash mismatch →
bad-witness-merkle-match - witness data without a commitment, or before SegWit →
unexpected-witness
- commitment present, coinbase witness not a single 32-byte element →
- Proposal does not fill an omitted reserved nonce (
API-13issubmitblock-only), so an empty coinbase witness with a commitment is miner-facingbad-witness-nonce-size. bip22_reject_reasonmaps the consensus variants; consensus Display remains log text.
- Owner:
render_block_templateincrates/rpc/src/handlers/mining.rs. - Core v31 emits
coinbaseaux: { "flags": HexStr(COINBASE_FLAGS) }. The flags bytes are empty, so the hex string is"". An empty object is not the Core shape.
- Owner:
prioritisetransactionincrates/rpc/src/handlers/mining.rs. - Core reads
fee_deltafrom params[2] (getInt<int64_t>). The deprecated dummy (params[1]) must be omitted, null, or numeric zero; any other value is-8Priority is no longer supported, dummy argument to prioritisetransaction must be 0. - Two-argument calls do not treat params[1] as
fee_delta.
- Owner:
prioritisetransactionincrates/rpc/src/handlers/mining.rs. - Core v31 rejects a mempool transaction with dust outputs when
require_standardis set:-8Priority is not supported for transactions with dust outputs. require_standardfollows Core's-acceptnonstdtxndefault: enforced everywhere except regtest. Absent txids (fee-delta overlay only) are not checked. Dust classification uses the pool's dust-relay fee viatx_has_dust_outputs.
- Owner:
MiningCoordinator::known_block_resultincrates/node/src/mining.rs. - Core proposal
pindex->IsValid(BLOCK_VALID_SCRIPTS)is true for a body that was fully connected and later reorged.chain_tx_count != 0is written byrecord_applied_tx_countafter a successful apply and is not cleared on disconnect. Header-only nodes stay 0. - Checkpoint restore writes
chain_tx_countonly on the applied tip. Applied-chain membership is the restore fallback so ancestors whose count is still 0 stayduplicate. NodeStatus::ActiveandStaleare header-chain displacement, including asubmitheadertip, and are not the scripts-valid test.submitblockuses the same scripts-valid test. A stale scripts-valid resubmit isduplicate, notinconclusive-not-best-prevblk. CoreBLOCK_HAVE_DATAafter prune is not modeled separately.
- Owner:
render_mining_infoincrates/rpc/src/handlers/mining.rs. - Core pushes
currentblockweight,currentblocktx, andsignet_challengeonly when set. Unset optionals are omitted, not JSONnull. Projection usestyped_to_sonic_omitting_nulls, the same helper as GBT.
- Owner:
estimatesmartfeeincrates/rpc/src/handlers/util.rs. conf_targetmust be in1..=1008(CoreMAX_CONFIRM_TARGET). Otherwise-8Invalid conf_target, must be between 1 and 1008.estimate_modeis optional, case-insensitiveUNSET/ECONOMICAL/CONSERVATIVE(CoreFeeModeFromString). Unknown strings are-8Invalid estimate_mode parameter, must be UNSET, ECONOMICAL or CONSERVATIVE. A non-string is-3. Accepted modes are parsed only; this node's estimator has one horizon.- Trailing parameters are refused.
- Owner:
parse_generateblock_transactionsincrates/rpc/src/handlers/mining.rs. - 64-character hex is Core
Txid::FromHex. A txid missing from the mempool is-5Transaction {str} not in mempool.using the caller's string. - Anything else is Core
DecodeHexTx. Invalid hex or a payload that is not a complete transaction is-22Transaction decode failed for {str}. Make sure the tx has at least one input.
The wallet-facing subset of this surface — tip, fees, address/script queries, and broadcast over Esplora, plus the key-free node RPCs — is owned by wallet-facing.md.
- Full Core differential suite: Versioned Core response structs, golden fixtures, and differential test lanes across all RPC methods are tracked under #78 (open).
- Typed embedding surface: Direct in-process application API as an alternative to localhost JSON-RPC daemon boundary is tracked under #145 (open).
crates/rpc/tests/manifest_coverage.rs:rpc_rows_and_the_live_registry_agree_both_waysrest_rows_and_router_registrations_agree_both_wayszmq_rows_are_valid_core_topicsevery_unimplemented_rpc_row_answers_method_not_foundgenerated_reference_matches_checked_in
crates/rpc/src/handlers/mining.rstestsgeneratetoaddress_projects_solved_hashes,generatetoaddress_rejects_script_hex_and_descriptors,generateblock_projects_hash_object,generateblock_accepts_addr_descriptor,generateblock_without_submit_includes_hex,generateblock_requires_transactions_array,generateblock_keeps_raw_transactions,generateblock_rejects_trailing_parameters,generateblock_rejects_invalid_supplied_checksums,generateblock_rejects_unknown_mempool_txid_like_core,generateblock_rejects_undecodable_raw_tx_like_corecrates/node/tests/mining.rstestsgenerate_mines_coinbase_only_blocks_to_the_tip,generateblock_rejects_unknown_mempool_txid,generateblock_raw_tx_does_not_require_mempool_admission,generate_without_submit_does_not_advance_the_tipcrates/mining/tests/template_shape.rstestscandidate_solves_an_unsolved_regtest_header,ordered_assembly_keeps_snapshot_orderAPI-06:crates/node/src/mining.rstesthash_ps_at_rejects_a_height_the_tip_cannot_resolvecrates/node/tests/mining.rstestnetwork_hash_ps_rejects_core_invalid_windowscrates/rpc/src/handlers/mining.rstestgetnetworkhashps_projects_control_invalid_request_as_invalid_parameter
API-07:crates/rpc/src/handlers/mining.rstestsgetblocktemplate_forwards_longpollid,getblocktemplate_emits_submitold_and_omits_it_when_unset,getblocktemplate_requires_signet_rule_on_signetcrates/node/src/mining.rstestsignet_template_carries_challenge_and_mandatory_rulecrates/node/tests/mining.rsteststemplate_does_not_echo_client_capabilities,signet_template_includes_challenge_and_signet_rule
API-08:crates/rpc/src/handlers/mining.rstestsgetblocktemplate_rejects_mainnet_without_peers,getblocktemplate_rejects_mainnet_during_ibd,getblocktemplate_proposal_skips_mainnet_connection_gates
API-09:crates/rpc/src/handlers/mining.rstestssubmitheader_rejects_undecodable_headers,submitheader_returns_null_and_forwards_decoded_header,submitheader_maps_rejected_to_verify_errorcrates/node/tests/mining.rstestssubmit_header_admits_a_mined_child_and_is_idempotent,submit_header_requires_the_previous_header,submit_header_rejects_bad_diffbits,submit_header_rejects_time_too_newcrates/node/src/mining.rstestspow_failure_is_high_hash,nbits_mismatch_is_bad_diffbits
API-10:crates/rpc/src/handlers/mining.rstestsgetblocktemplate_rejects_missing_segwit_rule,getblocktemplate_requires_signet_rule_on_signet,getblocktemplate_rejects_template_mandatory_rule_without_client_support,getblocktemplate_proposal_skips_client_rule_negotiation
API-11:crates/rpc/src/handlers/mining.rstestssubmitblock_requires_mining_control_and_rejects_garbage_encoding,submitblock_ignores_bip22_dummy_and_trailing_bytes
API-12:crates/rpc/src/handlers/mining.rstestsgetblocktemplate_rejects_invalid_mode,getblocktemplate_proposal_decode_matches_core,getblocktemplate_proposal_skips_client_rule_negotiation
API-13:crates/mining/src/coinbase.rstestsfills_reserved_nonce_when_commitment_present_and_witness_empty,leaves_an_existing_coinbase_witness_alone,skips_without_commitment_or_when_segwit_is_inactivecrates/node/tests/mining.rstestsubmit_block_fills_omitted_coinbase_witness
API-14:crates/node/tests/mining.rstestssubmit_block_applies_a_header_already_in_the_tree,proposal_of_an_applied_block_is_duplicate,proposal_of_an_invalid_header_is_duplicate_invalid,proposal_of_a_header_only_block_is_duplicate_inconclusive,duplicate_submit_returns_duplicate
API-15:crates/node/src/mining.rstestsconsensus_failures_use_core_bip22_reasons,header_failures_use_core_bip22_reasonscrates/node/tests/mining.rstestsproposal_without_coinbase_is_bad_cb_missing,proposal_merkle_mismatch_is_bad_txnmrklroot,proposal_rejects_excess_coinbase_without_side_effects
API-16:crates/node/tests/mining.rstesttemplate_does_not_echo_client_capabilities
API-17:crates/consensus/src/verify_block.rstestscontextual_rules_reject_witness_before_segwit_activation,contextual_rules_enforce_bip141_commitment_after_segwit_activation,bip141_coinbase_witness_must_have_exactly_one_32_byte_element,bip141_witness_commitment_last_output_winscrates/node/src/mining.rstestconsensus_failures_use_core_bip22_reasonscrates/node/tests/mining.rstestsproposal_commitment_without_witness_nonce_is_bad_witness_nonce_size,proposal_witness_without_commitment_is_unexpected_witness,proposal_wrong_witness_commitment_is_bad_witness_merkle_match
API-18:crates/rpc/src/handlers/mining.rstestgetblocktemplate_renders_candidate_and_reuses_control_resultcrates/rpc/tests/core_compat.rstestmining_responses_deserialize_into_pinned_types
API-19:crates/rpc/src/handlers/mining.rstestsprioritisetransaction_calls_mempool_prioritise_directly,prioritisetransaction_rejects_nonzero_dummy_like_core,prioritisetransaction_requires_fee_delta_as_third_parameter
API-20:crates/rpc/src/handlers/mining.rstestsprioritisetransaction_rejects_dust_outputs_like_core,prioritisetransaction_allows_dust_overlay_on_regtest,prioritisetransaction_allows_absent_txid_overlaycrates/mempool/src/standardness.rstestdust_relay_fee_changes_the_boundary
API-21:crates/node/tests/mining.rstestsproposal_of_a_disconnected_scripts_valid_block_is_duplicate,submit_of_a_disconnected_scripts_valid_block_is_duplicate,applied_ancestor_with_unset_chain_tx_count_is_duplicate
API-22:crates/rpc/src/handlers/mining.rstestsgetmininginfo_omits_unset_optional_fields,getmininginfo_can_include_signet_challenge,getmininginfo_projects_control_state
API-23:crates/rpc/src/handlers/util.rstestsestimatesmartfee_rejects_conf_target_outside_core_range,estimatesmartfee_rejects_unknown_estimate_mode,estimatesmartfee_accepts_core_estimate_modes_and_rejects_trailing
API-24:crates/rpc/src/handlers/mining.rstestsgenerateblock_rejects_unknown_mempool_txid_like_core,generateblock_rejects_undecodable_raw_tx_like_core,generateblock_keeps_raw_transactions