Skip to content
Draft
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion crates/mining/src/control.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ pub struct BlockTemplate {
pub enum BlockValidationResult {
/// The block is valid and, for submission, was synchronously applied.
Accepted,
/// The block was already accepted (its body is on the applied chain).
/// The block's body was already connected (scripts-valid), including after a later reorg.
Duplicate,
/// The block duplicates one already known to be invalid.
///
Expand Down
22 changes: 10 additions & 12 deletions crates/node/src/mining.rs
Original file line number Diff line number Diff line change
Expand Up @@ -723,22 +723,19 @@ impl MiningCoordinator {

/// Core `LookupBlockIndex` / BIP22 proposal vocabulary.
///
/// A node on the applied chain has had its body connected (Core
/// `BLOCK_VALID_SCRIPTS`). `Invalid` is `BLOCK_FAILED_VALID`. Any other
/// tree entry, including a header-only `Active` tip, is still
/// inconclusive — `NodeStatus::Active` is the header chain, not scripts.
/// `Invalid` is `BLOCK_FAILED_VALID`. A non-zero `chain_tx_count` is set
/// only after a successful apply (`record_applied_tx_count`) and survives
/// disconnect, matching Core `IsValid(BLOCK_VALID_SCRIPTS)` including
/// reorged bodies. Header-only entries stay 0 and are inconclusive —

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Remediation recommended

1. Comment duplicates api-21 rule 📘 Rule violation ⚙ Maintainability

The expanded known_block_result comment re-specifies the API-21 scripts-valid and reorg behavior
already defined in the authoritative external API contract without referencing it. This creates
parallel documentation that can drift from the contract.
Agent Prompt
## Issue description
The implementation comment duplicates the scripts-valid and reorg semantics already documented by the authoritative `API-21` contract.

## Issue Context
Keep only implementation-specific information locally and reference `docs/contracts/external-api.md` section `API-21` for the complete business rule. Apply the same treatment to the nearby `submit` comment if it repeats contract semantics.

## Fix Focus Areas
- crates/node/src/mining.rs[724-730]
- crates/node/src/mining.rs[781-785]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

/// `NodeStatus::Active` and `Stale` are the header chain, not scripts.
fn known_block_result(&self, block_hash: Hash256) -> Option<BlockValidationResult> {
let tree = self.block_tree.read();
let node_id = tree.lookup(block_hash)?;
let node = tree.node(node_id).ok()?;
if node.status == NodeStatus::Invalid {
return Some(BlockValidationResult::DuplicateInvalid);
}
let on_applied = self
.applied_tip
.load_full()
.is_some_and(|tip| tree.node_at_height_from(tip.tip_id, node.height) == Some(node_id));
if on_applied {
if node.chain_tx_count != 0 {
return Some(BlockValidationResult::Duplicate);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Action required

3. Restart loses duplicate state 🐞 Bug ≡ Correctness

Checkpoint restore assigns chain_tx_count only to the applied tip, leaving already-applied
ancestors at zero, so known_block_result returns DuplicateInconclusive for them after restart.
submitblock then bypasses the duplicate fast path and attempts to process an already-applied
ancestor instead of returning duplicate.
Agent Prompt
## Issue description
`known_block_result` now assumes every scripts-valid block has a nonzero per-node `chain_tx_count`, but checkpoint restore only restores that value on the applied tip. Applied ancestors consequently lose their duplicate classification after restart.

## Issue Context
Header reconstruction initializes every node's count to zero. Restore then updates only `headers.applied_tip_id`, while journal replay only assigns counts to the replayed suffix. Preserve durable per-block scripts-valid state, or retain an applied-chain fallback while introducing durable state for disconnected scripts-valid blocks.

## Fix Focus Areas
- crates/node/src/mining.rs[724-742]
- crates/node/src/checkpoint.rs[1282-1308]
- crates/chain/src/tree.rs[649-656]
- crates/node/src/chainstate_journal/replay.rs[475-508]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Remediation recommended

4. Pruned bodies report duplicate 🐞 Bug ≡ Correctness

A nonzero chain_tx_count records historical validation but does not prove that the body remains
stored, because pruning deletes bodies without clearing the count. A stale previously-applied block
whose body was pruned is therefore reported as duplicate and its submitted body is discarded
instead of being treated as new storage.
Agent Prompt
## Issue description
The shared duplicate predicate conflates historical scripts-valid state with current body availability. Pruned blocks retain `chain_tx_count` but no longer have a stored body, so `submitblock` must not take the body-present duplicate fast path solely from that count.

## Issue Context
Proposal mode may continue using durable scripts-valid state, but submit mode should independently determine whether the body is currently stored. If it was pruned, process and restore the submitted body using behavior equivalent to Core's `new_block` storage result.

## Fix Focus Areas
- crates/node/src/mining.rs[713-742]
- crates/node/src/mining.rs[779-793]
- crates/node/src/state.rs[1242-1290]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

}
Some(BlockValidationResult::DuplicateInconclusive)
Expand Down Expand Up @@ -781,9 +778,10 @@ impl MiningCoordinator {

fn submit(&self, block: &Block) -> Result<BlockValidationResult, MiningControlError> {
let block_hash: Hash256 = block.block_hash().into();
// Core v31 `submitblock` dropped the index pre-check. `ProcessNewBlock`
// returns `duplicate` only when the block was already accepted
// (`!new_block && accepted`). A header-only tree entry must still
// Core v31 `submitblock` dropped the hash pre-check. `ProcessNewBlock`
// still returns `duplicate` when the body is already stored
// (`!new_block`). Scripts-valid (`chain_tx_count != 0`), including a
// later reorg, is already stored. A header-only tree entry must still
// receive the body so `submitheader` then `submitblock` works.
if matches!(
self.known_block_result(block_hash),
Expand Down
71 changes: 71 additions & 0 deletions crates/node/tests/mining.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1259,6 +1259,77 @@ fn proposal_of_a_header_only_block_is_duplicate_inconclusive() -> anyhow::Result
Ok(())
}

fn disconnect_applied(state: &NodeState, block: &Block) -> anyhow::Result<()> {
state
.chain_followers()
.apply_disconnect(&state.apply_handles(), block)
.map(|_| ())
.map_err(|error| anyhow::anyhow!("{error}"))
}

#[test]
fn proposal_of_a_disconnected_scripts_valid_block_is_duplicate() -> anyhow::Result<()> {
Comment on lines +1270 to +1272

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Remediation recommended

2. Tests omit api-21 annotation 📘 Rule violation ▣ Testability

The two new permanent compatibility tests do not identify API-21, BIP22, or another named contract
in their names or adjacent annotations. Although the contract catalog maps them externally, the
tests themselves do not exercise an explicitly documented contract as required.
Agent Prompt
## Issue description
The new permanent tests lack a test-local reference to their named current contract.

## Issue Context
`docs/contracts/external-api.md` maps both tests to active contract `API-21`. Add an adjacent contract/spec comment such as `// CONTRACT: API-21 (BIP22 duplicate behavior)` to each test.

## Fix Focus Areas
- crates/node/tests/mining.rs[1270-1271]
- crates/node/tests/mining.rs[1307-1308]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

let state = open_regtest()?;
apply_genesis(&state)?;
let mining = coordinator(&state);
mining.publish_generation();
let genesis = Network::Regtest.genesis_block();
let child = mined_child(genesis.block_hash())?;
let child_hash = Hash256::from(child.block_hash());
assert_eq!(
mining.submit_block(child.clone())?,
BlockValidationResult::Accepted
);
disconnect_applied(&state, &child)?;
let chain_tx_count = {
let tree = state.block_tree();
tree.read()
.node_by_hash(child_hash)
.ok_or_else(|| anyhow::anyhow!("disconnected child missing from tree"))?
.chain_tx_count
};
assert_ne!(
chain_tx_count, 0,
"disconnect must keep the scripts-valid chain_tx_count"
);
let tip = state
.applied_tip()
.load_full()
.unwrap_or_else(|| panic!("applied tip missing after disconnect"));
assert_eq!(tip.hash, Hash256::from(genesis.block_hash()));
assert_eq!(
propose_block(&mining, child)?,
BlockValidationResult::Duplicate
);
Ok(())
}

#[test]
fn submit_of_a_disconnected_scripts_valid_block_is_duplicate() -> anyhow::Result<()> {
let state = open_regtest()?;
apply_genesis(&state)?;
let mining = coordinator(&state);
mining.publish_generation();
let genesis = Network::Regtest.genesis_block();
let genesis_hash = Hash256::from(genesis.block_hash());
let child = mined_child(genesis.block_hash())?;
assert_eq!(
mining.submit_block(child.clone())?,
BlockValidationResult::Accepted
);
disconnect_applied(&state, &child)?;
assert_eq!(
mining.submit_block(child)?,
BlockValidationResult::Duplicate
);
let tip = state
.applied_tip()
.load_full()
.unwrap_or_else(|| panic!("applied tip missing after duplicate submit"));
assert_eq!(tip.hash, genesis_hash);
Ok(())
}

#[test]
fn submit_block_applies_a_header_already_in_the_tree() -> anyhow::Result<()> {
let state = open_regtest()?;
Expand Down
2 changes: 1 addition & 1 deletion crates/rpc/src/registry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ declare_rows! {
"getnodeaddresses", SurfaceKind::Rpc, Status::Implemented, "", CORE_VERSION, "", "0.4.0", Some(network::getnodeaddresses);
"getblocktemplate", SurfaceKind::Rpc, Status::Implemented, "", CORE_VERSION, "BIP22/BIP23 template: client must advertise segwit (and signet on signet); submitold after long-poll, signet_challenge on signet, capabilities proposal+longpoll, coinbaseaux.flags empty hex.", "0.4.0", Some(mining::getblocktemplate);
"getmininginfo", SurfaceKind::Rpc, Status::Implemented, "", CORE_VERSION, "Pinned v30 shape including bits/target and next-block facts derived from the mining coordinator.", "0.4.0", Some(mining::getmininginfo);
"submitblock", SurfaceKind::Rpc, Status::Implemented, "", CORE_VERSION, "Decode failures are -22 (Block decode failed). Extra bytes after a complete block and BIP22's dummy second argument are ignored. A header already admitted by submitheader still accepts the body; only a previously applied block is duplicate.", "0.4.0", Some(mining::submitblock);
"submitblock", SurfaceKind::Rpc, Status::Implemented, "", CORE_VERSION, "Decode failures are -22 (Block decode failed). Extra bytes after a complete block and BIP22's dummy second argument are ignored. A header already admitted by submitheader still accepts the body; a previously connected body (including after reorg) is duplicate.", "0.4.0", Some(mining::submitblock);
"submitheader", SurfaceKind::Rpc, Status::Implemented, "", CORE_VERSION, "Header-only admission through the same tree path as inbound P2P headers. Decode failures are -22; missing previous or invalid headers are -25.", "0.4.0", Some(mining::submitheader);
"prioritisetransaction", SurfaceKind::Rpc, Status::Implemented, "", CORE_VERSION, "Dummy (params[1]) must be 0 or null; fee_delta is params[2]. Non-zero dummy is Core -8. Pooled dust outputs are -8 except on regtest.", "0.4.0", Some(mining::prioritisetransaction);
"generatetoaddress", SurfaceKind::Rpc, Status::Implemented, "", CORE_VERSION, "Assembles, solves, and submits n blocks paying the given address through the mining coordinator.", "0.4.0", Some(mining::generatetoaddress);
Expand Down
2 changes: 1 addition & 1 deletion docs/contracts/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ match a regression.
| [chain-events.md](chain-events.md) | `EVT-01`–`EVT-05` | `ChainSnapshot`, `ChainEventHint`, `ChainEventPublisher`, `ConsumerCursor`, `UndoStore`/`DisconnectMarker`, `ChainChangeProof`: the seam between the apply path and reconciliation consumers | `crates/node/src/txindex_worker.rs` (first consumer); any index mirroring the applied chain | `crates/node/src/state.rs` tests `record_publishes_snapshot_and_hints_in_commit_order`, `record_drops_hints_when_channel_full`, `active_chain_snapshot_anchors_at_restored_tip_after_restart`; `crates/node/src/txindex_worker_recovery_tests.rs` tests `shallow_reorg_rewinds_to_common_ancestor_then_replays`, `tip_change_during_rebuild_converges_on_new_tip`; `crates/node/src/apply.rs` tests `a_clean_disconnect_leaves_no_in_flight_marker`, `chain_change_proof_finish_restores_even_generation` |
| [mempool-mutations.md](mempool-mutations.md) | `MPL-01`–`MPL-04` | Gateway ordering invariant, `MutationEnvelope`/`MutationResult` semantics, ZMQ `A`/`R` payload bytes, generation-validated admission and chain-change fencing | apply path (`crates/node/src/apply.rs`), `sendrawtransaction` (`crates/rpc/src/handlers/tx.rs`), ZMQ `sequence` subscribers (enforcer `--enable-mempool`) | `crates/mempool/src/gateway.rs` test `accepted_and_block_inclusion_events_arrive_in_commit_order`; `crates/node/src/zmq_publisher.rs` tests `block_inclusion_suppresses_r_frames` and `mempool_event_payloads_carry_reversed_txid_label_and_le_sequence`; `crates/node/src/apply.rs` test `stable_generation_is_even_before_and_after_connect` |
| [mempool-policy.md](mempool-policy.md) | `POL-01` | Pointer: relay policy contract pinned to Core 31.1 | `sendrawtransaction`/`testmempoolaccept` (`crates/rpc/src/handlers/tx.rs`), P2P relay admission | `crates/mempool/tests/policy_contract.rs` and `crates/rpc/tests/policy_contract.rs` (`cargo test -p bitcoin-rs-mempool --test policy_contract` / `-p bitcoin-rs-rpc --test policy_contract`) |
| [external-api.md](external-api.md) | `API-01`–`API-20` | Pointer: JSON-RPC/REST/ZMQ manifest, generated reference, error code mappings, query budgeting, solo-mining generate, `getnetworkhashps` snapshot behavior, BIP22/BIP23 template extras, mainnet GBT operational gates, `submitheader`, GBT client-rule negotiation, `submitblock` decode, GBT proposal request parsing, `submitblock` uncommitted witness fill, Core v31 submit/proposal duplicate vocabulary, BIP22 reject-reason mapping, GBT `vbrequired` always 0, Core `CheckWitnessMalleation` reject reasons, GBT `coinbaseaux.flags` empty hex, `prioritisetransaction` dummy/`fee_delta` arity, and pooled-dust refusal | RPC/REST/ZMQ clients; `tools/bip300301-enforcer` | `crates/rpc/tests/manifest_coverage.rs` tests `rpc_rows_and_the_live_registry_agree_both_ways`, `generated_reference_matches_checked_in`; `crates/rpc/src/handlers/mining.rs` generate, GBT extra, GBT gate, `submitheader`, GBT rule-negotiation, `submitblock` decode, GBT proposal-parse, `coinbaseaux`, and `prioritisetransaction` dummy/dust tests; `crates/node/tests/mining.rs` generate, GBT extra, `submitheader`, uncommitted-witness submit, submit/proposal duplicate, BIP22 reject-reason, `vbrequired`, and witness-malleation proposal tests; `crates/mining/src/coinbase.rs` uncommitted-witness tests; `crates/consensus/src/verify_block.rs` CheckWitnessMalleation tests; `crates/node/src/mining.rs` test `hash_ps_at_rejects_a_height_the_tip_cannot_resolve`; `crates/node/tests/mining.rs` test `network_hash_ps_rejects_core_invalid_windows` |
| [external-api.md](external-api.md) | `API-01`–`API-21` | Pointer: JSON-RPC/REST/ZMQ manifest, generated reference, error code mappings, query budgeting, solo-mining generate, `getnetworkhashps` snapshot behavior, BIP22/BIP23 template extras, mainnet GBT operational gates, `submitheader`, GBT client-rule negotiation, `submitblock` decode, GBT proposal request parsing, `submitblock` uncommitted witness fill, Core v31 submit/proposal duplicate vocabulary, BIP22 reject-reason mapping, GBT `vbrequired` always 0, Core `CheckWitnessMalleation` reject reasons, GBT `coinbaseaux.flags` empty hex, `prioritisetransaction` dummy/`fee_delta` arity, pooled-dust refusal, and reorged scripts-valid duplicate | RPC/REST/ZMQ clients; `tools/bip300301-enforcer` | `crates/rpc/tests/manifest_coverage.rs` tests `rpc_rows_and_the_live_registry_agree_both_ways`, `generated_reference_matches_checked_in`; `crates/rpc/src/handlers/mining.rs` generate, GBT extra, GBT gate, `submitheader`, GBT rule-negotiation, `submitblock` decode, GBT proposal-parse, `coinbaseaux`, and `prioritisetransaction` dummy/dust tests; `crates/node/tests/mining.rs` generate, GBT extra, `submitheader`, uncommitted-witness submit, submit/proposal duplicate, BIP22 reject-reason, `vbrequired`, witness-malleation proposal, and reorged scripts-valid duplicate tests; `crates/mining/src/coinbase.rs` uncommitted-witness tests; `crates/consensus/src/verify_block.rs` CheckWitnessMalleation tests; `crates/node/src/mining.rs` test `hash_ps_at_rejects_a_height_the_tip_cannot_resolve`; `crates/node/tests/mining.rs` test `network_hash_ps_rejects_core_invalid_windows` |
| [wallet-facing.md](wallet-facing.md) | `WF-01`–`WF-03` | Public Esplora/JSON-RPC surface an external wallet may use; no `NodeState` / `UtxoSet` / index types | [bitcoin-wallet](https://github.com/gosuda/bitcoin-wallet) (`btcw`); any Esplora HTTP client | `bin/bitcoin-rs/tests/wallet_facing.rs` tests `external_wallet_can_scan_estimate_and_broadcast`, `source_does_not_import_node_internals`; `crates/rpc/src/esplora.rs` tests `esplora_lives_only_under_the_api_prefix`, `api_is_the_public_electrs_directory`, `esplora_is_the_mempool_backend_superset` |
| [p2p-wire.md](p2p-wire.md) | `P2P-01`–`P2P-02` | Pointer: command inventory in `crates/p2p/src/compat.rs`, handshake/reject/deviations pinned to Core 31.1 | `crates/p2p` peers; `crates/p2p/src/chain_query.rs` active-chain serving | `crates/p2p/tests/core_compat.rs` (`cargo test -p bitcoin-rs-p2p --test core_compat`); live lane `scripts/run-p2p-core-interop.sh` |
| [qa-corpus.md](qa-corpus.md) | `QAC-01` | Pointer: fuzz seed provenance and refresh rules | `fuzz/fuzz_targets/{p2p_message,block_decode,tx_decode,script_eval}.rs`; CI fuzz lanes | `fuzz/CORPUS_PROVENANCE.md` mapping table; targets run under `cargo fuzz run <target> -- -runs=10000` |
Expand Down
29 changes: 24 additions & 5 deletions docs/contracts/external-api.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ 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.
`prioritisetransaction` dust-output refusal. `API-21` is GBT proposal /
`submitblock` duplicate for reorged scripts-valid bodies.

## Clauses

Expand Down Expand Up @@ -190,12 +191,12 @@ reject reasons. `API-18` is GBT `coinbaseaux.flags`. `API-19` is
- **Owner**: `MiningCoordinator::known_block_result` in
`crates/node/src/mining.rs`.
- GBT proposal looks the block hash up first, matching Core
`LookupBlockIndex`: a node on the applied chain is `duplicate`,
`LookupBlockIndex`: a scripts-valid body is `duplicate` (`API-21`),
`Invalid` is `duplicate-invalid`, and any other tree entry (including a
header-only tip) is `duplicate-inconclusive`.
- `submitblock` matches Core v31 `ProcessNewBlock`: only an already
accepted block is `duplicate`. A header admitted by `submitheader` still
receives the body.
- `submitblock` matches Core v31 `ProcessNewBlock`: a scripts-valid body
is `duplicate`. A header admitted by `submitheader` still receives the
body.

### `API-15`: BIP22 reject reasons

Expand Down Expand Up @@ -259,6 +260,20 @@ reject reasons. `API-18` is GBT `coinbaseaux.flags`. `API-19` is
not checked. Dust classification uses the pool's dust-relay fee via
`tx_has_dust_outputs`.

### `API-21`: reorged scripts-valid bodies are `duplicate`

- **Owner**: `MiningCoordinator::known_block_result` in
`crates/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 != 0`
is written by `record_applied_tx_count` after a successful apply and is
not cleared on disconnect. Header-only nodes stay 0.
- `NodeStatus::Active` and `Stale` are header-chain displacement,
including a `submitheader` tip, and are not the scripts-valid test.
- `submitblock` uses the same test for Core `!new_block` (body already
stored). A stale scripts-valid resubmit is `duplicate`, not
`inconclusive-not-best-prevblk`.

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](wallet-facing.md).
Expand Down Expand Up @@ -371,3 +386,7 @@ owned by [wallet-facing.md](wallet-facing.md).
`prioritisetransaction_allows_dust_overlay_on_regtest`,
`prioritisetransaction_allows_absent_txid_overlay`
- `crates/mempool/src/standardness.rs` test `dust_relay_fee_changes_the_boundary`
- `API-21`:
- `crates/node/tests/mining.rs` tests
`proposal_of_a_disconnected_scripts_valid_block_is_duplicate`,
`submit_of_a_disconnected_scripts_valid_block_is_duplicate`
2 changes: 1 addition & 1 deletion docs/rpc-reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ Unimplemented-set derivation: audited against the Bitcoin Core v31.0 source comm
| `getnodeaddresses` | 0.4.0 | |
| `getblocktemplate` | 0.4.0 | BIP22/BIP23 template: client must advertise segwit (and signet on signet); submitold after long-poll, signet_challenge on signet, capabilities proposal+longpoll, coinbaseaux.flags empty hex. |
| `getmininginfo` | 0.4.0 | Pinned v30 shape including bits/target and next-block facts derived from the mining coordinator. |
| `submitblock` | 0.4.0 | Decode failures are -22 (Block decode failed). Extra bytes after a complete block and BIP22's dummy second argument are ignored. A header already admitted by submitheader still accepts the body; only a previously applied block is duplicate. |
| `submitblock` | 0.4.0 | Decode failures are -22 (Block decode failed). Extra bytes after a complete block and BIP22's dummy second argument are ignored. A header already admitted by submitheader still accepts the body; a previously connected body (including after reorg) is duplicate. |
| `submitheader` | 0.4.0 | Header-only admission through the same tree path as inbound P2P headers. Decode failures are -22; missing previous or invalid headers are -25. |
| `prioritisetransaction` | 0.4.0 | Dummy (params[1]) must be 0 or null; fee_delta is params[2]. Non-zero dummy is Core -8. Pooled dust outputs are -8 except on regtest. |
| `generatetoaddress` | 0.4.0 | Assembles, solves, and submits n blocks paying the given address through the mining coordinator. |
Expand Down
Loading