Skip to content

Commit 4c652ad

Browse files
authored
Merge pull request #6583 from jferrant/bug/fix-consensus-test-canonical-tip
Bug/fix consensus test canonical tip
2 parents ece4dac + e7340e8 commit 4c652ad

5 files changed

+261
-282
lines changed

stackslib/src/chainstate/nakamoto/tests/node.rs

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1060,6 +1060,105 @@ impl TestStacksNode {
10601060
let cost = builder.tenure_finish(tenure_tx).unwrap();
10611061
Ok((block, size, cost))
10621062
}
1063+
1064+
/// Insert a staging Nakamoto block as a pushed block and
1065+
/// then process it as the next ready block
1066+
/// NOTE: Will panic if called with unprocessed staging
1067+
/// blocks already in the queue.
1068+
pub fn process_pushed_next_ready_block<'a>(
1069+
stacks_node: &mut TestStacksNode,
1070+
sortdb: &mut SortitionDB,
1071+
miner: &mut TestMiner,
1072+
tenure_id_consensus_hash: &ConsensusHash,
1073+
coord: &mut ChainsCoordinator<
1074+
'a,
1075+
TestEventObserver,
1076+
(),
1077+
OnChainRewardSetProvider<'a, TestEventObserver>,
1078+
(),
1079+
(),
1080+
BitcoinIndexer,
1081+
>,
1082+
nakamoto_block: NakamotoBlock,
1083+
) -> Result<Option<StacksEpochReceipt>, ChainstateError> {
1084+
// Before processeding, make sure the caller did not accidentally construct a test with unprocessed blocks already in the queue
1085+
let nakamoto_blocks_db = stacks_node.chainstate.nakamoto_blocks_db();
1086+
assert!(nakamoto_blocks_db
1087+
.next_ready_nakamoto_block(stacks_node.chainstate.db())
1088+
.unwrap().is_none(), "process_pushed_next_ready_block can only be called if the staging blocks queue is empty");
1089+
1090+
let tenure_sn =
1091+
SortitionDB::get_block_snapshot_consensus(sortdb.conn(), tenure_id_consensus_hash)?
1092+
.ok_or_else(|| ChainstateError::NoSuchBlockError)?;
1093+
1094+
let cycle = sortdb
1095+
.pox_constants
1096+
.block_height_to_reward_cycle(sortdb.first_block_height, tenure_sn.block_height)
1097+
.unwrap();
1098+
1099+
// Get the reward set
1100+
let sort_tip_sn = SortitionDB::get_canonical_burn_chain_tip(sortdb.conn())?;
1101+
let reward_set = load_nakamoto_reward_set(
1102+
miner
1103+
.burnchain
1104+
.block_height_to_reward_cycle(sort_tip_sn.block_height)
1105+
.expect("FATAL: no reward cycle for sortition"),
1106+
&sort_tip_sn.sortition_id,
1107+
&miner.burnchain,
1108+
&mut stacks_node.chainstate,
1109+
&nakamoto_block.header.parent_block_id,
1110+
sortdb,
1111+
&OnChainRewardSetProvider::new(),
1112+
)
1113+
.expect("Failed to load reward set")
1114+
.expect("Expected a reward set")
1115+
.0
1116+
.known_selected_anchor_block_owned()
1117+
.expect("Unknown reward set");
1118+
1119+
let block_id = nakamoto_block.block_id();
1120+
1121+
debug!(
1122+
"Process Nakamoto block {block_id} ({:?}",
1123+
&nakamoto_block.header
1124+
);
1125+
1126+
let sort_tip = SortitionDB::get_canonical_sortition_tip(sortdb.conn())?;
1127+
let mut sort_handle = sortdb.index_handle(&sort_tip);
1128+
1129+
// Force the block to be added to the nakamoto_staging_blocks table
1130+
let config = stacks_node.chainstate.config();
1131+
let (headers_conn, staging_db_tx) =
1132+
stacks_node.chainstate.headers_conn_and_staging_tx_begin()?;
1133+
let accepted = NakamotoChainState::accept_block(
1134+
&config,
1135+
&nakamoto_block,
1136+
&mut sort_handle,
1137+
&staging_db_tx,
1138+
headers_conn,
1139+
&reward_set,
1140+
NakamotoBlockObtainMethod::Pushed,
1141+
)?;
1142+
staging_db_tx.commit()?;
1143+
debug!("Accepted Nakamoto block {}", &nakamoto_block.block_id());
1144+
// Actually attempt to process the accepted block added to nakamoto_staging_blocks
1145+
// Will attempt to execute the transactions via a call to append_block
1146+
let res = NakamotoChainState::process_next_nakamoto_block(
1147+
&mut coord.chain_state_db,
1148+
&mut coord.sortition_db,
1149+
&coord.canonical_sortition_tip.clone().expect(
1150+
"FAIL: processing a new Stacks block, but don't have a canonical sortition tip",
1151+
),
1152+
coord.dispatcher,
1153+
coord.config.txindex,
1154+
)?;
1155+
if res.is_some() {
1156+
// If we successfully processed the block, make sure we append the block to our current tenure
1157+
// so subsequent blocks do not attempt to reorg it.
1158+
stacks_node.add_nakamoto_extended_blocks(vec![nakamoto_block]);
1159+
}
1160+
Ok(res)
1161+
}
10631162
}
10641163

10651164
/// Get the Nakamoto parent linkage data for building atop the last-produced tenure or

0 commit comments

Comments
 (0)