diff --git a/clarity/src/vm/docs/mod.rs b/clarity/src/vm/docs/mod.rs index 2a5c5b767..ea12d21bc 100644 --- a/clarity/src/vm/docs/mod.rs +++ b/clarity/src/vm/docs/mod.rs @@ -2229,10 +2229,10 @@ fn make_all_api_reference() -> ReferenceAPIs { .iter() .map(|x| make_api_reference(x)) .collect(); - for data_type in DefineFunctions::ALL.iter() { functions.push(make_define_reference(data_type)) } + functions.sort_by(|x, y| x.name.cmp(&y.name)); let mut keywords = Vec::new(); for variable in NativeVariables::ALL.iter() { @@ -2241,6 +2241,7 @@ fn make_all_api_reference() -> ReferenceAPIs { keywords.push(api_ref) } } + keywords.sort_by(|x, y| x.name.cmp(&y.name)); ReferenceAPIs { functions, diff --git a/src/burnchains/burnchain.rs b/src/burnchains/burnchain.rs index 2cfbeaee9..6f3105d6d 100644 --- a/src/burnchains/burnchain.rs +++ b/src/burnchains/burnchain.rs @@ -73,7 +73,7 @@ use crate::util_lib::db::Error as db_error; use stacks_common::address::public_keys_to_address_hash; use stacks_common::address::AddressHashMode; use stacks_common::deps_common::bitcoin::util::hash::Sha256dHash as BitcoinSha256dHash; -use stacks_common::util::get_epoch_time_ms; +use stacks_common::util::{get_epoch_time_ms, sleep_ms}; use stacks_common::util::get_epoch_time_secs; use stacks_common::util::hash::to_hex; use stacks_common::util::log; @@ -602,6 +602,7 @@ impl Burnchain { debug!("Fetch initial headers"); indexer.sync_headers(headers_height, None).map_err(|e| { error!("Failed to sync initial headers"); + sleep_ms(100); e })?; } diff --git a/testnet/stacks-node/src/burnchains/bitcoin_regtest_controller.rs b/testnet/stacks-node/src/burnchains/bitcoin_regtest_controller.rs index 2e2fdbc20..bbdec5530 100644 --- a/testnet/stacks-node/src/burnchains/bitcoin_regtest_controller.rs +++ b/testnet/stacks-node/src/burnchains/bitcoin_regtest_controller.rs @@ -75,7 +75,7 @@ pub struct BitcoinRegtestController { burnchain_db: Option, chain_tip: Option, use_coordinator: Option, - burnchain_config: Option, + burnchain_config: Burnchain, ongoing_block_commit: Option, should_keep_running: Option>, allow_rbf: bool, @@ -190,7 +190,7 @@ impl BitcoinRegtestController { pub fn with_burnchain( config: Config, coordinator_channel: Option, - burnchain_config: Option, + burnchain: Option, should_keep_running: Option>, ) -> Self { std::fs::create_dir_all(&config.get_burnchain_path_str()) @@ -242,6 +242,8 @@ impl BitcoinRegtestController { runtime: indexer_runtime, }; + let burnchain_config = burnchain.unwrap_or_else(|| Self::default_burnchain(&config)); + Self { use_coordinator: coordinator_channel, config, @@ -258,7 +260,7 @@ impl BitcoinRegtestController { /// create a dummy bitcoin regtest controller. /// used just for submitting bitcoin ops. - pub fn new_dummy(config: Config) -> Self { + pub fn new_dummy(config: Config, burnchain: Burnchain) -> Self { let (network, _) = config.burnchain.get_bitcoin_network(); let burnchain_params = BurnchainParameters::from_params(&config.burnchain.chain, &network) .expect("Bitcoin network unsupported"); @@ -294,28 +296,21 @@ impl BitcoinRegtestController { db: None, burnchain_db: None, chain_tip: None, - burnchain_config: None, + burnchain_config: burnchain, ongoing_block_commit: None, should_keep_running: None, allow_rbf: true, } } - fn default_burnchain(&self) -> Burnchain { - let (network_name, _network_type) = self.config.burnchain.get_bitcoin_network(); - match &self.burnchain_config { - Some(burnchain) => burnchain.clone(), - None => { - let working_dir = self.config.get_burn_db_path(); - match Burnchain::new(&working_dir, &self.config.burnchain.chain, &network_name) { - Ok(burnchain) => burnchain, - Err(e) => { - error!("Failed to instantiate burnchain: {}", e); - panic!() - } - } - } - } + fn default_burnchain(config: &Config) -> Burnchain { + let (network_name, _network_type) = config.burnchain.get_bitcoin_network(); + let working_dir = config.get_burn_db_path(); + let mut burnchain = Burnchain::new(&working_dir, &config.burnchain.chain, &network_name) + .expect("Failed to instantiate burnchain"); + config.update_pox_constants(&mut burnchain.pox_constants); + + burnchain } pub fn get_pox_constants(&self) -> PoxConstants { @@ -324,10 +319,7 @@ impl BitcoinRegtestController { } pub fn get_burnchain(&self) -> Burnchain { - match self.burnchain_config { - Some(ref burnchain) => burnchain.clone(), - None => self.default_burnchain(), - } + self.burnchain_config.clone() } fn receive_blocks_helium(&mut self) -> BurnchainTip { diff --git a/testnet/stacks-node/src/config.rs b/testnet/stacks-node/src/config.rs index 621e5b085..d2e518fb0 100644 --- a/testnet/stacks-node/src/config.rs +++ b/testnet/stacks-node/src/config.rs @@ -6,6 +6,7 @@ use std::path::PathBuf; use rand::RngCore; use stacks::burnchains::bitcoin::BitcoinNetworkType; +use stacks::burnchains::PoxConstants; use stacks::burnchains::{MagicBytes, BLOCKSTACK_MAGIC_MAINNET}; use stacks::chainstate::stacks::index::marf::MARFOpenOpts; use stacks::chainstate::stacks::index::storage::TrieHashCalculationMode; @@ -394,10 +395,22 @@ lazy_static! { } impl Config { + /// This method applies any of this Config's configured PoX constants to the supplied + /// `PoxConstants` struct. + pub fn update_pox_constants(&self, pox_consts: &mut PoxConstants) { + if self.is_mainnet() { + return; + } + if let Some(pox_2_activation_height) = self.burnchain.pox_2_activation { + pox_consts.v1_unlock_height = pox_2_activation_height; + } + } + fn make_epochs( conf_epochs: &[StacksEpochConfigFile], burn_mode: &str, bitcoin_network: BitcoinNetworkType, + pox_2_activation: Option, ) -> Result, String> { let default_epochs = match bitcoin_network { BitcoinNetworkType::Mainnet => { @@ -488,6 +501,16 @@ impl Config { } } + if let Some(pox_2_activation) = pox_2_activation { + let last_epoch = out_epochs + .iter() + .find(|&e| e.epoch_id == StacksEpochId::Epoch21) + .ok_or("Cannot configure pox_2_activation if epoch 2.1 is not configured")?; + if last_epoch.start_height > pox_2_activation as u64 { + Err(format!("Cannot configure pox_2_activation at a lower height than the Epoch 2.1 start height. pox_2_activation = {}, epoch 2.1 start height = {}", pox_2_activation, last_epoch.start_height))?; + } + } + Ok(out_epochs) } @@ -669,13 +692,24 @@ impl Config { .rbf_fee_increment .unwrap_or(default_burnchain_config.rbf_fee_increment), epochs: default_burnchain_config.epochs, + pox_2_activation: burnchain + .pox_2_activation + .or(default_burnchain_config.pox_2_activation), }; + // check that pox_2_activation hasn't been set in mainnet + if result.pox_2_activation.is_some() { + if let BitcoinNetworkType::Mainnet = result.get_bitcoin_network().1 { + return Err("PoX-2 Activation height is not configurable in mainnet".into()); + } + } + if let Some(ref conf_epochs) = burnchain.epochs { result.epochs = Some(Self::make_epochs( conf_epochs, &result.mode, result.get_bitcoin_network().1, + burnchain.pox_2_activation, )?); } @@ -1137,6 +1171,7 @@ pub struct BurnchainConfig { /// Custom override for the definitions of the epochs. This will only be applied for testnet and /// regtest nodes. pub epochs: Option>, + pub pox_2_activation: Option, } impl BurnchainConfig { @@ -1165,6 +1200,7 @@ impl BurnchainConfig { block_commit_tx_estimated_size: BLOCK_COMMIT_TX_ESTIM_SIZE, rbf_fee_increment: DEFAULT_RBF_FEE_RATE_INCREMENT, epochs: None, + pox_2_activation: None, } } @@ -1230,6 +1266,7 @@ pub struct BurnchainConfigFile { pub rbf_fee_increment: Option, pub max_rbf: Option, pub epochs: Option>, + pub pox_2_activation: Option, } #[derive(Clone, Debug, Default)] diff --git a/testnet/stacks-node/src/neon_node.rs b/testnet/stacks-node/src/neon_node.rs index 660f024ca..566232b7a 100644 --- a/testnet/stacks-node/src/neon_node.rs +++ b/testnet/stacks-node/src/neon_node.rs @@ -1022,7 +1022,8 @@ fn spawn_miner_relayer( > = HashMap::new(); let burn_fee_cap = config.burnchain.burn_fee_cap; - let mut bitcoin_controller = BitcoinRegtestController::new_dummy(config.clone()); + let mut bitcoin_controller = + BitcoinRegtestController::new_dummy(config.clone(), burnchain.clone()); let mut microblock_miner_state: Option = None; let mut miner_tip = None; // only set if we won the last sortition let mut last_microblock_tenure_time = 0; diff --git a/testnet/stacks-node/src/node.rs b/testnet/stacks-node/src/node.rs index 45dae4db8..8ac2ef54c 100644 --- a/testnet/stacks-node/src/node.rs +++ b/testnet/stacks-node/src/node.rs @@ -300,11 +300,12 @@ impl Node { .iter() .map(|e| (e.address.clone(), e.amount)) .collect(); - let pox_constants = match config.burnchain.get_bitcoin_network() { + let mut pox_constants = match config.burnchain.get_bitcoin_network() { (_, BitcoinNetworkType::Mainnet) => PoxConstants::mainnet_default(), (_, BitcoinNetworkType::Testnet) => PoxConstants::testnet_default(), (_, BitcoinNetworkType::Regtest) => PoxConstants::regtest_default(), }; + config.update_pox_constants(&mut pox_constants); let mut boot_data = ChainStateBootData { initial_balances, @@ -447,7 +448,9 @@ impl Node { pub fn spawn_peer_server(&mut self, attachments_rx: Receiver>) { // we can call _open_ here rather than _connect_, since connect is first called in // make_genesis_block - let burnchain = Burnchain::regtest(&self.config.get_burn_db_path()); + let mut burnchain = Burnchain::regtest(&self.config.get_burn_db_path()); + self.config + .update_pox_constants(&mut burnchain.pox_constants); let sortdb = SortitionDB::open( &self.config.get_burn_db_file_path(), @@ -1003,7 +1006,10 @@ impl Node { ), }; - let burnchain = Burnchain::regtest(&self.config.get_burn_db_path()); + let mut burnchain = Burnchain::regtest(&self.config.get_burn_db_path()); + self.config + .update_pox_constants(&mut burnchain.pox_constants); + let commit_outs = if !burnchain.is_in_prepare_phase(burnchain_tip.block_snapshot.block_height + 1) { RewardSetInfo::into_commit_outs(None, self.config.is_mainnet()) diff --git a/testnet/stacks-node/src/tests/epoch_205.rs b/testnet/stacks-node/src/tests/epoch_205.rs index 1a1acef4e..d7b90b077 100644 --- a/testnet/stacks-node/src/tests/epoch_205.rs +++ b/testnet/stacks-node/src/tests/epoch_205.rs @@ -545,8 +545,9 @@ fn transition_empty_blocks() { // second block will be the first mined Stacks block next_block_and_wait(&mut btc_regtest_controller, &blocks_processed); - let mut bitcoin_controller = BitcoinRegtestController::new_dummy(conf.clone()); let burnchain = Burnchain::regtest(&conf.get_burn_db_path()); + let mut bitcoin_controller = + BitcoinRegtestController::new_dummy(conf.clone(), burnchain.clone()); // these should all succeed across the epoch boundary for _i in 0..5 {