Skip to content

Commit 8c0137c

Browse files
committed
Merge branch 'develop' of https://github.com/stacks-network/stacks-core into chore/remove-v1-signer
2 parents 04c6c8a + 9c90c5c commit 8c0137c

File tree

4 files changed

+136
-78
lines changed

4 files changed

+136
-78
lines changed

.github/workflows/bitcoin-tests.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ jobs:
114114
- tests::signer::v0::partial_tenure_fork
115115
- tests::signer::v0::mine_2_nakamoto_reward_cycles
116116
- tests::signer::v0::signer_set_rollover
117+
- tests::signer::v0::signing_in_0th_tenure_of_reward_cycle
117118
- tests::nakamoto_integrations::burn_ops_integration_test
118119
- tests::nakamoto_integrations::check_block_heights
119120
- tests::nakamoto_integrations::clarity_burn_state

stacks-signer/src/config.rs

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -235,13 +235,8 @@ impl TryFrom<RawConfigFile> for GlobalConfig {
235235
ConfigError::BadField("endpoint".to_string(), raw_data.endpoint.clone())
236236
})?;
237237

238-
let stacks_private_key =
239-
StacksPrivateKey::from_hex(&raw_data.stacks_private_key).map_err(|_| {
240-
ConfigError::BadField(
241-
"stacks_private_key".to_string(),
242-
raw_data.stacks_private_key.clone(),
243-
)
244-
})?;
238+
let stacks_private_key = StacksPrivateKey::from_hex(&raw_data.stacks_private_key)
239+
.map_err(|e| ConfigError::BadField("stacks_private_key".to_string(), e.into()))?;
245240
let stacks_public_key = StacksPublicKey::from_private(&stacks_private_key);
246241
let signer_hash = Hash160::from_data(stacks_public_key.to_bytes_compressed().as_slice());
247242
let stacks_address =

stackslib/src/net/relay.rs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1725,9 +1725,6 @@ impl Relayer {
17251725
"Failed to validate Nakamoto blocks pushed from {:?}: {:?}",
17261726
neighbor_key, &e
17271727
);
1728-
1729-
// punish this peer
1730-
bad_neighbors.push((*neighbor_key).clone());
17311728
break;
17321729
}
17331730

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

Lines changed: 133 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ use stacks::chainstate::stacks::db::{StacksBlockHeaderTypes, StacksChainState, S
3535
use stacks::codec::StacksMessageCodec;
3636
use stacks::core::{StacksEpochId, CHAIN_ID_TESTNET};
3737
use stacks::libstackerdb::StackerDBChunkData;
38+
use stacks::net::api::getsigner::GetSignerResponse;
3839
use stacks::net::api::postblock_proposal::{ValidateRejectCode, TEST_VALIDATE_STALL};
3940
use stacks::net::relay::fault_injection::set_ignore_block;
4041
use stacks::types::chainstate::{StacksAddress, StacksBlockId, StacksPrivateKey, StacksPublicKey};
@@ -1991,35 +1992,29 @@ fn end_of_tenure() {
19911992
std::thread::sleep(Duration::from_millis(100));
19921993
}
19931994

1994-
while signer_test.get_current_reward_cycle() != final_reward_cycle {
1995-
next_block_and(
1996-
&mut signer_test.running_nodes.btc_regtest_controller,
1997-
10,
1998-
|| Ok(true),
1999-
)
2000-
.unwrap();
2001-
assert!(
2002-
start_time.elapsed() <= short_timeout,
2003-
"Timed out waiting to enter the next reward cycle"
2004-
);
2005-
std::thread::sleep(Duration::from_millis(100));
2006-
}
1995+
wait_for(short_timeout.as_secs(), || {
1996+
let result = signer_test.get_current_reward_cycle() == final_reward_cycle;
1997+
if !result {
1998+
signer_test
1999+
.running_nodes
2000+
.btc_regtest_controller
2001+
.build_next_block(1);
2002+
}
2003+
Ok(result)
2004+
})
2005+
.expect("Timed out waiting to enter the next reward cycle");
20072006

2008-
while test_observer::get_burn_blocks()
2009-
.last()
2010-
.unwrap()
2011-
.get("burn_block_height")
2012-
.unwrap()
2013-
.as_u64()
2014-
.unwrap()
2015-
< final_reward_cycle_height_boundary + 1
2016-
{
2017-
assert!(
2018-
start_time.elapsed() <= short_timeout,
2019-
"Timed out waiting for burn block events"
2020-
);
2021-
std::thread::sleep(Duration::from_millis(100));
2022-
}
2007+
wait_for(short_timeout.as_secs(), || {
2008+
let blocks = test_observer::get_burn_blocks()
2009+
.last()
2010+
.unwrap()
2011+
.get("burn_block_height")
2012+
.unwrap()
2013+
.as_u64()
2014+
.unwrap();
2015+
Ok(blocks > final_reward_cycle_height_boundary)
2016+
})
2017+
.expect("Timed out waiting for burn block events");
20232018

20242019
signer_test.wait_for_cycle(30, final_reward_cycle);
20252020

@@ -2077,21 +2072,11 @@ fn retry_on_rejection() {
20772072
let burnchain = signer_test.running_nodes.conf.get_burnchain();
20782073
let sortdb = burnchain.open_sortition_db(true).unwrap();
20792074

2080-
loop {
2081-
next_block_and(
2082-
&mut signer_test.running_nodes.btc_regtest_controller,
2083-
60,
2084-
|| Ok(true),
2085-
)
2086-
.unwrap();
2087-
2088-
sleep_ms(10_000);
2089-
2075+
wait_for(30, || {
20902076
let tip = SortitionDB::get_canonical_burn_chain_tip(&sortdb.conn()).unwrap();
2091-
if tip.sortition {
2092-
break;
2093-
}
2094-
}
2077+
Ok(tip.sortition)
2078+
})
2079+
.expect("Timed out waiting for sortition");
20952080

20962081
// mine a nakamoto block
20972082
let mined_blocks = signer_test.running_nodes.nakamoto_blocks_mined.clone();
@@ -2532,12 +2517,10 @@ fn mock_sign_epoch_25() {
25322517
{
25332518
let mut mock_block_mesage = None;
25342519
let mock_poll_time = Instant::now();
2535-
next_block_and(
2536-
&mut signer_test.running_nodes.btc_regtest_controller,
2537-
60,
2538-
|| Ok(true),
2539-
)
2540-
.unwrap();
2520+
signer_test
2521+
.running_nodes
2522+
.btc_regtest_controller
2523+
.build_next_block(1);
25412524
let current_burn_block_height = signer_test
25422525
.running_nodes
25432526
.btc_regtest_controller
@@ -2744,12 +2727,10 @@ fn multiple_miners_mock_sign_epoch_25() {
27442727
{
27452728
let mut mock_block_mesage = None;
27462729
let mock_poll_time = Instant::now();
2747-
next_block_and(
2748-
&mut signer_test.running_nodes.btc_regtest_controller,
2749-
60,
2750-
|| Ok(true),
2751-
)
2752-
.unwrap();
2730+
signer_test
2731+
.running_nodes
2732+
.btc_regtest_controller
2733+
.build_next_block(1);
27532734
let current_burn_block_height = signer_test
27542735
.running_nodes
27552736
.btc_regtest_controller
@@ -4536,21 +4517,11 @@ fn miner_recovers_when_broadcast_block_delay_across_tenures_occurs() {
45364517
let burnchain = signer_test.running_nodes.conf.get_burnchain();
45374518
let sortdb = burnchain.open_sortition_db(true).unwrap();
45384519

4539-
loop {
4540-
next_block_and(
4541-
&mut signer_test.running_nodes.btc_regtest_controller,
4542-
60,
4543-
|| Ok(true),
4544-
)
4545-
.unwrap();
4546-
4547-
sleep_ms(10_000);
4548-
4520+
wait_for(30, || {
45494521
let tip = SortitionDB::get_canonical_burn_chain_tip(&sortdb.conn()).unwrap();
4550-
if tip.sortition {
4551-
break;
4552-
}
4553-
}
4522+
Ok(tip.sortition)
4523+
})
4524+
.expect("Timed out waiting for sortition");
45544525

45554526
// submit a tx so that the miner will mine a stacks block
45564527
let mut sender_nonce = 0;
@@ -4811,3 +4782,97 @@ fn miner_recovers_when_broadcast_block_delay_across_tenures_occurs() {
48114782
assert_eq!(info_after.stacks_tip.to_string(), block_n_2.block_hash);
48124783
assert_ne!(block_n_2, block_n);
48134784
}
4785+
4786+
#[test]
4787+
#[ignore]
4788+
/// Test that signers can successfully sign a block proposal in the 0th tenure of a reward cycle
4789+
/// This ensures there is no race condition in the /v2/pox endpoint which could prevent it from updating
4790+
/// on time, possibly triggering an "off by one" like behaviour in the 0th tenure.
4791+
///
4792+
fn signing_in_0th_tenure_of_reward_cycle() {
4793+
if env::var("BITCOIND_TEST") != Ok("1".into()) {
4794+
return;
4795+
}
4796+
4797+
tracing_subscriber::registry()
4798+
.with(fmt::layer())
4799+
.with(EnvFilter::from_default_env())
4800+
.init();
4801+
4802+
info!("------------------------- Test Setup -------------------------");
4803+
let num_signers = 5;
4804+
let mut signer_test: SignerTest<SpawnedSigner> = SignerTest::new(num_signers, vec![]);
4805+
let signer_public_keys = signer_test
4806+
.signer_stacks_private_keys
4807+
.iter()
4808+
.map(StacksPublicKey::from_private)
4809+
.collect::<Vec<_>>();
4810+
let long_timeout = Duration::from_secs(200);
4811+
signer_test.boot_to_epoch_3();
4812+
let curr_reward_cycle = signer_test.get_current_reward_cycle();
4813+
let next_reward_cycle = curr_reward_cycle + 1;
4814+
// Mine until the boundary of the first full Nakamoto reward cycles (epoch 3 starts in the middle of one)
4815+
let next_reward_cycle_height_boundary = signer_test
4816+
.running_nodes
4817+
.btc_regtest_controller
4818+
.get_burnchain()
4819+
.reward_cycle_to_block_height(next_reward_cycle)
4820+
.saturating_sub(1);
4821+
4822+
info!("------------------------- Advancing to {next_reward_cycle} Boundary at Block {next_reward_cycle_height_boundary} -------------------------");
4823+
signer_test.run_until_burnchain_height_nakamoto(
4824+
long_timeout,
4825+
next_reward_cycle_height_boundary,
4826+
num_signers,
4827+
);
4828+
4829+
let http_origin = format!("http://{}", &signer_test.running_nodes.conf.node.rpc_bind);
4830+
let get_v3_signer = |pubkey: &Secp256k1PublicKey, reward_cycle: u64| {
4831+
let url = &format!(
4832+
"{http_origin}/v3/signer/{pk}/{reward_cycle}",
4833+
pk = pubkey.to_hex()
4834+
);
4835+
info!("Send request: GET {url}");
4836+
reqwest::blocking::get(url)
4837+
.unwrap_or_else(|e| panic!("GET request failed: {e}"))
4838+
.json::<GetSignerResponse>()
4839+
.unwrap()
4840+
.blocks_signed
4841+
};
4842+
4843+
assert_eq!(signer_test.get_current_reward_cycle(), curr_reward_cycle);
4844+
4845+
for signer in &signer_public_keys {
4846+
let blocks_signed = get_v3_signer(&signer, next_reward_cycle);
4847+
assert_eq!(blocks_signed, 0);
4848+
}
4849+
4850+
info!("------------------------- Enter Reward Cycle {next_reward_cycle} -------------------------");
4851+
for signer in &signer_public_keys {
4852+
let blocks_signed = get_v3_signer(&signer, next_reward_cycle);
4853+
assert_eq!(blocks_signed, 0);
4854+
}
4855+
let blocks_before = signer_test
4856+
.running_nodes
4857+
.nakamoto_blocks_mined
4858+
.load(Ordering::SeqCst);
4859+
signer_test
4860+
.running_nodes
4861+
.btc_regtest_controller
4862+
.build_next_block(1);
4863+
4864+
wait_for(30, || {
4865+
Ok(signer_test
4866+
.running_nodes
4867+
.nakamoto_blocks_mined
4868+
.load(Ordering::SeqCst)
4869+
> blocks_before)
4870+
})
4871+
.unwrap();
4872+
4873+
for signer in &signer_public_keys {
4874+
let blocks_signed = get_v3_signer(&signer, next_reward_cycle);
4875+
assert_eq!(blocks_signed, 1);
4876+
}
4877+
assert_eq!(signer_test.get_current_reward_cycle(), next_reward_cycle);
4878+
}

0 commit comments

Comments
 (0)