Skip to content

Commit f56bfc7

Browse files
committed
chore: use the same burn view loader in both block validation and block processing
1 parent 40d3563 commit f56bfc7

File tree

2 files changed

+87
-69
lines changed

2 files changed

+87
-69
lines changed

stackslib/src/chainstate/nakamoto/mod.rs

Lines changed: 69 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -1763,6 +1763,73 @@ impl NakamotoChainState {
17631763
}
17641764
}
17651765

1766+
/// Get the current burnchain view
1767+
/// This is either:
1768+
/// (1) set by the tenure change tx if one exists
1769+
/// (2) the same as parent block id
1770+
pub fn get_block_burn_view(
1771+
sort_db: &SortitionDB,
1772+
next_ready_block: &NakamotoBlock,
1773+
parent_header_info: &StacksHeaderInfo,
1774+
) -> Result<ConsensusHash, ChainstateError> {
1775+
let burnchain_view = if let Some(tenure_change) = next_ready_block.get_tenure_tx_payload() {
1776+
if let Some(ref parent_burn_view) = parent_header_info.burn_view {
1777+
// check that the tenure_change's burn view descends from the parent
1778+
let parent_burn_view_sn = SortitionDB::get_block_snapshot_consensus(
1779+
sort_db.conn(),
1780+
parent_burn_view,
1781+
)?
1782+
.ok_or_else(|| {
1783+
warn!(
1784+
"Cannot process Nakamoto block: could not find parent block's burnchain view";
1785+
"consensus_hash" => %next_ready_block.header.consensus_hash,
1786+
"stacks_block_hash" => %next_ready_block.header.block_hash(),
1787+
"stacks_block_id" => %next_ready_block.header.block_id(),
1788+
"parent_block_id" => %next_ready_block.header.parent_block_id
1789+
);
1790+
ChainstateError::InvalidStacksBlock("Failed to load burn view of parent block ID".into())
1791+
})?;
1792+
let handle = sort_db.index_handle_at_ch(&tenure_change.burn_view_consensus_hash)?;
1793+
let connected_sort_id = get_ancestor_sort_id(&handle, parent_burn_view_sn.block_height, &handle.context.chain_tip)?
1794+
.ok_or_else(|| {
1795+
warn!(
1796+
"Cannot process Nakamoto block: could not find parent block's burnchain view";
1797+
"consensus_hash" => %next_ready_block.header.consensus_hash,
1798+
"stacks_block_hash" => %next_ready_block.header.block_hash(),
1799+
"stacks_block_id" => %next_ready_block.header.block_id(),
1800+
"parent_block_id" => %next_ready_block.header.parent_block_id
1801+
);
1802+
ChainstateError::InvalidStacksBlock("Failed to load burn view of parent block ID".into())
1803+
})?;
1804+
if connected_sort_id != parent_burn_view_sn.sortition_id {
1805+
warn!(
1806+
"Cannot process Nakamoto block: parent block's burnchain view does not connect to own burn view";
1807+
"consensus_hash" => %next_ready_block.header.consensus_hash,
1808+
"stacks_block_hash" => %next_ready_block.header.block_hash(),
1809+
"stacks_block_id" => %next_ready_block.header.block_id(),
1810+
"parent_block_id" => %next_ready_block.header.parent_block_id
1811+
);
1812+
return Err(ChainstateError::InvalidStacksBlock(
1813+
"Does not connect to burn view of parent block ID".into(),
1814+
));
1815+
}
1816+
}
1817+
tenure_change.burn_view_consensus_hash
1818+
} else {
1819+
parent_header_info.burn_view.clone().ok_or_else(|| {
1820+
warn!(
1821+
"Cannot process Nakamoto block: parent block does not have a burnchain view and current block has no tenure tx";
1822+
"consensus_hash" => %next_ready_block.header.consensus_hash,
1823+
"stacks_block_hash" => %next_ready_block.header.block_hash(),
1824+
"stacks_block_id" => %next_ready_block.header.block_id(),
1825+
"parent_block_id" => %next_ready_block.header.parent_block_id
1826+
);
1827+
ChainstateError::InvalidStacksBlock("Failed to load burn view of parent block ID".into())
1828+
})?
1829+
};
1830+
Ok(burnchain_view)
1831+
}
1832+
17661833
/// Process the next ready block.
17671834
/// If there exists a ready Nakamoto block, then this method returns Ok(Some(..)) with the
17681835
/// receipt. Otherwise, it returns Ok(None).
@@ -1882,62 +1949,8 @@ impl NakamotoChainState {
18821949
// this is either:
18831950
// (1) set by the tenure change tx if one exists
18841951
// (2) the same as parent block id
1885-
1886-
let burnchain_view = if let Some(tenure_change) = next_ready_block.get_tenure_tx_payload() {
1887-
if let Some(ref parent_burn_view) = parent_header_info.burn_view {
1888-
// check that the tenure_change's burn view descends from the parent
1889-
let parent_burn_view_sn = SortitionDB::get_block_snapshot_consensus(
1890-
sort_db.conn(),
1891-
parent_burn_view,
1892-
)?
1893-
.ok_or_else(|| {
1894-
warn!(
1895-
"Cannot process Nakamoto block: could not find parent block's burnchain view";
1896-
"consensus_hash" => %next_ready_block.header.consensus_hash,
1897-
"stacks_block_hash" => %next_ready_block.header.block_hash(),
1898-
"stacks_block_id" => %next_ready_block.header.block_id(),
1899-
"parent_block_id" => %next_ready_block.header.parent_block_id
1900-
);
1901-
ChainstateError::InvalidStacksBlock("Failed to load burn view of parent block ID".into())
1902-
})?;
1903-
let handle = sort_db.index_handle_at_ch(&tenure_change.burn_view_consensus_hash)?;
1904-
let connected_sort_id = get_ancestor_sort_id(&handle, parent_burn_view_sn.block_height, &handle.context.chain_tip)?
1905-
.ok_or_else(|| {
1906-
warn!(
1907-
"Cannot process Nakamoto block: could not find parent block's burnchain view";
1908-
"consensus_hash" => %next_ready_block.header.consensus_hash,
1909-
"stacks_block_hash" => %next_ready_block.header.block_hash(),
1910-
"stacks_block_id" => %next_ready_block.header.block_id(),
1911-
"parent_block_id" => %next_ready_block.header.parent_block_id
1912-
);
1913-
ChainstateError::InvalidStacksBlock("Failed to load burn view of parent block ID".into())
1914-
})?;
1915-
if connected_sort_id != parent_burn_view_sn.sortition_id {
1916-
warn!(
1917-
"Cannot process Nakamoto block: parent block's burnchain view does not connect to own burn view";
1918-
"consensus_hash" => %next_ready_block.header.consensus_hash,
1919-
"stacks_block_hash" => %next_ready_block.header.block_hash(),
1920-
"stacks_block_id" => %next_ready_block.header.block_id(),
1921-
"parent_block_id" => %next_ready_block.header.parent_block_id
1922-
);
1923-
return Err(ChainstateError::InvalidStacksBlock(
1924-
"Does not connect to burn view of parent block ID".into(),
1925-
));
1926-
}
1927-
}
1928-
tenure_change.burn_view_consensus_hash
1929-
} else {
1930-
parent_header_info.burn_view.clone().ok_or_else(|| {
1931-
warn!(
1932-
"Cannot process Nakamoto block: parent block does not have a burnchain view and current block has no tenure tx";
1933-
"consensus_hash" => %next_ready_block.header.consensus_hash,
1934-
"stacks_block_hash" => %next_ready_block.header.block_hash(),
1935-
"stacks_block_id" => %next_ready_block.header.block_id(),
1936-
"parent_block_id" => %next_ready_block.header.parent_block_id
1937-
);
1938-
ChainstateError::InvalidStacksBlock("Failed to load burn view of parent block ID".into())
1939-
})?
1940-
};
1952+
let burnchain_view =
1953+
Self::get_block_burn_view(sort_db, &next_ready_block, &parent_header_info)?;
19411954
let Some(burnchain_view_sn) =
19421955
SortitionDB::get_block_snapshot_consensus(sort_db.conn(), &burnchain_view)?
19431956
else {

stackslib/src/net/api/postblock_proposal.rs

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -363,15 +363,28 @@ impl NakamotoBlockProposal {
363363
});
364364
}
365365

366-
let sort_tip = SortitionDB::get_block_snapshot_consensus(
367-
sortdb.conn(),
368-
&self.block.header.consensus_hash,
366+
// open sortition view to the current burn view.
367+
// If the block has a TenureChange with an Extend cause, then the burn view is whatever is
368+
// indicated in the TenureChange.
369+
// Otherwise, it's the same as the block's parent's burn view.
370+
let parent_stacks_header = NakamotoChainState::get_block_header(
371+
chainstate.db(),
372+
&self.block.header.parent_block_id,
369373
)?
370374
.ok_or_else(|| BlockValidateRejectReason {
371-
reason_code: ValidateRejectCode::NoSuchTenure,
372-
reason: "Failed to find sortition for block tenure".to_string(),
375+
reason_code: ValidateRejectCode::InvalidBlock,
376+
reason: "Invalid parent block".into(),
373377
})?;
374378

379+
let burn_view_consensus_hash =
380+
NakamotoChainState::get_block_burn_view(sortdb, &self.block, &parent_stacks_header)?;
381+
let sort_tip =
382+
SortitionDB::get_block_snapshot_consensus(sortdb.conn(), &burn_view_consensus_hash)?
383+
.ok_or_else(|| BlockValidateRejectReason {
384+
reason_code: ValidateRejectCode::NoSuchTenure,
385+
reason: "Failed to find sortition for block tenure".to_string(),
386+
})?;
387+
375388
let burn_dbconn: SortitionHandleConn = sortdb.index_handle(&sort_tip.sortition_id);
376389
let mut db_handle = sortdb.index_handle(&sort_tip.sortition_id);
377390

@@ -409,14 +422,6 @@ impl NakamotoBlockProposal {
409422
)?;
410423

411424
// Validate txs against chainstate
412-
let parent_stacks_header = NakamotoChainState::get_block_header(
413-
chainstate.db(),
414-
&self.block.header.parent_block_id,
415-
)?
416-
.ok_or_else(|| BlockValidateRejectReason {
417-
reason_code: ValidateRejectCode::InvalidBlock,
418-
reason: "Invalid parent block".into(),
419-
})?;
420425

421426
// Validate the block's timestamp. It must be:
422427
// - Greater than the parent block's timestamp

0 commit comments

Comments
 (0)