Skip to content

Commit 33b79cc

Browse files
committed
added inegration test
1 parent 3c7769d commit 33b79cc

File tree

2 files changed

+82
-77
lines changed

2 files changed

+82
-77
lines changed

clarity/src/vm/clarity.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,9 @@ impl From<CheckError> for Error {
6161
CheckErrors::MemoryBalanceExceeded(_a, _b) => {
6262
Error::CostError(ExecutionCost::max_value(), ExecutionCost::max_value())
6363
}
64+
CheckErrors::ExecutionTimeExpired => {
65+
Error::CostError(ExecutionCost::max_value(), ExecutionCost::max_value())
66+
}
6467
_ => Error::Analysis(e),
6568
}
6669
}
@@ -75,6 +78,9 @@ impl From<InterpreterError> for Error {
7578
InterpreterError::Unchecked(CheckErrors::CostOverflow) => {
7679
Error::CostError(ExecutionCost::max_value(), ExecutionCost::max_value())
7780
}
81+
InterpreterError::Unchecked(CheckErrors::ExecutionTimeExpired) => {
82+
Error::CostError(ExecutionCost::max_value(), ExecutionCost::max_value())
83+
}
7884
_ => Error::Interpreter(e),
7985
}
8086
}
@@ -90,6 +96,9 @@ impl From<ParseError> for Error {
9096
ParseErrors::MemoryBalanceExceeded(_a, _b) => {
9197
Error::CostError(ExecutionCost::max_value(), ExecutionCost::max_value())
9298
}
99+
ParseErrors::ExecutionTimeExpired => {
100+
Error::CostError(ExecutionCost::max_value(), ExecutionCost::max_value())
101+
}
93102
_ => Error::Parse(e),
94103
}
95104
}

testnet/stacks-node/src/tests/signer/v0.rs

Lines changed: 73 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -955,6 +955,20 @@ impl MultipleMinerTest {
955955
self.signer_test.shutdown();
956956
}
957957

958+
pub fn wait_for_test_observer_blocks(&self, timeout_secs: u64) {
959+
let block_header_heash_tip = format!("0x{}", self.get_peer_stacks_tip().to_hex());
960+
961+
wait_for(timeout_secs, || {
962+
for block in test_observer::get_blocks().iter().rev() {
963+
if block["block_hash"].as_str().unwrap() == block_header_heash_tip {
964+
return Ok(true);
965+
}
966+
}
967+
Ok(false)
968+
})
969+
.expect("Timed out waiting for test_observer blocks");
970+
}
971+
958972
/// Wait for both miners to have the same stacks tip height
959973
pub fn wait_for_chains(&self, timeout_secs: u64) {
960974
wait_for(timeout_secs, || {
@@ -992,11 +1006,10 @@ fn last_block_contains_tenure_change_tx(cause: TenureChangeCause) -> bool {
9921006
}
9931007
}
9941008

995-
// Returns whether the last block in the test observer contains a tenure change
996-
/// transaction with the given cause.
1009+
/// Check if a txid exists in the last block
9971010
fn last_block_contains_txid(txid: &str) -> bool {
9981011
let blocks = test_observer::get_blocks();
999-
let last_block = &blocks.last().unwrap();
1012+
let last_block = blocks.last().unwrap();
10001013
let transactions = last_block["transactions"].as_array().unwrap();
10011014
for tx in transactions {
10021015
let raw_tx = tx["raw_tx"].as_str().unwrap();
@@ -12514,15 +12527,14 @@ fn signer_can_accept_rejected_block() {
1251412527
}
1251512528

1251612529
/// Test a scenario where:
12517-
/// Two miners boot to Nakamoto.
12530+
/// Two miners boot to Nakamoto (first miner has max_execution_time set to 0).
1251812531
/// Sortition occurs. Miner 1 wins.
12519-
/// Miner 1 proposes a block N
12520-
/// Signers accept and the stacks tip advances to N
12521-
/// Miner 1's block commits are paused so it cannot confirm the next tenure.
12532+
/// Miner 1 successfully mines block N with contract-publish
12533+
/// Miner 1 successfully mines block N+1 with transfer and a contract-call that gets rejected (by max_execution_time)
12534+
/// Miner 1 successfully mines block N+2 with transfer tx (this is mainly for ensuring everything still works after the expiration time)
1252212535
/// Sortition occurs. Miner 2 wins.
12523-
/// Miner 2 successfully mines blocks N+1, N+2, and N+3
12524-
/// Sortition occurs quickly, within first_proposal_burn_block_timing_secs. Miner 1 wins.
12525-
/// Miner 1 proposes block N+1' but gets rejected as more than one block has been mined in the current tenure (by miner2)
12536+
/// Miner 2 successfully mines block N+3 including the contract-call previously rejected by miner 1
12537+
/// Ensures both the miners are aligned
1252612538
#[test]
1252712539
#[ignore]
1252812540
fn miner_rejection_by_contract_call_execution_time_expired() {
@@ -12555,7 +12567,7 @@ fn miner_rejection_by_contract_call_execution_time_expired() {
1255512567

1255612568
let (conf_1, _) = miners.get_node_configs();
1255712569
let (miner_pkh_1, miner_pkh_2) = miners.get_miner_public_key_hashes();
12558-
let (miner_pk_1, miner_pk_2) = miners.get_miner_public_keys();
12570+
let (_miner_pk_1, miner_pk_2) = miners.get_miner_public_keys();
1255912571

1256012572
info!("------------------------- Pause Miner 2's Block Commits -------------------------");
1256112573

@@ -12570,100 +12582,84 @@ fn miner_rejection_by_contract_call_execution_time_expired() {
1257012582
info!("------------------------- Pause Miner 1's Block Commits -------------------------");
1257112583
rl1_skip_commit_op.set(true);
1257212584

12573-
// First, lets deploy the contract
12574-
let dummy_contract_src = "
12575-
(define-public (run-f)
12576-
(ok (1)))
12577-
";
12578-
1257912585
info!("------------------------- Miner 1 Mines a Nakamoto Block N -------------------------");
1258012586
miners
1258112587
.mine_bitcoin_block_and_tenure_change_tx(&sortdb, TenureChangeCause::BlockFound, 60)
1258212588
.expect("Failed to mine BTC block followed by Block N");
1258312589

12590+
miners.wait_for_test_observer_blocks(60);
12591+
12592+
miners.send_fee = 300;
1258412593
// First, lets deploy the contract
12585-
let _contract_publish_txid =
12586-
miners.send_and_mine_contract_publish("dummy-contract", dummy_contract_src, 60);
12594+
let dummy_contract_src = "(define-public (dummy (number uint)) (begin (ok (+ number u1))))";
12595+
12596+
let contract_publish_txid = miners
12597+
.send_and_mine_contract_publish("dummy-contract", dummy_contract_src, 60)
12598+
.expect("Failed to publish contract in a new block");
12599+
12600+
miners.wait_for_test_observer_blocks(60);
12601+
12602+
assert_eq!(last_block_contains_txid(&contract_publish_txid), true);
12603+
12604+
info!("------------------------- Miner 1 Mines a Nakamoto Block N+1 -------------------------");
1258712605

1258812606
let stacks_height_before = miners.get_peer_stacks_tip_height();
1258912607

12590-
// try calling it (has to fail)
12591-
let contract_call_txid = miners.send_contract_call("dummy-contract", "f", &[]);
12608+
let tx1 = miners.send_transfer_tx();
1259212609

12593-
let miner_1_block_n =
12594-
wait_for_block_pushed_by_miner_key(30, stacks_height_before + 1, &miner_pk_1)
12595-
.expect("Failed to get block N+1");
12610+
// try calling the contract (has to fail)
12611+
let contract_call_txid =
12612+
miners.send_contract_call("dummy-contract", "dummy", &[clarity::vm::Value::UInt(1)]);
1259612613

12614+
let _ = wait_for(60, || {
12615+
Ok(miners.get_peer_stacks_tip_height() > stacks_height_before)
12616+
});
12617+
12618+
miners.wait_for_test_observer_blocks(60);
12619+
12620+
assert_eq!(last_block_contains_txid(&tx1), true);
1259712621
assert_eq!(last_block_contains_txid(&contract_call_txid), false);
1259812622

12599-
// assure we have a successful sortition that miner 1 won
12623+
info!("------------------------- Miner 1 Mines a Nakamoto Block N+2 -------------------------");
12624+
12625+
miners.sender_nonce -= 1;
12626+
12627+
let tx2 = miners
12628+
.send_and_mine_transfer_tx(60)
12629+
.expect("Failed to mine N + 2");
12630+
12631+
miners.wait_for_test_observer_blocks(60);
12632+
12633+
assert_eq!(last_block_contains_txid(&tx2), true);
12634+
1260012635
verify_sortition_winner(&sortdb, &miner_pkh_1);
1260112636

1260212637
info!("------------------------- Miner 2 Submits a Block Commit -------------------------");
1260312638
miners.submit_commit_miner_2(&sortdb);
1260412639

12605-
info!("------------------------- Pause Miner 2's Block Mining -------------------------");
12606-
TEST_MINE_STALL.set(true);
12607-
1260812640
info!("------------------------- Mine Tenure -------------------------");
1260912641
miners
12610-
.mine_bitcoin_blocks_and_confirm(&sortdb, 1, 60)
12611-
.expect("Failed to mine BTC block");
12612-
12613-
info!("------------------------- Miner 1 Submits a Block Commit -------------------------");
12614-
miners.submit_commit_miner_1(&sortdb);
12642+
.mine_bitcoin_block_and_tenure_change_tx(&sortdb, TenureChangeCause::BlockFound, 60)
12643+
.expect("Failed to mine BTC block followed by Block N+3");
1261512644

12616-
info!("------------------------- Miner 2 Mines Block N+2 -------------------------");
12645+
info!("------------------------- Miner 2 Mines Block N+3 -------------------------");
1261712646

12618-
TEST_MINE_STALL.set(false);
12619-
let _ = wait_for_block_pushed_by_miner_key(30, block_n_height + 1, &miner_pk_2)
12620-
.expect("Failed to get block N+1");
12647+
let stacks_height_before = miners.get_peer_stacks_tip_height();
1262112648

12622-
// assure we have a successful sortition that miner 2 won
12623-
verify_sortition_winner(&sortdb, &miner_pkh_2);
12649+
let contract_call_txid =
12650+
miners.send_contract_call("dummy-contract", "dummy", &[clarity::vm::Value::UInt(1)]);
1262412651

12625-
assert_eq!(
12626-
get_chain_info(&conf_1).stacks_tip_height,
12627-
block_n_height + 1
12628-
);
12629-
12630-
info!("------------------------- Miner 2 Mines N+2 and N+3 -------------------------");
12631-
miners
12632-
.send_and_mine_transfer_tx(30)
12633-
.expect("Failed to send and mine transfer tx");
12634-
miners
12635-
.send_and_mine_transfer_tx(30)
12636-
.expect("Failed to send and mine transfer tx");
12637-
assert_eq!(
12638-
get_chain_info(&conf_1).stacks_tip_height,
12639-
block_n_height + 3
12640-
);
12652+
let _ = wait_for_block_pushed_by_miner_key(30, stacks_height_before + 1, &miner_pk_2)
12653+
.expect("Failed to get block N+3");
1264112654

12642-
info!("------------------------- Miner 1 Wins the Next Tenure, Mines N+3 -------------------------");
12643-
miners.btc_regtest_controller_mut().build_next_block(1);
12655+
miners.wait_for_test_observer_blocks(60);
1264412656

12645-
let _ = wait_for_block_pushed_by_miner_key(30, block_n_height + 1, &miner_pk_2)
12646-
.expect("Failed to get block N+3");
12657+
assert_eq!(last_block_contains_txid(&contract_call_txid), true);
1264712658

12648-
// check N+2 contains the contract call (previously rejected by miner 1)
12649-
let miner1_blocks_after_boot_to_epoch3 = get_nakamoto_headers(&conf_1)
12650-
.into_iter()
12651-
.filter(|block| {
12652-
// skip first nakamoto block
12653-
if block.stacks_block_height == stacks_height_before {
12654-
return false;
12655-
}
12656-
let nakamoto_block_header = block.anchored_header.as_stacks_nakamoto().unwrap();
12657-
miner_pk_1
12658-
.verify(
12659-
nakamoto_block_header.miner_signature_hash().as_bytes(),
12660-
&nakamoto_block_header.miner_signature,
12661-
)
12662-
.unwrap()
12663-
})
12664-
.count();
12659+
verify_sortition_winner(&sortdb, &miner_pkh_2);
1266512660

12666-
assert_eq!(miner1_blocks_after_boot_to_epoch3, 1);
12661+
// ensure both miners are aligned
12662+
miners.wait_for_chains(60);
1266712663

1266812664
info!("------------------------- Shutdown -------------------------");
1266912665
miners.shutdown();

0 commit comments

Comments
 (0)