Skip to content

Commit 091afbf

Browse files
committed
CRC: update v3_signer_endpoint test to confirm exact number of blocks
Signed-off-by: Jacinta Ferrant <[email protected]>
1 parent 08a62a2 commit 091afbf

File tree

2 files changed

+79
-29
lines changed

2 files changed

+79
-29
lines changed

stackslib/src/chainstate/nakamoto/mod.rs

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3316,7 +3316,7 @@ impl NakamotoChainState {
33163316
StacksPublicKey::recover_to_pubkey(signer_sighash.bits(), &signer_signature)
33173317
.map_err(|e| ChainstateError::InvalidStacksBlock(e.to_string()))?;
33183318
let sql = "INSERT INTO signer_stats(public_key,reward_cycle) VALUES(?1,?2) ON CONFLICT(public_key,reward_cycle) DO UPDATE SET blocks_signed=blocks_signed+1";
3319-
let params = params![serde_json::to_string(&signer_pubkey).unwrap(), reward_cycle];
3319+
let params = params![signer_pubkey.to_hex(), reward_cycle];
33203320
tx.execute(sql, params)?;
33213321
}
33223322
Ok(())
@@ -3331,7 +3331,7 @@ impl NakamotoChainState {
33313331
) -> Result<u64, ChainstateError> {
33323332
let sql =
33333333
"SELECT blocks_signed FROM signer_stats WHERE public_key = ?1 AND reward_cycle = ?2";
3334-
let params = params![serde_json::to_string(&signer_pubkey).unwrap(), reward_cycle];
3334+
let params = params![signer_pubkey.to_hex(), reward_cycle];
33353335
chainstate_db
33363336
.query_row(sql, params, |row| row.get("blocks_signed"))
33373337
.optional()
@@ -4135,12 +4135,19 @@ impl NakamotoChainState {
41354135
if let Some(signer_calculation) = signer_set_calc {
41364136
Self::write_reward_set(chainstate_tx, &new_block_id, &signer_calculation.reward_set)?;
41374137

4138-
let cycle_number = pox_constants
4139-
.reward_cycle_of_prepare_phase(
4140-
first_block_height.into(),
4141-
chain_tip_burn_header_height.into(),
4142-
)
4143-
.or_else(|| reward_cycle.map(|cycle| cycle + 1));
4138+
let cycle_number = if let Some(cycle) = pox_constants.reward_cycle_of_prepare_phase(
4139+
first_block_height.into(),
4140+
chain_tip_burn_header_height.into(),
4141+
) {
4142+
Some(cycle)
4143+
} else {
4144+
pox_constants
4145+
.block_height_to_reward_cycle(
4146+
first_block_height.into(),
4147+
chain_tip_burn_header_height.into(),
4148+
)
4149+
.map(|cycle| cycle + 1)
4150+
};
41444151

41454152
if let Some(cycle) = cycle_number {
41464153
reward_set_data = Some(RewardSetData::new(

testnet/stacks-node/src/tests/nakamoto_integrations.rs

Lines changed: 64 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -8025,11 +8025,23 @@ fn v3_signer_api_endpoint() {
80258025
let (mut conf, _miner_account) = naka_neon_integration_conf(None);
80268026
let password = "12345".to_string();
80278027
conf.connection_options.auth_token = Some(password.clone());
8028+
conf.miner.wait_on_interim_blocks = Duration::from_secs(1);
80288029
let stacker_sk = setup_stacker(&mut conf);
80298030
let signer_sk = Secp256k1PrivateKey::new();
80308031
let signer_addr = tests::to_addr(&signer_sk);
80318032
let signer_pubkey = Secp256k1PublicKey::from_private(&signer_sk);
8033+
let sender_sk = Secp256k1PrivateKey::new();
8034+
// setup sender + recipient for some test stx transfers
8035+
// these are necessary for the interim blocks to get mined at all
8036+
let sender_addr = tests::to_addr(&sender_sk);
8037+
let send_amt = 100;
8038+
let send_fee = 180;
8039+
conf.add_initial_balance(
8040+
PrincipalData::from(sender_addr.clone()).to_string(),
8041+
send_amt + send_fee,
8042+
);
80328043
conf.add_initial_balance(PrincipalData::from(signer_addr.clone()).to_string(), 100000);
8044+
let recipient = PrincipalData::from(StacksAddress::burn_address(false));
80338045

80348046
// only subscribe to the block proposal events
80358047
test_observer::spawn();
@@ -8070,16 +8082,13 @@ fn v3_signer_api_endpoint() {
80708082
);
80718083

80728084
info!("------------------------- Reached Epoch 3.0 -------------------------");
8073-
80748085
blind_signer(&conf, &signers, proposals_submitted);
8075-
wait_for_first_naka_block_commit(60, &commits_submitted);
8076-
80778086
// TODO (hack) instantiate the sortdb in the burnchain
80788087
_ = btc_regtest_controller.sortdb_mut();
80798088

80808089
info!("------------------------- Setup finished, run test -------------------------");
80818090

8082-
let naka_tenures = 20;
8091+
let naka_tenures = conf.burnchain.pox_reward_length.unwrap().into();
80838092
let pre_naka_reward_cycle = 1;
80848093
let http_origin = format!("http://{}", &conf.node.rpc_bind);
80858094

@@ -8102,35 +8111,69 @@ fn v3_signer_api_endpoint() {
81028111
let blocks_signed_pre_naka = get_v3_signer(&signer_pubkey, pre_naka_reward_cycle);
81038112
assert_eq!(blocks_signed_pre_naka, 0);
81048113

8105-
// Keep track of reward cycles encountered
8106-
let mut reward_cycles = HashSet::new();
8114+
let block_height = btc_regtest_controller.get_headers_height();
8115+
let first_reward_cycle = btc_regtest_controller
8116+
.get_burnchain()
8117+
.block_height_to_reward_cycle(block_height)
8118+
.unwrap();
8119+
8120+
let second_reward_cycle = first_reward_cycle.saturating_add(1);
8121+
let second_reward_cycle_start = btc_regtest_controller
8122+
.get_burnchain()
8123+
.reward_cycle_to_block_height(second_reward_cycle)
8124+
.saturating_sub(1);
8125+
8126+
let nmb_naka_blocks_in_first_cycle = second_reward_cycle_start - block_height;
8127+
let nmb_naka_blocks_in_second_cycle = naka_tenures - nmb_naka_blocks_in_first_cycle;
81078128

81088129
// Mine some nakamoto tenures
8109-
for _ in 0..naka_tenures {
8130+
for _i in 0..naka_tenures {
81108131
next_block_and_mine_commit(
81118132
&mut btc_regtest_controller,
81128133
60,
81138134
&coord_channel,
81148135
&commits_submitted,
81158136
)
81168137
.unwrap();
8117-
let block_height = btc_regtest_controller.get_headers_height();
8118-
let reward_cycle = btc_regtest_controller
8119-
.get_burnchain()
8120-
.block_height_to_reward_cycle(block_height)
8121-
.unwrap();
8122-
reward_cycles.insert(reward_cycle);
81238138
}
8139+
let block_height = btc_regtest_controller.get_headers_height();
8140+
let reward_cycle = btc_regtest_controller
8141+
.get_burnchain()
8142+
.block_height_to_reward_cycle(block_height)
8143+
.unwrap();
81248144

8125-
// Make sure we got a couple cycles
8126-
assert!(reward_cycles.len() > 1);
8127-
assert!(!reward_cycles.contains(&pre_naka_reward_cycle));
8145+
assert_eq!(reward_cycle, second_reward_cycle);
81288146

8129-
// Since we have only one signer, it must be signing at least 1 block per reward cycle
8130-
for reward_cycle in reward_cycles.into_iter() {
8131-
let blocks_signed = get_v3_signer(&signer_pubkey, reward_cycle);
8132-
assert_ne!(blocks_signed, 0);
8133-
}
8147+
// Assert that we mined a single block (the commit op) per tenure
8148+
let nmb_signed_first_cycle = get_v3_signer(&signer_pubkey, first_reward_cycle);
8149+
let nmb_signed_second_cycle = get_v3_signer(&signer_pubkey, second_reward_cycle);
8150+
8151+
assert_eq!(nmb_signed_first_cycle, nmb_naka_blocks_in_first_cycle);
8152+
assert_eq!(nmb_signed_second_cycle, nmb_naka_blocks_in_second_cycle);
8153+
8154+
let blocks_processed_before = coord_channel
8155+
.lock()
8156+
.expect("Mutex poisoned")
8157+
.get_stacks_blocks_processed();
8158+
// submit a tx so that the miner will mine an extra stacks block
8159+
let sender_nonce = 0;
8160+
let transfer_tx =
8161+
make_stacks_transfer(&sender_sk, sender_nonce, send_fee, &recipient, send_amt);
8162+
submit_tx(&http_origin, &transfer_tx);
8163+
8164+
wait_for(30, || {
8165+
Ok(coord_channel
8166+
.lock()
8167+
.expect("Mutex poisoned")
8168+
.get_stacks_blocks_processed()
8169+
> blocks_processed_before)
8170+
})
8171+
.unwrap();
8172+
// Assert that we mined an additional block in the second cycle
8173+
assert_eq!(
8174+
get_v3_signer(&signer_pubkey, second_reward_cycle),
8175+
nmb_naka_blocks_in_second_cycle + 1
8176+
);
81348177

81358178
info!("------------------------- Test finished, clean up -------------------------");
81368179

0 commit comments

Comments
 (0)