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

Test specifically the flow when tenure changes #5242

Draft
wants to merge 11 commits into
base: develop
Choose a base branch
from
108 changes: 94 additions & 14 deletions testnet/stacks-node/src/tests/nakamoto_integrations.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,20 @@ use std::{env, thread};

use clarity::vm::ast::ASTRules;
use clarity::vm::costs::ExecutionCost;
use clarity::vm::types::{PrincipalData, QualifiedContractIdentifier};
use clarity::vm::types::{PrincipalData, QualifiedContractIdentifier, StandardPrincipalData};
use clarity::vm::{ClarityName, ClarityVersion, Value};
use http_types::headers::AUTHORIZATION;
use lazy_static::lazy_static;
use libsigner::v0::messages::SignerMessage as SignerMessageV0;
use libsigner::{SignerSession, StackerDBSession};
use rand::RngCore;
use stacks::burnchains::bitcoin::address::{
BitcoinAddress, LegacyBitcoinAddress, LegacyBitcoinAddressType,
};
use stacks::burnchains::bitcoin::keys::BitcoinPublicKey;
use stacks::burnchains::bitcoin::BitcoinNetworkType;
use stacks::burnchains::{MagicBytes, Txid};
use stacks::chainstate::burn::db::sortdb::SortitionDB;
use stacks::chainstate::burn::db::sortdb::{get_block_commit_by_txid, SortitionDB};
use stacks::chainstate::burn::operations::{
BlockstackOperationType, DelegateStxOp, PreStxOp, StackStxOp, TransferStxOp,
VoteForAggregateKeyOp,
Expand Down Expand Up @@ -71,6 +76,7 @@ use stacks::net::api::getstackers::GetStackersResponse;
use stacks::net::api::postblock_proposal::{
BlockValidateReject, BlockValidateResponse, NakamotoBlockProposal, ValidateRejectCode,
};
use stacks::types::{Address, PublicKey};
use stacks::util::hash::hex_bytes;
use stacks::util_lib::boot::boot_code_id;
use stacks::util_lib::signed_structured_data::pox4::{
Expand Down Expand Up @@ -2212,14 +2218,13 @@ fn multiple_miners() {
for tenure_ix in 0..tenure_count {
info!("Mining tenure {}", tenure_ix);
let commits_before = commits_submitted.load(Ordering::SeqCst);
let info_old_tenure = get_chain_info_result(&naka_conf).unwrap();
next_block_and_process_new_stacks_block(&mut btc_regtest_controller, 60, &coord_channel)
.unwrap();

let mut last_tip = BlockHeaderHash([0x00; 32]);
let mut last_tip_height = 0;

// mine the interim blocks
for interim_block_ix in 0..inter_blocks_per_tenure {
let info_old_stacks = get_chain_info_result(&naka_conf).unwrap();
let blocks_processed_before = coord_channel
.lock()
.expect("Mutex poisoned")
Expand All @@ -2239,12 +2244,26 @@ fn multiple_miners() {
})
.unwrap();

let info = get_chain_info_result(&naka_conf).unwrap();
assert_ne!(info.stacks_tip, last_tip);
assert_ne!(info.stacks_tip_height, last_tip_height);

last_tip = info.stacks_tip;
last_tip_height = info.stacks_tip_height;
let info_new_stacks = get_chain_info_result(&naka_conf).unwrap();
assert_ne!(info_new_stacks.stacks_tip, info_old_stacks.stacks_tip);
assert_eq!(
info_new_stacks.stacks_tip_consensus_hash,
info_old_stacks.stacks_tip_consensus_hash
);
assert_eq!(
info_new_stacks.stacks_tip_height,
info_old_stacks.stacks_tip_height + 1,
"Stacks block height should increment by 1"
);
assert_ne!(
info_old_tenure.stacks_tip_consensus_hash,
info_old_stacks.stacks_tip_consensus_hash
);
assert_eq!(
info_new_stacks.burn_block_height,
info_old_tenure.burn_block_height + 1,
"Tenure block height should increment by 1"
);
}

wait_for(20, || {
Expand All @@ -2253,6 +2272,61 @@ fn multiple_miners() {
.unwrap();
}

// check most recently process blocks
// case to check:
// old stacks_tip_consensus_hash != new stacks_tip_consensus_hash and second tx is in the new burn block
let info_node_1_old_block_consensus_hash = get_chain_info(&naka_conf).stacks_tip_consensus_hash;
let info_node_2_old_block_consensus_hash =
get_chain_info(&conf_node_2).stacks_tip_consensus_hash;

// TODO: submit burn block without waiting for it to be mined
// btc_regtest_controller.build_next_block(1); - flashblock
next_block_and_process_new_stacks_block(&mut btc_regtest_controller, 60, &coord_channel)
.unwrap();

// submit tx 1
let miner_1_stacks_address = StandardPrincipalData::from(&node_1_sk);
let http_origin = &naka_conf.node.data_url;
let recipient = PrincipalData::from(StacksAddress::burn_address(false));
let miner_1_account = get_account(http_origin, &miner_1_stacks_address);
let miner_1_nonce = miner_1_account.nonce;
let transfer_tx =
make_stacks_transfer(&sender_sk, miner_1_nonce, send_fee, &recipient, send_amt);
submit_tx(&http_origin, &transfer_tx);
thread::sleep(Duration::from_secs(15));

// submit tx 2
let transfer_tx = make_stacks_transfer(
&sender_sk,
miner_1_nonce + 1,
send_fee,
&recipient,
send_amt,
);
submit_tx(&http_origin, &transfer_tx);

// TODO: wait so the burn block is mined
thread::sleep(Duration::from_secs(15));

let info_node_1_second_tx_consensus_hash = get_chain_info(&naka_conf).stacks_tip_consensus_hash;
let info_node_2_second_tx_consensus_hash =
get_chain_info(&conf_node_2).stacks_tip_consensus_hash;

let info_node_1_new_block_consensus_hash = get_chain_info(&naka_conf).stacks_tip_consensus_hash;
let info_node_2_new_block_consensus_hash =
get_chain_info(&conf_node_2).stacks_tip_consensus_hash;

assert_eq!(
info_node_1_second_tx_consensus_hash,
info_node_1_new_block_consensus_hash
);
assert!(info_node_1_old_block_consensus_hash != info_node_1_new_block_consensus_hash);
assert_eq!(
info_node_2_second_tx_consensus_hash,
info_node_2_new_block_consensus_hash
);
assert!(info_node_2_old_block_consensus_hash != info_node_2_new_block_consensus_hash);

// load the chain tip, and assert that it is a nakamoto block and at least 30 blocks have advanced in epoch 3
let tip = NakamotoChainState::get_canonical_block_header(chainstate.db(), &sortdb)
.unwrap()
Expand All @@ -2267,12 +2341,18 @@ fn multiple_miners() {
let peer_2_height = get_chain_info(&conf_node_2).stacks_tip_height;
info!("Peer height information"; "peer_1" => peer_1_height, "peer_2" => peer_2_height);
assert_eq!(peer_1_height, peer_2_height);

info!(
"Stacks block height {} vs previous formula {}",
tip.stacks_block_height,
block_height_pre_3_0 + ((inter_blocks_per_tenure + 1) * tenure_count)
);
assert!(tip.anchored_header.as_stacks_nakamoto().is_some());

// TODO: shouldn't this be + 2 instead of +1 as 2 stx transactions are submitted with time difference, making 2 different stacks blocks for them
assert_eq!(
tip.stacks_block_height,
block_height_pre_3_0 + ((inter_blocks_per_tenure + 1) * tenure_count),
"Should have mined (1 + interim_blocks_per_tenure) * tenure_count nakamoto blocks"
block_height_pre_3_0 + ((inter_blocks_per_tenure + 1) * tenure_count) + 1,
"Should have mined (1 + interim_blocks_per_tenure) * tenure_count + 1 nakamoto blocks"
);

coord_channel
Expand Down
Loading