Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: improved stacking orders #1331

Merged
merged 17 commits into from
Jan 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
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
4 changes: 2 additions & 2 deletions components/clarinet-cli/src/generate/project.rs
Original file line number Diff line number Diff line change
Expand Up @@ -415,14 +415,14 @@ disable_stacks_api = false

# Send some stacking orders
[[devnet.pox_stacking_orders]]
start_at_cycle = 0
start_at_cycle = 2
duration = 12
wallet = "wallet_1"
slots = 2
btc_address = "mr1iPkD9N3RJZZxXRk7xF9d36gffa6exNC"

[[devnet.pox_stacking_orders]]
start_at_cycle = 1
start_at_cycle = 2
duration = 12
wallet = "wallet_2"
slots = 1
Expand Down
2 changes: 1 addition & 1 deletion components/clarinet-files/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ pub use network_manifest::{
DEFAULT_BITCOIN_NODE_IMAGE, DEFAULT_DERIVATION_PATH, DEFAULT_DOCKER_PLATFORM,
DEFAULT_EPOCH_2_0, DEFAULT_EPOCH_2_05, DEFAULT_EPOCH_2_1, DEFAULT_EPOCH_2_2, DEFAULT_EPOCH_2_3,
DEFAULT_EPOCH_2_4, DEFAULT_EPOCH_2_5, DEFAULT_EPOCH_3_0, DEFAULT_FAUCET_MNEMONIC,
DEFAULT_POSTGRES_IMAGE, DEFAULT_STACKS_API_IMAGE, DEFAULT_STACKS_API_IMAGE_NAKA,
DEFAULT_FIRST_BURN_HEADER_HEIGHT, DEFAULT_POSTGRES_IMAGE, DEFAULT_STACKS_API_IMAGE,
DEFAULT_STACKS_EXPLORER_IMAGE, DEFAULT_STACKS_MINER_MNEMONIC, DEFAULT_STACKS_NODE_IMAGE,
DEFAULT_STACKS_NODE_IMAGE_NAKA, DEFAULT_SUBNET_API_IMAGE, DEFAULT_SUBNET_CONTRACT_ID,
DEFAULT_SUBNET_MNEMONIC, DEFAULT_SUBNET_NODE_IMAGE,
Expand Down
57 changes: 57 additions & 0 deletions components/clarinet-files/src/network_manifest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,13 @@ pub const DEFAULT_EPOCH_2_4: u64 = 104;
pub const DEFAULT_EPOCH_2_5: u64 = 105;
pub const DEFAULT_EPOCH_3_0: u64 = 121;

// Currently, the pox-4 contract has these values hardcoded:
// https://github.com/stacks-network/stacks-core/blob/e09ab931e2f15ff70f3bb5c2f4d7afb[…]42bd7bec6/stackslib/src/chainstate/stacks/boot/pox-testnet.clar
// but they may be configurable in the future.
pub const DEFAULT_POX_PREPARE_LENGTH: u64 = 4;
pub const DEFAULT_POX_REWARD_LENGTH: u64 = 10;
pub const DEFAULT_FIRST_BURN_HEADER_HEIGHT: u64 = 100;

#[derive(Serialize, Deserialize, Debug)]
pub struct NetworkManifestFile {
network: NetworkConfigFile,
Expand Down Expand Up @@ -316,6 +323,7 @@ pub struct PoxStackingOrder {
pub wallet: String,
pub slots: u64,
pub btc_address: String,
pub auto_extend: Option<bool>,
}

#[derive(Serialize, Deserialize, Debug, Clone)]
Expand Down Expand Up @@ -770,6 +778,34 @@ impl NetworkManifest {
let remapped_subnet_contract_id =
format!("{}.{}", default_deployer.stx_address, contract_id.name);

// validate that epoch 3.0 is started in a reward phase
let epoch_3_0 = devnet_config.epoch_3_0.unwrap_or(DEFAULT_EPOCH_3_0);
if !is_in_reward_phase(
DEFAULT_FIRST_BURN_HEADER_HEIGHT,
DEFAULT_POX_REWARD_LENGTH,
DEFAULT_POX_PREPARE_LENGTH,
&epoch_3_0,
) {
return Err(format!(
"Epoch 3.0 must start *during* a reward phase, not a prepare phase. Epoch 3.0 start set to: {}. Reward Cycle Length: {}. Prepare Phase Length: {}",
epoch_3_0, DEFAULT_POX_REWARD_LENGTH, DEFAULT_POX_PREPARE_LENGTH
));
}

// for stacking orders, we validate that wallet names match one of the provided accounts
if let Some(ref val) = devnet_config.pox_stacking_orders {
for (i, stacking_order) in val.iter().enumerate() {
let wallet_name = &stacking_order.wallet;
let wallet_is_in_accounts = accounts
.iter()
.any(|(account_name, _)| wallet_name == account_name);
if !wallet_is_in_accounts {
return Err(format!("Account data was not provided for the wallet ({}) listed in stacking order {}.", wallet_name, i + 1));
};
}

devnet_config.pox_stacking_orders = Some(val.clone());
}
let config = DevnetConfig {
name: devnet_config.name.take().unwrap_or("devnet".into()),
network_id: devnet_config.network_id,
Expand Down Expand Up @@ -1008,6 +1044,27 @@ fn compute_btc_address(public_key: &PublicKey, network: &BitcoinNetwork) -> Stri
btc_address.to_string()
}

// This logic was taken from stacks-core:
// https://github.com/stacks-network/stacks-core/blob/524b0e1ae9ad3c8d2d2ac37e72be4aee2c045ef8/src/burnchains/mod.rs#L513C30-L530
pub fn is_in_reward_phase(
first_block_height: u64,
reward_cycle_length: u64,
prepare_length: u64,
block_height: &u64,
) -> bool {
if block_height <= &first_block_height {
// not a reward cycle start if we're the first block after genesis.
false
} else {
let effective_height = block_height - first_block_height;
let reward_index = effective_height % reward_cycle_length;

// NOTE: first block in reward cycle is mod 1, so mod 0 is the last block in the
// prepare phase.
!(reward_index == 0 || reward_index > (reward_cycle_length - prepare_length))
}
}

#[cfg(feature = "wasm")]
fn compute_btc_address(_public_key: &PublicKey, _network: &BitcoinNetwork) -> String {
"__not_implemented__".to_string()
Expand Down
1 change: 1 addition & 0 deletions components/stacks-devnet-js/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -746,6 +746,7 @@ impl StacksDevnet {
wallet,
slots,
btc_address,
auto_extend: Some(false),
});
}
overrides.pox_stacking_orders = Some(stacking_orders);
Expand Down
Loading
Loading