diff --git a/CHANGELOG.md b/CHANGELOG.md index 9bab7a19d41..33fe1be833f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,13 @@ and this project adheres to the versioning scheme outlined in the [README.md](RE - Functions that include a `signer-key` parameter also include a `signer-sig` parameter to demonstrate that the owner of `signer-key` is approving that particular Stacking operation. For more details, refer to the `verify-signer-key-sig` method in the `pox-4` contract. - Signer key authorizations can be added via `set-signer-key-authorization` to omit the need for `signer-key` signatures - A `max-amount` field is a field in signer key authorizations and defines the maximum amount of STX that can be locked in a single transaction. +- Added configuration parameters to customize the burn block at which to start processing Stacks blocks, when running on testnet or regtest. + ``` + [burnchain] + first_burn_block_height = 2582526 + first_burn_block_timestamp = 1710780828 + first_burn_block_hash = "000000000000001a17c68d43cb577d62074b63a09805e4a07e829ee717507f66" + ``` ### Modified diff --git a/stackslib/src/chainstate/coordinator/tests.rs b/stackslib/src/chainstate/coordinator/tests.rs index 43128620bb5..72f3ed71215 100644 --- a/stackslib/src/chainstate/coordinator/tests.rs +++ b/stackslib/src/chainstate/coordinator/tests.rs @@ -602,6 +602,7 @@ pub fn get_chainstate(path: &str) -> StacksChainState { } fn make_genesis_block( + burnchain: &Burnchain, sort_db: &SortitionDB, state: &mut StacksChainState, parent_block: &BlockHeaderHash, @@ -611,6 +612,7 @@ fn make_genesis_block( key_index: u32, ) -> (BlockstackOperationType, StacksBlock) { make_genesis_block_with_recipients( + burnchain, sort_db, state, parent_block, @@ -625,6 +627,7 @@ fn make_genesis_block( /// build a stacks block with just the coinbase off of /// parent_block, in the canonical sortition fork. fn make_genesis_block_with_recipients( + burnchain: &Burnchain, sort_db: &SortitionDB, state: &mut StacksChainState, parent_block: &BlockHeaderHash, @@ -655,6 +658,7 @@ fn make_genesis_block_with_recipients( let proof = VRF::prove(vrf_key, sortition_tip.sortition_hash.as_bytes()); let mut builder = StacksBlockBuilder::make_regtest_block_builder( + burnchain, &parent_stacks_header, proof.clone(), 0, @@ -920,6 +924,7 @@ fn make_stacks_block_with_input( let iconn = sort_db.index_conn(); let mut builder = StacksBlockBuilder::make_regtest_block_builder( + burnchain, &parent_stacks_header, proof.clone(), total_burn, @@ -1132,6 +1137,7 @@ fn missed_block_commits_2_05() { let (mut good_op, block) = if ix == 0 { make_genesis_block_with_recipients( + &b, &sort_db, &mut chainstate, &parent, @@ -1460,6 +1466,7 @@ fn missed_block_commits_2_1() { let (mut good_op, block) = if ix == 0 { make_genesis_block_with_recipients( + &b, &sort_db, &mut chainstate, &parent, @@ -1802,6 +1809,7 @@ fn late_block_commits_2_1() { let (mut good_op, block) = if ix == 0 { make_genesis_block_with_recipients( + &b, &sort_db, &mut chainstate, &parent, @@ -2065,6 +2073,7 @@ fn test_simple_setup() { let (op, block) = if ix == 0 { make_genesis_block( + &b, &sort_db, &mut chainstate, &parent, @@ -2332,6 +2341,7 @@ fn test_sortition_with_reward_set() { let b = get_burnchain(path, None); let (good_op, mut block) = if ix == 0 { make_genesis_block_with_recipients( + &b, &sort_db, &mut chainstate, &parent, @@ -2601,6 +2611,7 @@ fn test_sortition_with_burner_reward_set() { let b = get_burnchain(path, None); let (good_op, block) = if ix == 0 { make_genesis_block_with_recipients( + &b, &sort_db, &mut chainstate, &parent, @@ -2844,6 +2855,7 @@ fn test_pox_btc_ops() { let (good_op, block) = if ix == 0 { make_genesis_block_with_recipients( + &b, &sort_db, &mut chainstate, &parent, @@ -3130,6 +3142,7 @@ fn test_stx_transfer_btc_ops() { let b = get_burnchain(path, pox_consts.clone()); let (good_op, block) = if ix == 0 { make_genesis_block_with_recipients( + &b, &sort_db, &mut chainstate, &parent, @@ -3547,6 +3560,7 @@ fn test_delegate_stx_btc_ops() { let (good_op, block) = if ix == 0 { make_genesis_block_with_recipients( + &b, &sort_db, &mut chainstate, &parent, @@ -3881,6 +3895,7 @@ fn test_initial_coinbase_reward_distributions() { let b = get_burnchain(path, pox_consts.clone()); let (good_op, block) = if ix == 0 { make_genesis_block_with_recipients( + &b, &sort_db, &mut chainstate, &parent, @@ -4076,6 +4091,7 @@ fn test_epoch_switch_cost_contract_instantiation() { let (good_op, block) = if ix == 0 { make_genesis_block_with_recipients( + &b, &sort_db, &mut chainstate, &parent, @@ -4279,6 +4295,7 @@ fn test_epoch_switch_pox_2_contract_instantiation() { let (good_op, block) = if ix == 0 { make_genesis_block_with_recipients( + &b, &sort_db, &mut chainstate, &parent, @@ -4484,6 +4501,7 @@ fn test_epoch_switch_pox_3_contract_instantiation() { let (good_op, block) = if ix == 0 { make_genesis_block_with_recipients( + &b, &sort_db, &mut chainstate, &parent, @@ -4772,6 +4790,7 @@ fn atlas_stop_start() { let (good_op, block) = if ix == 0 { make_genesis_block_with_recipients( + &b, &sort_db, &mut chainstate, &parent, @@ -5025,6 +5044,7 @@ fn test_epoch_verify_active_pox_contract() { let (good_op, block) = if ix == 0 { make_genesis_block_with_recipients( + &b, &sort_db, &mut chainstate, &parent, @@ -5397,6 +5417,7 @@ fn test_sortition_with_sunset() { let (good_op, block) = if ix == 0 { make_genesis_block_with_recipients( + &b, &sort_db, &mut chainstate, &parent, @@ -5735,6 +5756,7 @@ fn test_sortition_with_sunset_and_epoch_switch() { let (good_op, block) = if ix == 0 { make_genesis_block_with_recipients( + &b, &sort_db, &mut chainstate, &parent, @@ -5965,6 +5987,7 @@ fn test_pox_processable_block_in_different_pox_forks() { eprintln!("Making block {}", ix); let (op, block) = if ix == 0 { make_genesis_block( + &b, &sort_db, &mut chainstate, &BlockHeaderHash([0; 32]), @@ -6250,6 +6273,7 @@ fn test_pox_no_anchor_selected() { eprintln!("Making block {}", ix); let (op, block) = if ix == 0 { make_genesis_block( + &b, &sort_db, &mut chainstate, &BlockHeaderHash([0; 32]), @@ -6464,6 +6488,7 @@ fn test_pox_fork_out_of_order() { eprintln!("Making block {}", ix); let (op, block) = if ix == 0 { make_genesis_block( + &b, &sort_db, &mut chainstate, &BlockHeaderHash([0; 32]), diff --git a/stackslib/src/chainstate/stacks/boot/mod.rs b/stackslib/src/chainstate/stacks/boot/mod.rs index e93f39e1abe..ff9bcbfd17e 100644 --- a/stackslib/src/chainstate/stacks/boot/mod.rs +++ b/stackslib/src/chainstate/stacks/boot/mod.rs @@ -2680,6 +2680,7 @@ pub mod test { let block_txs = vec![coinbase_tx]; let block_builder = StacksBlockBuilder::make_regtest_block_builder( + &burnchain, &parent_tip, vrf_proof, tip.total_burn, @@ -2716,6 +2717,10 @@ pub mod test { #[test] fn test_lockups() { + let burnchain = Burnchain::default_unittest( + 0, + &BurnchainHeaderHash::from_hex(BITCOIN_REGTEST_FIRST_BLOCK_HASH).unwrap(), + ); let mut peer_config = TestPeerConfig::new(function_name!(), 2000, 2001); let alice = StacksAddress::from_string("STVK1K405H6SK9NKJAP32GHYHDJ98MMNP8Y6Z9N0").unwrap(); let bob = StacksAddress::from_string("ST76D2FMXZ7D2719PNE4N71KPSX84XCCNCMYC940").unwrap(); @@ -2802,6 +2807,7 @@ pub mod test { let block_txs = vec![coinbase_tx]; let block_builder = StacksBlockBuilder::make_regtest_block_builder( + &burnchain, &parent_tip, vrf_proof, tip.total_burn, @@ -2896,7 +2902,8 @@ pub mod test { block_txs.push(tx); } - let block_builder = StacksBlockBuilder::make_regtest_block_builder(&parent_tip, vrf_proof, tip.total_burn, microblock_pubkeyhash).unwrap(); + let block_builder = StacksBlockBuilder::make_regtest_block_builder(&burnchain, + &parent_tip, vrf_proof, tip.total_burn, microblock_pubkeyhash).unwrap(); let (anchored_block, _size, _cost) = StacksBlockBuilder::make_anchored_block_from_txs(block_builder, chainstate, &sortdb.index_conn(), block_txs).unwrap(); (anchored_block, vec![]) }); @@ -2992,6 +2999,7 @@ pub mod test { let block_txs = vec![coinbase_tx, burn_tx]; let block_builder = StacksBlockBuilder::make_regtest_block_builder( + &burnchain, &parent_tip, vrf_proof, tip.total_burn, @@ -3102,6 +3110,7 @@ pub mod test { } let block_builder = StacksBlockBuilder::make_regtest_block_builder( + &burnchain, &parent_tip, vrf_proof, tip.total_burn, @@ -3318,6 +3327,7 @@ pub mod test { } let block_builder = StacksBlockBuilder::make_block_builder( + &burnchain, false, &parent_tip, vrf_proof, @@ -3576,6 +3586,7 @@ pub mod test { } let block_builder = StacksBlockBuilder::make_regtest_block_builder( + &burnchain, &parent_tip, vrf_proof, tip.total_burn, @@ -3850,6 +3861,7 @@ pub mod test { } let block_builder = StacksBlockBuilder::make_regtest_block_builder( + &burnchain, &parent_tip, vrf_proof, tip.total_burn, @@ -4102,7 +4114,8 @@ pub mod test { block_txs.push(charlie_test_tx); } - let block_builder = StacksBlockBuilder::make_regtest_block_builder(&parent_tip, vrf_proof, tip.total_burn, microblock_pubkeyhash).unwrap(); + let block_builder = StacksBlockBuilder::make_regtest_block_builder(&burnchain, + &parent_tip, vrf_proof, tip.total_burn, microblock_pubkeyhash).unwrap(); let (anchored_block, _size, _cost) = StacksBlockBuilder::make_anchored_block_from_txs(block_builder, chainstate, &sortdb.index_conn(), block_txs).unwrap(); (anchored_block, vec![]) }); @@ -4265,6 +4278,7 @@ pub mod test { } let block_builder = StacksBlockBuilder::make_regtest_block_builder( + &burnchain, &parent_tip, vrf_proof, tip.total_burn, @@ -4563,6 +4577,7 @@ pub mod test { } let block_builder = StacksBlockBuilder::make_regtest_block_builder( + &burnchain, &parent_tip, vrf_proof, tip.total_burn, @@ -5143,6 +5158,7 @@ pub mod test { } let block_builder = StacksBlockBuilder::make_regtest_block_builder( + &burnchain, &parent_tip, vrf_proof, tip.total_burn, @@ -5521,7 +5537,7 @@ pub mod test { block_txs.push(charlie_reject); } - let block_builder = StacksBlockBuilder::make_regtest_block_builder(&parent_tip, vrf_proof, tip.total_burn, microblock_pubkeyhash).unwrap(); + let block_builder = StacksBlockBuilder::make_regtest_block_builder(&burnchain, &parent_tip, vrf_proof, tip.total_burn, microblock_pubkeyhash).unwrap(); let (anchored_block, _size, _cost) = StacksBlockBuilder::make_anchored_block_from_txs(block_builder, chainstate, &sortdb.index_conn(), block_txs).unwrap(); if tenure_id == 2 { diff --git a/stackslib/src/chainstate/stacks/boot/pox_2_tests.rs b/stackslib/src/chainstate/stacks/boot/pox_2_tests.rs index 07d34a04cc8..2c47f0ec0bd 100644 --- a/stackslib/src/chainstate/stacks/boot/pox_2_tests.rs +++ b/stackslib/src/chainstate/stacks/boot/pox_2_tests.rs @@ -3782,6 +3782,7 @@ fn test_get_pox_addrs() { } let block_builder = StacksBlockBuilder::make_block_builder( + &burnchain, false, &parent_tip, vrf_proof, @@ -4078,6 +4079,7 @@ fn test_stack_with_segwit() { } let block_builder = StacksBlockBuilder::make_block_builder( + &burnchain, false, &parent_tip, vrf_proof, diff --git a/stackslib/src/chainstate/stacks/db/blocks.rs b/stackslib/src/chainstate/stacks/db/blocks.rs index 4ee162c162a..dd70fcfb01b 100644 --- a/stackslib/src/chainstate/stacks/db/blocks.rs +++ b/stackslib/src/chainstate/stacks/db/blocks.rs @@ -10272,6 +10272,7 @@ pub mod test { &coinbase_tx, BlockBuilderSettings::max_value(), None, + &peer_config.burnchain, ) .unwrap(); @@ -10453,6 +10454,7 @@ pub mod test { #[test] fn test_get_parent_block_header() { let peer_config = TestPeerConfig::new(function_name!(), 21313, 21314); + let burnchain = peer_config.burnchain.clone(); let mut peer = TestPeer::new(peer_config); let chainstate_path = peer.chainstate_path.clone(); @@ -10522,6 +10524,7 @@ pub mod test { &coinbase_tx, BlockBuilderSettings::max_value(), None, + &burnchain, ) .unwrap(); (anchored_block.0, vec![]) @@ -10999,6 +11002,7 @@ pub mod test { epochs[num_epochs - 1].block_limit.runtime = 10_000_000; peer_config.epochs = Some(epochs); peer_config.burnchain.pox_constants.v1_unlock_height = 26; + let burnchain = peer_config.burnchain.clone(); let mut peer = TestPeer::new(peer_config); @@ -11076,6 +11080,7 @@ pub mod test { &coinbase_tx, BlockBuilderSettings::max_value(), None, + &burnchain, ) .unwrap(); @@ -11323,6 +11328,7 @@ pub mod test { epochs[num_epochs - 1].block_limit.read_length = 10_000_000; peer_config.epochs = Some(epochs); peer_config.burnchain.pox_constants.v1_unlock_height = 26; + let burnchain = peer_config.burnchain.clone(); let mut peer = TestPeer::new(peer_config); @@ -11397,6 +11403,7 @@ pub mod test { &coinbase_tx, BlockBuilderSettings::max_value(), None, + &burnchain, ) .unwrap(); diff --git a/stackslib/src/chainstate/stacks/db/unconfirmed.rs b/stackslib/src/chainstate/stacks/db/unconfirmed.rs index ea76bc54b3e..92d32dd0389 100644 --- a/stackslib/src/chainstate/stacks/db/unconfirmed.rs +++ b/stackslib/src/chainstate/stacks/db/unconfirmed.rs @@ -675,6 +675,7 @@ mod test { let initial_balance = 1000000000; let mut peer_config = TestPeerConfig::new(function_name!(), 7000, 7001); peer_config.initial_balances = vec![(addr.to_account_principal(), initial_balance)]; + let burnchain = peer_config.burnchain.clone(); let mut peer = TestPeer::new(peer_config); @@ -740,6 +741,7 @@ mod test { }; let block_builder = StacksBlockBuilder::make_regtest_block_builder( + &burnchain, &parent_tip, vrf_proof, tip.total_burn, @@ -903,6 +905,7 @@ mod test { let initial_balance = 1000000000; let mut peer_config = TestPeerConfig::new(function_name!(), 7002, 7003); peer_config.initial_balances = vec![(addr.to_account_principal(), initial_balance)]; + let burnchain = peer_config.burnchain.clone(); let mut peer = TestPeer::new(peer_config); @@ -968,6 +971,7 @@ mod test { }; let block_builder = StacksBlockBuilder::make_regtest_block_builder( + &burnchain, &parent_tip, vrf_proof, tip.total_burn, @@ -1146,6 +1150,7 @@ mod test { block_limit: BLOCK_LIMIT_MAINNET_20, network_epoch: PEER_VERSION_EPOCH_2_0, }]); + let burnchain = peer_config.burnchain.clone(); let mut peer = TestPeer::new(peer_config); let chainstate_path = peer.chainstate_path.clone(); @@ -1216,6 +1221,7 @@ mod test { }; let block_builder = StacksBlockBuilder::make_regtest_block_builder( + &burnchain, &parent_tip, vrf_proof, tip.total_burn, diff --git a/stackslib/src/chainstate/stacks/miner.rs b/stackslib/src/chainstate/stacks/miner.rs index c9e8c24e706..ec8ac4a36cc 100644 --- a/stackslib/src/chainstate/stacks/miner.rs +++ b/stackslib/src/chainstate/stacks/miner.rs @@ -38,7 +38,7 @@ use stacks_common::util::hash::{MerkleTree, Sha512Trunc256Sum}; use stacks_common::util::secp256k1::{MessageSignature, Secp256k1PrivateKey}; use stacks_common::util::vrf::*; -use crate::burnchains::{PrivateKey, PublicKey}; +use crate::burnchains::{Burnchain, PrivateKey, PublicKey}; use crate::chainstate::burn::db::sortdb::{SortitionDB, SortitionDBConn, SortitionHandleTx}; use crate::chainstate::burn::operations::*; use crate::chainstate::burn::*; @@ -2049,6 +2049,7 @@ impl StacksBlockBuilder { /// Create a block builder for mining pub fn make_block_builder( + burnchain: &Burnchain, mainnet: bool, stacks_parent_header: &StacksHeaderInfo, proof: VRFProof, @@ -2056,20 +2057,19 @@ impl StacksBlockBuilder { pubkey_hash: Hash160, ) -> Result { let builder = if stacks_parent_header.consensus_hash == FIRST_BURNCHAIN_CONSENSUS_HASH { - let (first_block_hash_hex, first_block_height, first_block_ts) = if mainnet { + let (first_block_hash, first_block_height, first_block_ts) = if mainnet { ( - BITCOIN_MAINNET_FIRST_BLOCK_HASH, + BurnchainHeaderHash::from_hex(BITCOIN_MAINNET_FIRST_BLOCK_HASH).unwrap(), BITCOIN_MAINNET_FIRST_BLOCK_HEIGHT, BITCOIN_MAINNET_FIRST_BLOCK_TIMESTAMP, ) } else { ( - BITCOIN_TESTNET_FIRST_BLOCK_HASH, - BITCOIN_TESTNET_FIRST_BLOCK_HEIGHT, - BITCOIN_TESTNET_FIRST_BLOCK_TIMESTAMP, + burnchain.first_block_hash, + burnchain.first_block_height, + burnchain.first_block_timestamp, ) }; - let first_block_hash = BurnchainHeaderHash::from_hex(first_block_hash_hex).unwrap(); StacksBlockBuilder::first_pubkey_hash( 0, &FIRST_BURNCHAIN_CONSENSUS_HASH, @@ -2103,21 +2103,20 @@ impl StacksBlockBuilder { /// Create a block builder for regtest mining pub fn make_regtest_block_builder( + burnchain: &Burnchain, stacks_parent_header: &StacksHeaderInfo, proof: VRFProof, total_burn: u64, pubkey_hash: Hash160, ) -> Result { let builder = if stacks_parent_header.consensus_hash == FIRST_BURNCHAIN_CONSENSUS_HASH { - let first_block_hash = - BurnchainHeaderHash::from_hex(BITCOIN_REGTEST_FIRST_BLOCK_HASH).unwrap(); StacksBlockBuilder::first_pubkey_hash( 0, &FIRST_BURNCHAIN_CONSENSUS_HASH, - &first_block_hash, - u32::try_from(BITCOIN_REGTEST_FIRST_BLOCK_HEIGHT) + &burnchain.first_block_hash, + u32::try_from(burnchain.first_block_height) .expect("first regtest bitcoin block is over 2^32"), - u64::try_from(BITCOIN_REGTEST_FIRST_BLOCK_TIMESTAMP) + u64::try_from(burnchain.first_block_timestamp) .expect("first regtest bitcoin block timestamp is over 2^64"), &proof, pubkey_hash, @@ -2395,6 +2394,7 @@ impl StacksBlockBuilder { coinbase_tx: &StacksTransaction, settings: BlockBuilderSettings, event_observer: Option<&dyn MemPoolEventDispatcher>, + burnchain: &Burnchain, ) -> Result<(StacksBlock, ExecutionCost, u64), Error> { if let TransactionPayload::Coinbase(..) = coinbase_tx.payload { } else { @@ -2417,6 +2417,7 @@ impl StacksBlockBuilder { let (mut chainstate, _) = chainstate_handle.reopen()?; let mut builder = StacksBlockBuilder::make_block_builder( + burnchain, chainstate.mainnet, parent_stacks_header, proof, diff --git a/stackslib/src/chainstate/stacks/tests/accounting.rs b/stackslib/src/chainstate/stacks/tests/accounting.rs index e11224ab625..8d65e40a4ed 100644 --- a/stackslib/src/chainstate/stacks/tests/accounting.rs +++ b/stackslib/src/chainstate/stacks/tests/accounting.rs @@ -121,6 +121,7 @@ fn test_bad_microblock_fees_pre_v210() { }, ]; peer_config.epochs = Some(epochs); + let burnchain = peer_config.burnchain.clone(); let num_blocks = 10; let mut anchored_sender_nonce = 0; @@ -303,6 +304,7 @@ fn test_bad_microblock_fees_pre_v210() { } let builder = StacksBlockBuilder::make_block_builder( + &burnchain, chainstate.mainnet, &parent_tip, vrf_proof, @@ -404,6 +406,7 @@ fn test_bad_microblock_fees_fix_transition() { (addr.to_account_principal(), 1000000000), (addr_anchored.to_account_principal(), 1000000000), ]; + let burnchain = peer_config.burnchain.clone(); let epochs = vec![ StacksEpoch { @@ -624,6 +627,7 @@ fn test_bad_microblock_fees_fix_transition() { } let builder = StacksBlockBuilder::make_block_builder( + &burnchain, chainstate.mainnet, &parent_tip, vrf_proof, @@ -759,6 +763,7 @@ fn test_get_block_info_v210() { (addr.to_account_principal(), 1000000000), (addr_anchored.to_account_principal(), 1000000000), ]; + let burnchain = peer_config.burnchain.clone(); let epochs = vec![ StacksEpoch { @@ -978,6 +983,7 @@ fn test_get_block_info_v210() { } let builder = StacksBlockBuilder::make_block_builder( + &burnchain, chainstate.mainnet, &parent_tip, vrf_proof, @@ -1129,6 +1135,7 @@ fn test_get_block_info_v210_no_microblocks() { (addr.to_account_principal(), 1000000000), (addr_anchored.to_account_principal(), 1000000000), ]; + let burnchain = peer_config.burnchain.clone(); let epochs = vec![ StacksEpoch { @@ -1280,6 +1287,7 @@ fn test_get_block_info_v210_no_microblocks() { mblock_pubkey_hash }; let builder = StacksBlockBuilder::make_block_builder( + &burnchain, chainstate.mainnet, &parent_tip, vrf_proof, @@ -1486,6 +1494,7 @@ fn test_coinbase_pay_to_alt_recipient_v210(pay_to_contract: bool) { }, ]; peer_config.epochs = Some(epochs); + let burnchain = peer_config.burnchain.clone(); let num_blocks = 10; let mut anchored_sender_nonce = 0; @@ -1745,6 +1754,7 @@ fn test_coinbase_pay_to_alt_recipient_v210(pay_to_contract: bool) { } let builder = StacksBlockBuilder::make_block_builder( + &burnchain, chainstate.mainnet, &parent_tip, vrf_proof, diff --git a/stackslib/src/chainstate/stacks/tests/block_construction.rs b/stackslib/src/chainstate/stacks/tests/block_construction.rs index 7e241bad481..ae428af15fc 100644 --- a/stackslib/src/chainstate/stacks/tests/block_construction.rs +++ b/stackslib/src/chainstate/stacks/tests/block_construction.rs @@ -69,6 +69,7 @@ use crate::util_lib::db::Error as db_error; #[test] fn test_build_anchored_blocks_empty() { let peer_config = TestPeerConfig::new(function_name!(), 2000, 2001); + let burnchain = peer_config.burnchain.clone(); let mut peer = TestPeer::new(peer_config); let chainstate_path = peer.chainstate_path.clone(); @@ -138,6 +139,7 @@ fn test_build_anchored_blocks_empty() { &coinbase_tx, BlockBuilderSettings::max_value(), None, + &burnchain, ) .unwrap(); (anchored_block.0, vec![]) @@ -167,6 +169,7 @@ fn test_build_anchored_blocks_stx_transfers_single() { let mut peer_config = TestPeerConfig::new(function_name!(), 2002, 2003); peer_config.initial_balances = vec![(addr.to_account_principal(), 1000000000)]; + let burnchain = peer_config.burnchain.clone(); let mut peer = TestPeer::new(peer_config); @@ -260,6 +263,7 @@ fn test_build_anchored_blocks_stx_transfers_single() { &coinbase_tx, BlockBuilderSettings::max_value(), None, + &burnchain, ) .unwrap(); (anchored_block.0, vec![]) @@ -302,6 +306,7 @@ fn test_build_anchored_blocks_empty_with_builder_timeout() { let mut peer_config = TestPeerConfig::new(function_name!(), 2022, 2023); peer_config.initial_balances = vec![(addr.to_account_principal(), 1000000000)]; + let burnchain = peer_config.burnchain.clone(); let mut peer = TestPeer::new(peer_config); @@ -399,6 +404,7 @@ fn test_build_anchored_blocks_empty_with_builder_timeout() { ..BlockBuilderSettings::max_value() }, None, + &burnchain, ) .unwrap(); (anchored_block.0, vec![]) @@ -439,6 +445,7 @@ fn test_build_anchored_blocks_stx_transfers_multi() { let mut peer_config = TestPeerConfig::new(function_name!(), 2004, 2005); peer_config.initial_balances = balances; + let burnchain = peer_config.burnchain.clone(); let mut peer = TestPeer::new(peer_config); @@ -559,6 +566,7 @@ fn test_build_anchored_blocks_stx_transfers_multi() { &coinbase_tx, BlockBuilderSettings::max_value(), None, + &burnchain, ) .unwrap(); (anchored_block.0, vec![]) @@ -603,6 +611,7 @@ fn test_build_anchored_blocks_connected_by_microblocks_across_epoch() { let mut peer_config = TestPeerConfig::new(function_name!(), 2016, 2017); peer_config.initial_balances = vec![(addr.to_account_principal(), 1000000000)]; + let burnchain = peer_config.burnchain.clone(); let epochs = vec![ StacksEpoch { @@ -787,6 +796,7 @@ fn test_build_anchored_blocks_connected_by_microblocks_across_epoch() { &coinbase_tx, BlockBuilderSettings::max_value(), None, + &burnchain, ) .unwrap(); @@ -837,6 +847,7 @@ fn test_build_anchored_blocks_connected_by_microblocks_across_epoch_invalid() { let mut peer_config = TestPeerConfig::new(function_name!(), 2018, 2019); peer_config.initial_balances = vec![(addr.to_account_principal(), 1000000000)]; + let burnchain = peer_config.burnchain.clone(); let epochs = vec![ StacksEpoch { @@ -1042,6 +1053,7 @@ fn test_build_anchored_blocks_connected_by_microblocks_across_epoch_invalid() { &coinbase_tx, BlockBuilderSettings::max_value(), None, + &burnchain, ) .unwrap(); @@ -1160,6 +1172,7 @@ fn test_build_anchored_blocks_incrementing_nonces() { let mut peer_config = TestPeerConfig::new(function_name!(), 2030, 2031); peer_config.initial_balances = initial_balances; + let burnchain = peer_config.burnchain.clone(); let mut peer = TestPeer::new(peer_config); @@ -1246,6 +1259,7 @@ fn test_build_anchored_blocks_incrementing_nonces() { &coinbase_tx, BlockBuilderSettings::limited(), None, + &burnchain, ) .unwrap(); (anchored_block.0, vec![]) @@ -1344,6 +1358,7 @@ fn test_build_anchored_blocks_skip_too_expensive() { }, network_epoch: PEER_VERSION_EPOCH_2_0, }]); + let burnchain = peer_config.burnchain.clone(); let mut peer = TestPeer::new(peer_config); @@ -1492,6 +1507,7 @@ fn test_build_anchored_blocks_skip_too_expensive() { &coinbase_tx, BlockBuilderSettings::limited(), None, + &burnchain, ) .unwrap(); (anchored_block.0, vec![]) @@ -1541,6 +1557,7 @@ fn test_build_anchored_blocks_multiple_chaintips() { let mut peer_config = TestPeerConfig::new(function_name!(), 2008, 2009); peer_config.initial_balances = balances; + let burnchain = peer_config.burnchain.clone(); let mut peer = TestPeer::new(peer_config); @@ -1644,6 +1661,7 @@ fn test_build_anchored_blocks_multiple_chaintips() { &coinbase_tx, BlockBuilderSettings::limited(), None, + &burnchain, ) .unwrap() }; @@ -1686,6 +1704,7 @@ fn test_build_anchored_blocks_empty_chaintips() { let mut peer_config = TestPeerConfig::new(function_name!(), 2010, 2011); peer_config.initial_balances = balances; + let burnchain = peer_config.burnchain.clone(); let mut peer = TestPeer::new(peer_config); @@ -1749,6 +1768,7 @@ fn test_build_anchored_blocks_empty_chaintips() { &coinbase_tx, BlockBuilderSettings::max_value(), None, + &burnchain, ) .unwrap(); @@ -1827,6 +1847,7 @@ fn test_build_anchored_blocks_too_expensive_transactions() { let mut peer_config = TestPeerConfig::new(function_name!(), 2013, 2014); peer_config.initial_balances = balances; + let burnchain = peer_config.burnchain.clone(); let mut peer = TestPeer::new(peer_config); @@ -1954,6 +1975,7 @@ fn test_build_anchored_blocks_too_expensive_transactions() { &coinbase_tx, BlockBuilderSettings::max_value(), None, + &burnchain, ) .unwrap(); @@ -1979,6 +2001,7 @@ fn test_build_anchored_blocks_too_expensive_transactions() { #[test] fn test_build_anchored_blocks_invalid() { let peer_config = TestPeerConfig::new(function_name!(), 2014, 2015); + let burnchain = peer_config.burnchain.clone(); let mut peer = TestPeer::new(peer_config); let chainstate_path = peer.chainstate_path.clone(); @@ -2110,7 +2133,7 @@ fn test_build_anchored_blocks_invalid() { let coinbase_tx = make_coinbase(miner, tenure_id as usize); let mut anchored_block = StacksBlockBuilder::build_anchored_block( - chainstate, &sortdb.index_conn(), &mut mempool, &parent_tip, tip.total_burn, vrf_proof, Hash160([tenure_id as u8; 20]), &coinbase_tx, BlockBuilderSettings::max_value(), None, + chainstate, &sortdb.index_conn(), &mut mempool, &parent_tip, tip.total_burn, vrf_proof, Hash160([tenure_id as u8; 20]), &coinbase_tx, BlockBuilderSettings::max_value(), None, &burnchain, ).unwrap(); if tenure_id == bad_block_tenure { @@ -2189,6 +2212,7 @@ fn test_build_anchored_blocks_bad_nonces() { let mut peer_config = TestPeerConfig::new(function_name!(), 2012, 2013); peer_config.initial_balances = balances; + let burnchain = peer_config.burnchain.clone(); let mut peer = TestPeer::new(peer_config); @@ -2388,6 +2412,7 @@ fn test_build_anchored_blocks_bad_nonces() { &coinbase_tx, BlockBuilderSettings::max_value(), None, + &burnchain, ) .unwrap(); @@ -2439,6 +2464,7 @@ fn test_build_microblock_stream_forks() { let mut peer_config = TestPeerConfig::new(function_name!(), 2014, 2015); peer_config.initial_balances = balances; + let burnchain = peer_config.burnchain.clone(); let mut peer = TestPeer::new(peer_config); @@ -2637,6 +2663,7 @@ fn test_build_microblock_stream_forks() { &coinbase_tx, BlockBuilderSettings::max_value(), None, + &burnchain, ) .unwrap(); @@ -2738,6 +2765,7 @@ fn test_build_microblock_stream_forks_with_descendants() { let mut peer_config = TestPeerConfig::new(function_name!(), 2014, 2015); peer_config.initial_balances = balances; + let burnchain = peer_config.burnchain.clone(); let mut peer = TestPeer::new(peer_config); @@ -3062,6 +3090,7 @@ fn test_build_microblock_stream_forks_with_descendants() { &coinbase_tx, BlockBuilderSettings::max_value(), None, + &burnchain, ) .unwrap(); @@ -3204,6 +3233,7 @@ fn test_contract_call_across_clarity_versions() { (addr.to_account_principal(), 1000000000), (addr_anchored.to_account_principal(), 1000000000), ]; + let burnchain = peer_config.burnchain.clone(); let epochs = vec![ StacksEpoch { @@ -3632,11 +3662,12 @@ fn test_contract_call_across_clarity_versions() { let sort_ic = sortdb.index_conn(); let builder = StacksBlockBuilder::make_block_builder( + &burnchain, chainstate.mainnet, &parent_tip, vrf_proof, tip.total_burn, - Hash160([tenure_id as u8; 20]) + Hash160([tenure_id as u8; 20]), ) .unwrap(); @@ -3794,6 +3825,7 @@ fn test_is_tx_problematic() { network_epoch: PEER_VERSION_EPOCH_2_05, }, ]); + let burnchain = peer_config.burnchain.clone(); let mut peer = TestPeer::new(peer_config); @@ -3876,6 +3908,7 @@ fn test_is_tx_problematic() { // attempting to build an anchored block with this tx should cause this tx // to get flagged as problematic let block_builder = StacksBlockBuilder::make_regtest_block_builder( + &burnchain, &parent_tip, vrf_proof.clone(), tip.total_burn, @@ -4052,6 +4085,7 @@ fn test_is_tx_problematic() { // attempting to build an anchored block with this tx should cause this tx // to get flagged as problematic let block_builder = StacksBlockBuilder::make_regtest_block_builder( + &burnchain, &parent_tip, vrf_proof.clone(), tip.total_burn, @@ -4101,6 +4135,7 @@ fn test_is_tx_problematic() { // attempting to build an anchored block with this tx should cause this tx // to get flagged as problematic let block_builder = StacksBlockBuilder::make_regtest_block_builder( + &burnchain, &parent_tip, vrf_proof.clone(), tip.total_burn, @@ -4152,6 +4187,7 @@ fn test_is_tx_problematic() { // attempting to build an anchored block with this tx should cause this tx // to get flagged as problematic let block_builder = StacksBlockBuilder::make_regtest_block_builder( + &burnchain, &parent_tip, vrf_proof.clone(), tip.total_burn, @@ -4202,6 +4238,7 @@ fn test_is_tx_problematic() { &coinbase_tx, BlockBuilderSettings::limited(), None, + &burnchain, ) .unwrap(); @@ -4271,6 +4308,7 @@ fn mempool_incorporate_pox_unlocks() { peer_config.burnchain.pox_constants.v1_unlock_height = peer_config.epochs.as_ref().unwrap()[1].end_height as u32 + 1; let pox_constants = peer_config.burnchain.pox_constants.clone(); + let burnchain = peer_config.burnchain.clone(); let mut peer = TestPeer::new(peer_config); @@ -4443,6 +4481,7 @@ fn mempool_incorporate_pox_unlocks() { &coinbase_tx, BlockBuilderSettings::limited(), None, + &burnchain, ) .unwrap(); @@ -4484,6 +4523,7 @@ fn test_fee_order_mismatch_nonce_order() { let mut peer_config = TestPeerConfig::new(function_name!(), 2002, 2003); peer_config.initial_balances = vec![(addr.to_account_principal(), 1000000000)]; + let burnchain = peer_config.burnchain.clone(); let mut peer = TestPeer::new(peer_config); @@ -4581,6 +4621,7 @@ fn test_fee_order_mismatch_nonce_order() { &coinbase_tx, BlockBuilderSettings::max_value(), None, + &burnchain, ) .unwrap(); (anchored_block.0, vec![]) diff --git a/stackslib/src/main.rs b/stackslib/src/main.rs index 4ab56c30283..1040f867c61 100644 --- a/stackslib/src/main.rs +++ b/stackslib/src/main.rs @@ -577,6 +577,7 @@ simulating a miner. } let start = get_epoch_time_ms(); + let burnchain_path = format!("{}/mainnet/burnchain", &argv[2]); let sort_db_path = format!("{}/mainnet/burnchain/sortition", &argv[2]); let chain_state_path = format!("{}/mainnet/chainstate/", &argv[2]); @@ -645,6 +646,7 @@ simulating a miner. &coinbase_tx, settings, None, + &Burnchain::new(&burnchain_path, "bitcoin", "main").unwrap(), ); let stop = get_epoch_time_ms(); @@ -1336,6 +1338,7 @@ simulating a miner. process::exit(1); } + let burnchain_path = format!("{}/mainnet/burnchain", &argv[2]); let sort_db_path = format!("{}/mainnet/burnchain/sortition", &argv[2]); let chain_state_path = format!("{}/mainnet/chainstate/", &argv[2]); @@ -1518,6 +1521,7 @@ simulating a miner. &coinbase_tx, settings, None, + &Burnchain::new(&burnchain_path, "bitcoin", "main").unwrap(), ); let stop = get_epoch_time_ms(); diff --git a/stackslib/src/net/api/tests/mod.rs b/stackslib/src/net/api/tests/mod.rs index b0802a44c4e..ce67147a9e4 100644 --- a/stackslib/src/net/api/tests/mod.rs +++ b/stackslib/src/net/api/tests/mod.rs @@ -294,6 +294,8 @@ impl<'a> TestRPC<'a> { peer_1_config.add_neighbor(&peer_2_config.to_neighbor()); peer_2_config.add_neighbor(&peer_1_config.to_neighbor()); + let burnchain = peer_1_config.burnchain.clone(); + let mut peer_1 = TestPeer::new(peer_1_config); let mut peer_2 = TestPeer::new(peer_2_config); @@ -441,6 +443,7 @@ impl<'a> TestRPC<'a> { }; let block_builder = StacksBlockBuilder::make_regtest_block_builder( + &burnchain, &parent_tip, vrf_proof, tip.total_burn, @@ -718,6 +721,7 @@ impl<'a> TestRPC<'a> { }; let block_builder = StacksBlockBuilder::make_regtest_block_builder( + &burnchain, &parent_tip, vrf_proof, tip.total_burn, diff --git a/stackslib/src/net/mod.rs b/stackslib/src/net/mod.rs index c18f0d77f1c..2b4f9a053e8 100644 --- a/stackslib/src/net/mod.rs +++ b/stackslib/src/net/mod.rs @@ -3464,6 +3464,7 @@ pub mod test { let tip = SortitionDB::get_canonical_burn_chain_tip(&self.sortdb.as_ref().unwrap().conn()) .unwrap(); + let burnchain = self.config.burnchain.clone(); let (burn_ops, stacks_block, microblocks) = self.make_tenure( |ref mut miner, ref mut sortdb, @@ -3478,6 +3479,7 @@ pub mod test { block_txs.extend_from_slice(txs); let block_builder = StacksBlockBuilder::make_regtest_block_builder( + &burnchain, &parent_tip, vrf_proof, tip.total_burn, diff --git a/stackslib/src/net/relay.rs b/stackslib/src/net/relay.rs index d1fcbd20c51..28ff92ae585 100644 --- a/stackslib/src/net/relay.rs +++ b/stackslib/src/net/relay.rs @@ -5318,6 +5318,7 @@ pub mod test { network_epoch: PEER_VERSION_EPOCH_2_05, }, ]); + let burnchain = peer_config.burnchain.clone(); // activate new AST rules right away let mut peer = TestPeer::new(peer_config); @@ -5403,6 +5404,7 @@ pub mod test { let coinbase_tx = make_coinbase(miner, 0); let block_builder = StacksBlockBuilder::make_regtest_block_builder( + &burnchain, &parent_tip, vrf_proof.clone(), tip.total_burn, @@ -5467,6 +5469,7 @@ pub mod test { let mblock_privk = miner.next_microblock_privkey(); let block_builder = StacksBlockBuilder::make_regtest_block_builder( + &burnchain, &parent_tip, vrf_proof.clone(), tip.total_burn, @@ -5491,6 +5494,7 @@ pub mod test { // make a bad block anyway // don't worry about the state root let block_builder = StacksBlockBuilder::make_regtest_block_builder( + &burnchain, &parent_tip, vrf_proof.clone(), tip.total_burn, @@ -5732,6 +5736,7 @@ pub mod test { }, ]; peer_config.epochs = Some(epochs); + let burnchain = peer_config.burnchain.clone(); let mut peer = TestPeer::new(peer_config); @@ -5789,6 +5794,7 @@ pub mod test { mblock_pubkey_hash_bytes.copy_from_slice(&coinbase_tx.txid()[0..20]); let builder = StacksBlockBuilder::make_block_builder( + &burnchain, chainstate.mainnet, &parent_tip, vrfproof, @@ -5903,6 +5909,7 @@ pub mod test { peer_config.epochs = Some(epochs); peer_config.initial_balances = initial_balances; + let burnchain = peer_config.burnchain.clone(); let mut peer = TestPeer::new(peer_config); @@ -5966,6 +5973,7 @@ pub mod test { mblock_pubkey_hash_bytes.copy_from_slice(&coinbase_tx.txid()[0..20]); let builder = StacksBlockBuilder::make_block_builder( + &burnchain, chainstate.mainnet, &parent_tip, vrfproof, @@ -6082,6 +6090,7 @@ pub mod test { peer_config.epochs = Some(epochs); peer_config.initial_balances = initial_balances; + let burnchain = peer_config.burnchain.clone(); let mut peer = TestPeer::new(peer_config); let versioned_contract_opt: RefCell> = RefCell::new(None); @@ -6151,6 +6160,7 @@ pub mod test { mblock_pubkey_hash_bytes.copy_from_slice(&coinbase_tx.txid()[0..20]); let builder = StacksBlockBuilder::make_block_builder( + &burnchain, chainstate.mainnet, &parent_tip, vrfproof, diff --git a/stackslib/src/net/tests/download/epoch2x.rs b/stackslib/src/net/tests/download/epoch2x.rs index 200ec772199..5e9ea0daf2b 100644 --- a/stackslib/src/net/tests/download/epoch2x.rs +++ b/stackslib/src/net/tests/download/epoch2x.rs @@ -701,6 +701,7 @@ pub fn test_get_blocks_and_microblocks_2_peers_download_plain_100_blocks() { // build up block data to replicate let mut block_data = vec![]; let spending_account = &mut peers[1].config.spending_account.clone(); + let burnchain = peers[1].config.burnchain.clone(); // function to make a tenure in which a the peer's miner stacks its STX let mut make_stacking_tenure = |miner: &mut TestMiner, @@ -792,6 +793,7 @@ pub fn test_get_blocks_and_microblocks_2_peers_download_plain_100_blocks() { ); let mut builder = StacksBlockBuilder::make_block_builder( + &burnchain, chainstate.mainnet, &parent_tip, vrfproof, @@ -1392,6 +1394,7 @@ pub fn test_get_blocks_and_microblocks_2_peers_download_multiple_microblock_desc .unwrap(); let chainstate_path = peers[1].chainstate_path.clone(); + let burnchain = peers[1].config.burnchain.clone(); let (mut burn_ops, stacks_block, _) = peers[1].make_tenure( |ref mut miner, @@ -1436,6 +1439,7 @@ pub fn test_get_blocks_and_microblocks_2_peers_download_multiple_microblock_desc &coinbase_tx, BlockBuilderSettings::max_value(), None, + &burnchain, ) .unwrap(); (anchored_block, vec![]) diff --git a/testnet/stacks-node/src/burnchains/bitcoin_regtest_controller.rs b/testnet/stacks-node/src/burnchains/bitcoin_regtest_controller.rs index 0f78af61f64..f96c0c198b7 100644 --- a/testnet/stacks-node/src/burnchains/bitcoin_regtest_controller.rs +++ b/testnet/stacks-node/src/burnchains/bitcoin_regtest_controller.rs @@ -57,6 +57,7 @@ use stacks_common::util::sleep_ms; use super::super::operations::BurnchainOpSigner; use super::super::Config; use super::{BurnchainController, BurnchainTip, Error as BurnchainControllerError}; +use crate::config::BurnchainConfig; /// The number of bitcoin blocks that can have /// passed since the UTXO cache was last refreshed before @@ -124,14 +125,22 @@ pub fn addr2str(btc_addr: &BitcoinAddress) -> String { format!("{}", &btc_addr) } +pub fn burnchain_params_from_config(config: &BurnchainConfig) -> BurnchainParameters { + let (network, _) = config.get_bitcoin_network(); + let mut params = BurnchainParameters::from_params(&config.chain, &network) + .expect("Bitcoin network unsupported"); + if let Some(first_burn_block_height) = config.first_burn_block_height { + params.first_block_height = first_burn_block_height; + } + params +} + /// Helper method to create a BitcoinIndexer pub fn make_bitcoin_indexer( config: &Config, should_keep_running: Option>, ) -> BitcoinIndexer { - let (network, _) = config.burnchain.get_bitcoin_network(); - let burnchain_params = BurnchainParameters::from_params(&config.burnchain.chain, &network) - .expect("Bitcoin network unsupported"); + let burnchain_params = burnchain_params_from_config(&config.burnchain); let indexer_config = { let burnchain_config = config.burnchain.clone(); BitcoinIndexerConfig { @@ -271,7 +280,7 @@ impl BitcoinRegtestController { ) -> Self { std::fs::create_dir_all(&config.get_burnchain_path_str()) .expect("Unable to create workdir"); - let (network, network_id) = config.burnchain.get_bitcoin_network(); + let (_, network_id) = config.burnchain.get_bitcoin_network(); let res = SpvClient::new( &config.get_spv_headers_file_path(), @@ -286,8 +295,7 @@ impl BitcoinRegtestController { panic!() } - let burnchain_params = BurnchainParameters::from_params(&config.burnchain.chain, &network) - .expect("Bitcoin network unsupported"); + let burnchain_params = burnchain_params_from_config(&config.burnchain); if network_id == BitcoinNetworkType::Mainnet && config.burnchain.epochs.is_some() { panic!("It is an error to set custom epochs while running on Mainnet: network_id {:?} config.burnchain {:#?}", @@ -336,9 +344,7 @@ impl BitcoinRegtestController { /// create a dummy bitcoin regtest controller. /// used just for submitting bitcoin ops. pub fn new_dummy(config: Config) -> Self { - let (network, _) = config.burnchain.get_bitcoin_network(); - let burnchain_params = BurnchainParameters::from_params(&config.burnchain.chain, &network) - .expect("Bitcoin network unsupported"); + let burnchain_params = burnchain_params_from_config(&config.burnchain); let indexer_config = { let burnchain_config = config.burnchain.clone(); diff --git a/testnet/stacks-node/src/config.rs b/testnet/stacks-node/src/config.rs index 817d846c133..7901b6d8751 100644 --- a/testnet/stacks-node/src/config.rs +++ b/testnet/stacks-node/src/config.rs @@ -33,6 +33,7 @@ use stacks::cost_estimates::{CostEstimator, FeeEstimator, PessimisticEstimator, use stacks::net::atlas::AtlasConfig; use stacks::net::connection::ConnectionOptions; use stacks::net::{Neighbor, NeighborKey}; +use stacks::types::chainstate::BurnchainHeaderHash; use stacks::util_lib::boot::boot_code_id; use stacks::util_lib::db::Error as DBError; use stacks_common::consts::SIGNER_SLOTS_PER_USER; @@ -536,6 +537,31 @@ impl Config { return; } + if let Some(first_burn_block_height) = self.burnchain.first_burn_block_height { + debug!( + "Override first_block_height from {} to {}", + burnchain.first_block_height, first_burn_block_height + ); + burnchain.first_block_height = first_burn_block_height; + } + + if let Some(first_burn_block_timestamp) = self.burnchain.first_burn_block_timestamp { + debug!( + "Override first_block_timestamp from {} to {}", + burnchain.first_block_timestamp, first_burn_block_timestamp + ); + burnchain.first_block_timestamp = first_burn_block_timestamp; + } + + if let Some(first_burn_block_hash) = &self.burnchain.first_burn_block_hash { + debug!( + "Override first_burn_block_hash from {} to {}", + burnchain.first_block_hash, first_burn_block_hash + ); + burnchain.first_block_hash = BurnchainHeaderHash::from_hex(&first_burn_block_hash) + .expect("Invalid first_burn_block_hash"); + } + if let Some(pox_prepare_length) = self.burnchain.pox_prepare_length { debug!("Override pox_prepare_length to {pox_prepare_length}"); burnchain.pox_constants.prepare_length = pox_prepare_length; @@ -555,7 +581,28 @@ impl Config { } if let Some(epochs) = &self.burnchain.epochs { - // Iterate through the epochs vector and find the item where epoch_id == StacksEpochId::Epoch22 + if let Some(epoch) = epochs + .iter() + .find(|epoch| epoch.epoch_id == StacksEpochId::Epoch10) + { + // Epoch 1.0 start height can be equal to the first block height iff epoch 2.0 + // start height is also equal to the first block height. + assert!( + epoch.start_height <= burnchain.first_block_height, + "FATAL: Epoch 1.0 start height must be at or before the first block height" + ); + } + + if let Some(epoch) = epochs + .iter() + .find(|epoch| epoch.epoch_id == StacksEpochId::Epoch20) + { + assert_eq!( + epoch.start_height, burnchain.first_block_height, + "FATAL: Epoch 2.0 start height must match the first block height" + ); + } + if let Some(epoch) = epochs .iter() .find(|epoch| epoch.epoch_id == StacksEpochId::Epoch21) @@ -781,7 +828,6 @@ impl Config { ); } - // epochs must be a prefix of [1.0, 2.0, 2.05, 2.1] let expected_list = [ StacksEpochId::Epoch10, StacksEpochId::Epoch20, @@ -1243,6 +1289,9 @@ pub struct BurnchainConfig { pub leader_key_tx_estimated_size: u64, pub block_commit_tx_estimated_size: u64, pub rbf_fee_increment: u64, + pub first_burn_block_height: Option, + pub first_burn_block_timestamp: Option, + pub first_burn_block_hash: Option, /// Custom override for the definitions of the epochs. This will only be applied for testnet and /// regtest nodes. pub epochs: Option>, @@ -1281,6 +1330,9 @@ impl BurnchainConfig { leader_key_tx_estimated_size: LEADER_KEY_TX_ESTIM_SIZE, block_commit_tx_estimated_size: BLOCK_COMMIT_TX_ESTIM_SIZE, rbf_fee_increment: DEFAULT_RBF_FEE_RATE_INCREMENT, + first_burn_block_height: None, + first_burn_block_timestamp: None, + first_burn_block_hash: None, epochs: None, pox_2_activation: None, pox_prepare_length: None, @@ -1372,6 +1424,9 @@ pub struct BurnchainConfigFile { pub block_commit_tx_estimated_size: Option, pub rbf_fee_increment: Option, pub max_rbf: Option, + pub first_burn_block_height: Option, + pub first_burn_block_timestamp: Option, + pub first_burn_block_hash: Option, pub epochs: Option>, pub pox_prepare_length: Option, pub pox_reward_length: Option, @@ -1524,6 +1579,16 @@ impl BurnchainConfigFile { rbf_fee_increment: self .rbf_fee_increment .unwrap_or(default_burnchain_config.rbf_fee_increment), + first_burn_block_height: self + .first_burn_block_height + .or(default_burnchain_config.first_burn_block_height), + first_burn_block_timestamp: self + .first_burn_block_timestamp + .or(default_burnchain_config.first_burn_block_timestamp), + first_burn_block_hash: self + .first_burn_block_hash + .clone() + .or(default_burnchain_config.first_burn_block_hash.clone()), // will be overwritten below epochs: default_burnchain_config.epochs, ast_precheck_size_height: self.ast_precheck_size_height, @@ -1552,6 +1617,13 @@ impl BurnchainConfigFile { { return Err("PoX-2 parameters are not configurable in mainnet".into()); } + // Check that the first burn block options are not set in mainnet + if config.first_burn_block_height.is_some() + || config.first_burn_block_timestamp.is_some() + || config.first_burn_block_hash.is_some() + { + return Err("First burn block parameters are not configurable in mainnet".into()); + } } if let Some(ref conf_epochs) = self.epochs { diff --git a/testnet/stacks-node/src/nakamoto_node/miner.rs b/testnet/stacks-node/src/nakamoto_node/miner.rs index c0f648ffcba..3a976aecca2 100644 --- a/testnet/stacks-node/src/nakamoto_node/miner.rs +++ b/testnet/stacks-node/src/nakamoto_node/miner.rs @@ -25,7 +25,7 @@ use hashbrown::HashSet; use libsigner::{ BlockProposalSigners, MessageSlotID, SignerMessage, SignerSession, StackerDBSession, }; -use stacks::burnchains::{Burnchain, BurnchainParameters}; +use stacks::burnchains::Burnchain; use stacks::chainstate::burn::db::sortdb::SortitionDB; use stacks::chainstate::burn::{BlockSnapshot, ConsensusHash}; use stacks::chainstate::nakamoto::miner::{NakamotoBlockBuilder, NakamotoTenureInfo}; @@ -50,6 +50,7 @@ use wsts::curve::scalar::Scalar; use super::relayer::RelayerThread; use super::sign_coordinator::SignCoordinator; use super::{Config, Error as NakamotoNodeError, EventDispatcher, Keychain}; +use crate::burnchains::bitcoin_regtest_controller::burnchain_params_from_config; use crate::nakamoto_node::VRF_MOCK_MINER_KEY; use crate::run_loop::nakamoto::Globals; use crate::run_loop::RegisteredKey; @@ -664,10 +665,7 @@ impl BlockMinerThread { .expect("FATAL: could not query chain tip") else { debug!("No Stacks chain tip known, will return a genesis block"); - let (network, _) = self.config.burnchain.get_bitcoin_network(); - let burnchain_params = - BurnchainParameters::from_params(&self.config.burnchain.chain, &network) - .expect("Bitcoin network unsupported"); + let burnchain_params = burnchain_params_from_config(&self.config.burnchain); let chain_tip = ChainTip::genesis( &burnchain_params.first_block_hash, diff --git a/testnet/stacks-node/src/neon_node.rs b/testnet/stacks-node/src/neon_node.rs index 2eb7f1b1d10..2a05feb44e6 100644 --- a/testnet/stacks-node/src/neon_node.rs +++ b/testnet/stacks-node/src/neon_node.rs @@ -152,7 +152,7 @@ use clarity::vm::costs::ExecutionCost; use clarity::vm::types::{PrincipalData, QualifiedContractIdentifier}; use stacks::burnchains::bitcoin::address::{BitcoinAddress, LegacyBitcoinAddressType}; use stacks::burnchains::db::BurnchainHeaderReader; -use stacks::burnchains::{Burnchain, BurnchainParameters, BurnchainSigner, PoxConstants, Txid}; +use stacks::burnchains::{Burnchain, BurnchainSigner, PoxConstants, Txid}; use stacks::chainstate::burn::db::sortdb::SortitionDB; use stacks::chainstate::burn::operations::leader_block_commit::{ RewardSetInfo, BURN_BLOCK_MINED_AT_MODULUS, @@ -204,7 +204,7 @@ use stacks_common::util::{get_epoch_time_ms, get_epoch_time_secs}; use super::{BurnchainController, Config, EventDispatcher, Keychain}; use crate::burnchains::bitcoin_regtest_controller::{ - addr2str, BitcoinRegtestController, OngoingBlockCommit, + addr2str, burnchain_params_from_config, BitcoinRegtestController, OngoingBlockCommit, }; use crate::burnchains::make_bitcoin_indexer; use crate::chain_data::MinerStats; @@ -1503,10 +1503,7 @@ impl BlockMinerThread { (parent_info, canonical) } else { debug!("No Stacks chain tip known, will return a genesis block"); - let (network, _) = self.config.burnchain.get_bitcoin_network(); - let burnchain_params = - BurnchainParameters::from_params(&self.config.burnchain.chain, &network) - .expect("Bitcoin network unsupported"); + let burnchain_params = burnchain_params_from_config(&self.config.burnchain); let chain_tip = ChainTip::genesis( &burnchain_params.first_block_hash, @@ -2315,6 +2312,7 @@ impl BlockMinerThread { &coinbase_tx, builder_settings, Some(&self.event_dispatcher), + &self.burnchain, ) { Ok(block) => block, Err(ChainstateError::InvalidStacksMicroblock(msg, mblock_header_hash)) => { @@ -2344,6 +2342,7 @@ impl BlockMinerThread { &coinbase_tx, builder_settings, Some(&self.event_dispatcher), + &self.burnchain, ) { Ok(block) => block, Err(e) => { diff --git a/testnet/stacks-node/src/tenure.rs b/testnet/stacks-node/src/tenure.rs index 882a65d06b0..fd7683f569e 100644 --- a/testnet/stacks-node/src/tenure.rs +++ b/testnet/stacks-node/src/tenure.rs @@ -101,6 +101,7 @@ impl<'a> Tenure { &self.coinbase_tx, BlockBuilderSettings::limited(), None, + &self.config.get_burnchain(), ) .unwrap();