Skip to content

Commit 29ee7ed

Browse files
committed
test: Add partial integration test for mock miner replay
1 parent 91952ac commit 29ee7ed

File tree

5 files changed

+229
-43
lines changed

5 files changed

+229
-43
lines changed

.github/workflows/bitcoin-tests.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ jobs:
7272
- tests::neon_integrations::confirm_unparsed_ongoing_ops
7373
- tests::neon_integrations::min_txs
7474
- tests::neon_integrations::vote_for_aggregate_key_burn_op_test
75+
- tests::neon_integrations::mock_miner_replay
7576
- tests::epoch_25::microblocks_disabled
7677
- tests::should_succeed_handling_malformed_and_valid_txs
7778
- tests::nakamoto_integrations::simple_neon_integration

stacks-common/src/types/chainstate.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,11 @@ impl_byte_array_serde!(TrieHash);
3030

3131
pub const TRIEHASH_ENCODED_SIZE: usize = 32;
3232

33-
#[derive(Serialize, Deserialize)]
3433
pub struct BurnchainHeaderHash(pub [u8; 32]);
3534
impl_array_newtype!(BurnchainHeaderHash, u8, 32);
3635
impl_array_hexstring_fmt!(BurnchainHeaderHash);
3736
impl_byte_array_newtype!(BurnchainHeaderHash, u8, 32);
37+
impl_byte_array_serde!(BurnchainHeaderHash);
3838

3939
pub struct BlockHeaderHash(pub [u8; 32]);
4040
impl_array_newtype!(BlockHeaderHash, u8, 32);

stackslib/src/chainstate/stacks/miner.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,9 +76,9 @@ pub struct AssembledAnchorBlock {
7676
/// Consensus hash this Stacks block
7777
pub consensus_hash: ConsensusHash,
7878
/// Burnchain tip's block hash when we finished mining
79-
pub my_burn_hash: BurnchainHeaderHash,
79+
pub burn_hash: BurnchainHeaderHash,
8080
/// Burnchain tip's block height when we finished mining
81-
pub my_block_height: u64,
81+
pub burn_block_height: u64,
8282
/// Burnchain tip's block hash when we started mining (could be different)
8383
pub orig_burn_hash: BurnchainHeaderHash,
8484
/// The block we produced

testnet/stacks-node/src/neon_node.rs

Lines changed: 50 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@
140140
use std::cmp;
141141
use std::cmp::Ordering as CmpOrdering;
142142
use std::collections::{BTreeMap, HashMap, HashSet, VecDeque};
143-
use std::io::{Read, Write};
143+
use std::io::{ErrorKind, Read, Write};
144144
use std::net::SocketAddr;
145145
use std::sync::mpsc::{Receiver, TrySendError};
146146
use std::thread::JoinHandle;
@@ -1123,7 +1123,7 @@ impl BlockMinerThread {
11231123
) -> Vec<&AssembledAnchorBlock> {
11241124
let mut ret = vec![];
11251125
for (_, (assembled_block, _)) in last_mined_blocks.iter() {
1126-
if assembled_block.my_block_height >= burn_height {
1126+
if assembled_block.burn_block_height >= burn_height {
11271127
ret.push(assembled_block);
11281128
}
11291129
}
@@ -1633,7 +1633,7 @@ impl BlockMinerThread {
16331633
&prev_block.anchored_block.block_hash(),
16341634
&prev_block.parent_consensus_hash,
16351635
&prev_block.anchored_block.header.parent_block,
1636-
&prev_block.my_burn_hash,
1636+
&prev_block.burn_hash,
16371637
&prev_block.anchored_block.txs.len()
16381638
);
16391639
max_txs = cmp::max(max_txs, prev_block.anchored_block.txs.len());
@@ -1645,7 +1645,7 @@ impl BlockMinerThread {
16451645
continue;
16461646
}
16471647
if prev_block.parent_consensus_hash == *parent_consensus_hash
1648-
&& prev_block.my_burn_hash == self.burn_block.burn_header_hash
1648+
&& prev_block.burn_hash == self.burn_block.burn_header_hash
16491649
&& prev_block.anchored_block.header.parent_block
16501650
== stacks_parent_header.anchored_header.block_hash()
16511651
{
@@ -1677,7 +1677,7 @@ impl BlockMinerThread {
16771677
// already have.
16781678
info!("Relayer: Stacks tip is unchanged since we last tried to mine a block off of {}/{} at height {} with {} txs, in {} at burn height {}, and no new microblocks ({} <= {} + 1)",
16791679
&prev_block.parent_consensus_hash, &prev_block.anchored_block.header.parent_block, prev_block.anchored_block.header.total_work.work,
1680-
prev_block.anchored_block.txs.len(), prev_block.my_burn_hash, parent_block_burn_height, stream.len(), prev_block.anchored_block.header.parent_microblock_sequence);
1680+
prev_block.anchored_block.txs.len(), prev_block.burn_hash, parent_block_burn_height, stream.len(), prev_block.anchored_block.header.parent_microblock_sequence);
16811681

16821682
return None;
16831683
}
@@ -1688,7 +1688,7 @@ impl BlockMinerThread {
16881688
// fee minus the old BTC fee
16891689
info!("Relayer: Stacks tip is unchanged since we last tried to mine a block off of {}/{} at height {} with {} txs, in {} at burn height {}, but there are new microblocks ({} > {} + 1)",
16901690
&prev_block.parent_consensus_hash, &prev_block.anchored_block.header.parent_block, prev_block.anchored_block.header.total_work.work,
1691-
prev_block.anchored_block.txs.len(), prev_block.my_burn_hash, parent_block_burn_height, stream.len(), prev_block.anchored_block.header.parent_microblock_sequence);
1691+
prev_block.anchored_block.txs.len(), prev_block.burn_hash, parent_block_burn_height, stream.len(), prev_block.anchored_block.header.parent_microblock_sequence);
16921692

16931693
best_attempt = cmp::max(best_attempt, prev_block.attempt);
16941694
}
@@ -1697,20 +1697,20 @@ impl BlockMinerThread {
16971697
// no microblock stream to confirm, and the stacks tip hasn't changed
16981698
info!("Relayer: Stacks tip is unchanged since we last tried to mine a block off of {}/{} at height {} with {} txs, in {} at burn height {}, and no microblocks present",
16991699
&prev_block.parent_consensus_hash, &prev_block.anchored_block.header.parent_block, prev_block.anchored_block.header.total_work.work,
1700-
prev_block.anchored_block.txs.len(), prev_block.my_burn_hash, parent_block_burn_height);
1700+
prev_block.anchored_block.txs.len(), prev_block.burn_hash, parent_block_burn_height);
17011701

17021702
return None;
17031703
}
17041704
}
17051705
} else {
1706-
if self.burn_block.burn_header_hash == prev_block.my_burn_hash {
1706+
if self.burn_block.burn_header_hash == prev_block.burn_hash {
17071707
// only try and re-mine if there was no sortition since the last chain tip
17081708
info!("Relayer: Stacks tip has changed to {}/{} since we last tried to mine a block in {} at burn height {}; attempt was {} (for Stacks tip {}/{})",
1709-
parent_consensus_hash, stacks_parent_header.anchored_header.block_hash(), prev_block.my_burn_hash, parent_block_burn_height, prev_block.attempt, &prev_block.parent_consensus_hash, &prev_block.anchored_block.header.parent_block);
1709+
parent_consensus_hash, stacks_parent_header.anchored_header.block_hash(), prev_block.burn_hash, parent_block_burn_height, prev_block.attempt, &prev_block.parent_consensus_hash, &prev_block.anchored_block.header.parent_block);
17101710
best_attempt = cmp::max(best_attempt, prev_block.attempt);
17111711
} else {
17121712
info!("Relayer: Burn tip has changed to {} ({}) since we last tried to mine a block in {}",
1713-
&self.burn_block.burn_header_hash, self.burn_block.block_height, &prev_block.my_burn_hash);
1713+
&self.burn_block.burn_header_hash, self.burn_block.block_height, &prev_block.burn_hash);
17141714
}
17151715
}
17161716
}
@@ -2554,34 +2554,48 @@ impl BlockMinerThread {
25542554
} = self.config.get_node_config(false);
25552555

25562556
let res = bitcoin_controller.submit_operation(target_epoch_id, op, &mut op_signer, attempt);
2557+
if res.is_none() {
2558+
self.failed_to_submit_last_attempt = true;
2559+
if !mock_mining {
2560+
warn!("Relayer: Failed to submit Bitcoin transaction");
2561+
return None;
2562+
}
2563+
debug!("Relayer: Mock-mining enabled; not sending Bitcoin transaction");
2564+
} else {
2565+
self.failed_to_submit_last_attempt = false;
2566+
}
2567+
25572568
let assembled_block = AssembledAnchorBlock {
25582569
parent_consensus_hash: parent_block_info.parent_consensus_hash,
25592570
consensus_hash: cur_burn_chain_tip.consensus_hash,
2560-
my_burn_hash: cur_burn_chain_tip.burn_header_hash,
2561-
my_block_height: cur_burn_chain_tip.block_height,
2571+
burn_hash: cur_burn_chain_tip.burn_header_hash,
2572+
burn_block_height: cur_burn_chain_tip.block_height,
25622573
orig_burn_hash: self.burn_block.burn_header_hash,
25632574
anchored_block,
25642575
attempt,
25652576
tenure_begin,
25662577
};
2567-
if res.is_none() {
2568-
self.failed_to_submit_last_attempt = true;
2569-
if mock_mining {
2570-
debug!("Relayer: Mock-mining enabled; not sending Bitcoin transaction");
2571-
if let Some(dir) = mock_mining_output_dir {
2572-
let stacks_block_height = assembled_block.anchored_block.header.total_work.work;
2573-
let filename = format!("{stacks_block_height}.json");
2574-
let filepath = dir.join(filename);
2575-
assembled_block
2576-
.serialize_to_file(&filepath)
2577-
.unwrap_or_else(|e| panic!("Failed to write to file '{filepath:?}': {e}"));
2578-
}
2579-
} else {
2580-
warn!("Relayer: Failed to submit Bitcoin transaction");
2581-
return None;
2578+
2579+
if mock_mining {
2580+
let stacks_block_height = assembled_block.anchored_block.header.total_work.work;
2581+
info!("Mock mined Stacks block {stacks_block_height}");
2582+
if let Some(dir) = mock_mining_output_dir {
2583+
info!("Writing mock mined Stacks block {stacks_block_height} to file");
2584+
fs::create_dir_all(&dir).unwrap_or_else(|e| match e.kind() {
2585+
ErrorKind::AlreadyExists => { /* This is fine */ }
2586+
_ => error!("Failed to create directory '{dir:?}': {e}"),
2587+
});
2588+
let filename = format!("{stacks_block_height}.json");
2589+
let filepath = dir.join(filename);
2590+
assembled_block
2591+
.serialize_to_file(&filepath)
2592+
.unwrap_or_else(|e| match e.kind() {
2593+
ErrorKind::AlreadyExists => {
2594+
error!("Failed to overwrite file '{filepath:?}'")
2595+
}
2596+
_ => error!("Failed to write to file '{filepath:?}': {e}"),
2597+
});
25822598
}
2583-
} else {
2584-
self.failed_to_submit_last_attempt = false;
25852599
}
25862600

25872601
Some(MinerThreadResult::Block(
@@ -3010,7 +3024,7 @@ impl RelayerThread {
30103024
let AssembledAnchorBlock {
30113025
parent_consensus_hash,
30123026
anchored_block: mined_block,
3013-
my_burn_hash: mined_burn_hash,
3027+
burn_hash: mined_burn_hash,
30143028
attempt: _,
30153029
..
30163030
} = last_mined_block_data;
@@ -3423,16 +3437,16 @@ impl RelayerThread {
34233437
fn clear_stale_mined_blocks(burn_height: u64, last_mined_blocks: MinedBlocks) -> MinedBlocks {
34243438
let mut ret = HashMap::new();
34253439
for (stacks_bhh, (assembled_block, microblock_privkey)) in last_mined_blocks.into_iter() {
3426-
if assembled_block.my_block_height < burn_height {
3440+
if assembled_block.burn_block_height < burn_height {
34273441
debug!(
34283442
"Stale mined block: {} (as of {},{})",
3429-
&stacks_bhh, &assembled_block.my_burn_hash, assembled_block.my_block_height
3443+
&stacks_bhh, &assembled_block.burn_hash, assembled_block.burn_block_height
34303444
);
34313445
continue;
34323446
}
34333447
debug!(
34343448
"Mined block in-flight: {} (as of {},{})",
3435-
&stacks_bhh, &assembled_block.my_burn_hash, assembled_block.my_block_height
3449+
&stacks_bhh, &assembled_block.burn_hash, assembled_block.burn_block_height
34363450
);
34373451
ret.insert(stacks_bhh, (assembled_block, microblock_privkey));
34383452
}
@@ -3760,7 +3774,7 @@ impl RelayerThread {
37603774
) => {
37613775
// finished mining a block
37623776
if BlockMinerThread::find_inflight_mined_blocks(
3763-
last_mined_block.my_block_height,
3777+
last_mined_block.burn_block_height,
37643778
&self.last_mined_blocks,
37653779
)
37663780
.len()
@@ -3769,7 +3783,7 @@ impl RelayerThread {
37693783
// first time we've mined a block in this burnchain block
37703784
debug!(
37713785
"Bump block processed for burnchain block {}",
3772-
&last_mined_block.my_block_height
3786+
&last_mined_block.burn_block_height
37733787
);
37743788
self.globals.counters.bump_blocks_processed();
37753789
}
@@ -3779,7 +3793,7 @@ impl RelayerThread {
37793793
&last_mined_block.anchored_block.block_hash()
37803794
);
37813795

3782-
let bhh = last_mined_block.my_burn_hash.clone();
3796+
let bhh = last_mined_block.burn_hash.clone();
37833797
let orig_bhh = last_mined_block.orig_burn_hash.clone();
37843798
let tenure_begin = last_mined_block.tenure_begin;
37853799

0 commit comments

Comments
 (0)