Skip to content

Commit

Permalink
fix: test + patch
Browse files Browse the repository at this point in the history
  • Loading branch information
lgalabru committed Jul 20, 2021
1 parent 3dd875b commit 06d13f8
Show file tree
Hide file tree
Showing 2 changed files with 92 additions and 14 deletions.
36 changes: 23 additions & 13 deletions src/burnchains/burnchain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ use std::sync::{
Arc,
};
use std::thread;
use std::time::Instant;
use std::time::{Instant, Duration};

use crate::types::chainstate::StacksAddress;
use crate::types::proof::TrieHash;
Expand Down Expand Up @@ -1171,24 +1171,33 @@ impl Burnchain {

// handle reorgs
let (sync_height, did_reorg) = Burnchain::sync_reorg(indexer)?;
let end_height = if did_reorg {
if did_reorg {
// a reorg happened
warn!(
"Dropping headers higher than {} due to burnchain reorg",
sync_height
);
indexer.drop_headers(sync_height)?;
// Patch issue #2771
target_block_height_opt
} else {
None
};
}

// get latest headers.
debug!("Sync headers from {}", sync_height);

// fetch all headers, no matter what
let mut end_block = indexer.sync_headers(sync_height, end_height)?;
let mut end_block = indexer.sync_headers(sync_height, None)?;
if did_reorg {
// a reorg happened, and the last header fetched
// is on a smaller fork than the one we just
// invalidated. Wait for more blocks.
while end_block < db_height {
let end_height = target_block_height_opt
.unwrap_or(0)
.max(db_height);
info!("Burnchain reorg happened at height {} invalidating chain tip {} but only {} headers presents on canonical chain. Retry in 1s", sync_height, db_height, end_block);
thread::sleep(Duration::from_millis(1000));
end_block = indexer.sync_headers(sync_height, Some(end_height))?;
}
}

let mut start_block = sync_height;
if db_height < start_block {
Expand Down Expand Up @@ -1331,19 +1340,20 @@ impl Burnchain {
while let Ok(Some(burnchain_block)) = db_recv.recv() {
debug!("Try recv next parsed block");

if burnchain_block.block_height() == 0 {
let block_height = burnchain_block.block_height();
if block_height == 0 {
continue;
}

if is_mainnet {
if last_processed.block_height == STACKS_2_0_LAST_BLOCK_TO_PROCESS {
if block_height == STACKS_2_0_LAST_BLOCK_TO_PROCESS {
info!("Reached Stacks 2.0 last block to processed, ignoring subsequent burn blocks";
"block_height" => last_processed.block_height);
"block_height" => block_height);
continue;
} else if last_processed.block_height > STACKS_2_0_LAST_BLOCK_TO_PROCESS {
} else if block_height > STACKS_2_0_LAST_BLOCK_TO_PROCESS {
debug!("Reached Stacks 2.0 last block to processed, ignoring subsequent burn blocks";
"last_block" => STACKS_2_0_LAST_BLOCK_TO_PROCESS,
"block_height" => last_processed.block_height);
"block_height" => block_height);
continue;
}
}
Expand Down
70 changes: 69 additions & 1 deletion testnet/stacks-node/src/tests/neon_integrations.rs
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,7 @@ mod test_observer {
}
}

const PANIC_TIMEOUT_SECS: u64 = 600;
const PANIC_TIMEOUT_SECS: u64 = 30;
fn next_block_and_wait(
btc_controller: &mut BitcoinRegtestController,
blocks_processed: &Arc<AtomicU64>,
Expand Down Expand Up @@ -1310,6 +1310,74 @@ fn bitcoind_forking_test() {
channel.stop_chains_coordinator();
}

#[test]
#[ignore]
fn should_fix_2771() {
if env::var("BITCOIND_TEST") != Ok("1".into()) {
return;
}

let (conf, miner_account) = neon_integration_test_conf();

let mut btcd_controller = BitcoinCoreController::new(conf.clone());
btcd_controller
.start_bitcoind()
.map_err(|_e| ())
.expect("Failed starting bitcoind");

let mut btc_regtest_controller = BitcoinRegtestController::new(conf.clone(), None);
let http_origin = format!("http://{}", &conf.node.rpc_bind);

btc_regtest_controller.bootstrap_chain(201);

eprintln!("Chain bootstrapped...");

let mut run_loop = neon::RunLoop::new(conf);
let blocks_processed = run_loop.get_blocks_processed_arc();

let channel = run_loop.get_coordinator_channel().unwrap();

thread::spawn(move || run_loop.start(None, 0));

// give the run loop some time to start up!
wait_for_runloop(&blocks_processed);

// first block wakes up the run loop
next_block_and_wait(&mut btc_regtest_controller, &blocks_processed);

// first block will hold our VRF registration
next_block_and_wait(&mut btc_regtest_controller, &blocks_processed);

let mut sort_height = channel.get_sortitions_processed();
eprintln!("Sort height: {}", sort_height);

while sort_height < 210 {
next_block_and_wait(&mut btc_regtest_controller, &blocks_processed);
sort_height = channel.get_sortitions_processed();
eprintln!("Sort height: {}", sort_height);
}
// let's query the miner's account nonce:

eprintln!("Miner account: {}", miner_account);

// okay, let's figure out the burn block we want to fork away.
warn!("Will trigger re-org at block {}", 208);
let burn_header_hash_to_fork = btc_regtest_controller.get_block_hash(208);
btc_regtest_controller.invalidate_block(&burn_header_hash_to_fork);
btc_regtest_controller.build_next_block(1);
thread::sleep(Duration::from_secs(5));

// We invalidated a fork 210 long, and the new one is 207 blocks long.
// Let's dispatch the blocks one by one, instead of mining 210-207 blocks
while sort_height < 213 {
next_block_and_wait(&mut btc_regtest_controller, &blocks_processed);
sort_height = channel.get_sortitions_processed();
eprintln!("Sort height: {}", sort_height);
}

channel.stop_chains_coordinator();
}

/// Returns a StacksMicroblock with the given transactions, sequence, and parent block that is
/// signed with the given private key.
fn make_signed_microblock(
Expand Down

0 comments on commit 06d13f8

Please sign in to comment.