Skip to content

Commit

Permalink
Merge pull request #5528 from stacks-network/release/3.0.0.0.4
Browse files Browse the repository at this point in the history
merge Release/3.0.0.0.4 to master
  • Loading branch information
wileyj authored Dec 4, 2024
2 parents 160b495 + 5f54e64 commit 230a946
Show file tree
Hide file tree
Showing 8 changed files with 119 additions and 81 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,13 @@ and this project adheres to the versioning scheme outlined in the [README.md](RE

### Changed

## [3.0.0.0.4]

### Added

### Changed

- Use the same burn view loader in both block validation and block processing

## [3.0.0.0.3]

Expand Down
8 changes: 8 additions & 0 deletions stacks-signer/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,14 @@ and this project adheres to the versioning scheme outlined in the [README.md](RE

### Changed

## [3.0.0.0.4.0]

### Added

### Changed

- Use the same burn view loader in both block validation and block processing

## [3.0.0.0.3.0]

### Added
Expand Down
10 changes: 0 additions & 10 deletions stacks-signer/src/signerdb.rs
Original file line number Diff line number Diff line change
Expand Up @@ -871,16 +871,6 @@ where
.map_err(DBError::SerializationError)
}

#[cfg(test)]
pub fn test_signer_db(db_path: &str) -> SignerDb {
use std::fs;

if fs::metadata(db_path).is_ok() {
fs::remove_file(db_path).unwrap();
}
SignerDb::new(db_path).expect("Failed to create signer db")
}

#[cfg(test)]
mod tests {
use std::fs;
Expand Down
2 changes: 1 addition & 1 deletion stackslib/src/chainstate/burn/db/sortdb.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3986,7 +3986,7 @@ impl<'a> SortitionDBConn<'a> {
tip,
reward_cycle_id,
)?;
info!("Fetching preprocessed reward set";
debug!("Fetching preprocessed reward set";
"tip_sortition_id" => %tip,
"reward_cycle_id" => reward_cycle_id,
"prepare_phase_start_sortition_id" => %first_sortition,
Expand Down
125 changes: 69 additions & 56 deletions stackslib/src/chainstate/nakamoto/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1788,6 +1788,73 @@ impl NakamotoChainState {
}
}

/// Get the current burnchain view
/// This is either:
/// (1) set by the tenure change tx if one exists
/// (2) the same as parent block id
pub fn get_block_burn_view(
sort_db: &SortitionDB,
next_ready_block: &NakamotoBlock,
parent_header_info: &StacksHeaderInfo,
) -> Result<ConsensusHash, ChainstateError> {
let burnchain_view = if let Some(tenure_change) = next_ready_block.get_tenure_tx_payload() {
if let Some(ref parent_burn_view) = parent_header_info.burn_view {
// check that the tenure_change's burn view descends from the parent
let parent_burn_view_sn = SortitionDB::get_block_snapshot_consensus(
sort_db.conn(),
parent_burn_view,
)?
.ok_or_else(|| {
warn!(
"Cannot process Nakamoto block: could not find parent block's burnchain view";
"consensus_hash" => %next_ready_block.header.consensus_hash,
"stacks_block_hash" => %next_ready_block.header.block_hash(),
"stacks_block_id" => %next_ready_block.header.block_id(),
"parent_block_id" => %next_ready_block.header.parent_block_id
);
ChainstateError::InvalidStacksBlock("Failed to load burn view of parent block ID".into())
})?;
let handle = sort_db.index_handle_at_ch(&tenure_change.burn_view_consensus_hash)?;
let connected_sort_id = get_ancestor_sort_id(&handle, parent_burn_view_sn.block_height, &handle.context.chain_tip)?
.ok_or_else(|| {
warn!(
"Cannot process Nakamoto block: could not find parent block's burnchain view";
"consensus_hash" => %next_ready_block.header.consensus_hash,
"stacks_block_hash" => %next_ready_block.header.block_hash(),
"stacks_block_id" => %next_ready_block.header.block_id(),
"parent_block_id" => %next_ready_block.header.parent_block_id
);
ChainstateError::InvalidStacksBlock("Failed to load burn view of parent block ID".into())
})?;
if connected_sort_id != parent_burn_view_sn.sortition_id {
warn!(
"Cannot process Nakamoto block: parent block's burnchain view does not connect to own burn view";
"consensus_hash" => %next_ready_block.header.consensus_hash,
"stacks_block_hash" => %next_ready_block.header.block_hash(),
"stacks_block_id" => %next_ready_block.header.block_id(),
"parent_block_id" => %next_ready_block.header.parent_block_id
);
return Err(ChainstateError::InvalidStacksBlock(
"Does not connect to burn view of parent block ID".into(),
));
}
}
tenure_change.burn_view_consensus_hash
} else {
parent_header_info.burn_view.clone().ok_or_else(|| {
warn!(
"Cannot process Nakamoto block: parent block does not have a burnchain view and current block has no tenure tx";
"consensus_hash" => %next_ready_block.header.consensus_hash,
"stacks_block_hash" => %next_ready_block.header.block_hash(),
"stacks_block_id" => %next_ready_block.header.block_id(),
"parent_block_id" => %next_ready_block.header.parent_block_id
);
ChainstateError::InvalidStacksBlock("Failed to load burn view of parent block ID".into())
})?
};
Ok(burnchain_view)
}

/// Process the next ready block.
/// If there exists a ready Nakamoto block, then this method returns Ok(Some(..)) with the
/// receipt. Otherwise, it returns Ok(None).
Expand Down Expand Up @@ -1920,62 +1987,8 @@ impl NakamotoChainState {
// this is either:
// (1) set by the tenure change tx if one exists
// (2) the same as parent block id

let burnchain_view = if let Some(tenure_change) = next_ready_block.get_tenure_tx_payload() {
if let Some(ref parent_burn_view) = parent_header_info.burn_view {
// check that the tenure_change's burn view descends from the parent
let parent_burn_view_sn = SortitionDB::get_block_snapshot_consensus(
sort_db.conn(),
parent_burn_view,
)?
.ok_or_else(|| {
warn!(
"Cannot process Nakamoto block: could not find parent block's burnchain view";
"consensus_hash" => %next_ready_block.header.consensus_hash,
"stacks_block_hash" => %next_ready_block.header.block_hash(),
"stacks_block_id" => %next_ready_block.header.block_id(),
"parent_block_id" => %next_ready_block.header.parent_block_id
);
ChainstateError::InvalidStacksBlock("Failed to load burn view of parent block ID".into())
})?;
let handle = sort_db.index_handle_at_ch(&tenure_change.burn_view_consensus_hash)?;
let connected_sort_id = get_ancestor_sort_id(&handle, parent_burn_view_sn.block_height, &handle.context.chain_tip)?
.ok_or_else(|| {
warn!(
"Cannot process Nakamoto block: could not find parent block's burnchain view";
"consensus_hash" => %next_ready_block.header.consensus_hash,
"stacks_block_hash" => %next_ready_block.header.block_hash(),
"stacks_block_id" => %next_ready_block.header.block_id(),
"parent_block_id" => %next_ready_block.header.parent_block_id
);
ChainstateError::InvalidStacksBlock("Failed to load burn view of parent block ID".into())
})?;
if connected_sort_id != parent_burn_view_sn.sortition_id {
warn!(
"Cannot process Nakamoto block: parent block's burnchain view does not connect to own burn view";
"consensus_hash" => %next_ready_block.header.consensus_hash,
"stacks_block_hash" => %next_ready_block.header.block_hash(),
"stacks_block_id" => %next_ready_block.header.block_id(),
"parent_block_id" => %next_ready_block.header.parent_block_id
);
return Err(ChainstateError::InvalidStacksBlock(
"Does not connect to burn view of parent block ID".into(),
));
}
}
tenure_change.burn_view_consensus_hash
} else {
parent_header_info.burn_view.clone().ok_or_else(|| {
warn!(
"Cannot process Nakamoto block: parent block does not have a burnchain view and current block has no tenure tx";
"consensus_hash" => %next_ready_block.header.consensus_hash,
"stacks_block_hash" => %next_ready_block.header.block_hash(),
"stacks_block_id" => %next_ready_block.header.block_id(),
"parent_block_id" => %next_ready_block.header.parent_block_id
);
ChainstateError::InvalidStacksBlock("Failed to load burn view of parent block ID".into())
})?
};
let burnchain_view =
Self::get_block_burn_view(sort_db, &next_ready_block, &parent_header_info)?;
let Some(burnchain_view_sn) =
SortitionDB::get_block_snapshot_consensus(sort_db.conn(), &burnchain_view)?
else {
Expand Down
35 changes: 24 additions & 11 deletions stackslib/src/net/api/postblock_proposal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -374,9 +374,30 @@ impl NakamotoBlockProposal {
});
}

let sort_tip = SortitionDB::get_canonical_sortition_tip(sortdb.conn())?;
let burn_dbconn: SortitionHandleConn = sortdb.index_handle(&sort_tip);
let mut db_handle = sortdb.index_handle(&sort_tip);
// open sortition view to the current burn view.
// If the block has a TenureChange with an Extend cause, then the burn view is whatever is
// indicated in the TenureChange.
// Otherwise, it's the same as the block's parent's burn view.
let parent_stacks_header = NakamotoChainState::get_block_header(
chainstate.db(),
&self.block.header.parent_block_id,
)?
.ok_or_else(|| BlockValidateRejectReason {
reason_code: ValidateRejectCode::InvalidBlock,
reason: "Invalid parent block".into(),
})?;

let burn_view_consensus_hash =
NakamotoChainState::get_block_burn_view(sortdb, &self.block, &parent_stacks_header)?;
let sort_tip =
SortitionDB::get_block_snapshot_consensus(sortdb.conn(), &burn_view_consensus_hash)?
.ok_or_else(|| BlockValidateRejectReason {
reason_code: ValidateRejectCode::NoSuchTenure,
reason: "Failed to find sortition for block tenure".to_string(),
})?;

let burn_dbconn: SortitionHandleConn = sortdb.index_handle(&sort_tip.sortition_id);
let mut db_handle = sortdb.index_handle(&sort_tip.sortition_id);

// (For the signer)
// Verify that the block's tenure is on the canonical sortition history
Expand Down Expand Up @@ -413,14 +434,6 @@ impl NakamotoBlockProposal {
)?;

// Validate txs against chainstate
let parent_stacks_header = NakamotoChainState::get_block_header(
chainstate.db(),
&self.block.header.parent_block_id,
)?
.ok_or_else(|| BlockValidateRejectReason {
reason_code: ValidateRejectCode::InvalidBlock,
reason: "Invalid parent block".into(),
})?;

// Validate the block's timestamp. It must be:
// - Greater than the parent block's timestamp
Expand Down
6 changes: 5 additions & 1 deletion testnet/stacks-node/src/nakamoto_node/miner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,11 @@ pub struct BlockMinerThread {
registered_key: RegisteredKey,
/// Burnchain block snapshot which elected this miner
burn_election_block: BlockSnapshot,
/// Current burnchain tip
/// Current burnchain tip as of the last TenureChange
/// * if the last tenure-change was a BlockFound, then this is the same as the
/// `burn_election_block`.
/// * otherwise, if the last tenure-change is an Extend, then this is the sortition of the burn
/// view consensus hash in the TenureChange
burn_block: BlockSnapshot,
/// The start of the parent tenure for this tenure
parent_tenure_id: StacksBlockId,
Expand Down
7 changes: 5 additions & 2 deletions testnet/stacks-node/src/tests/signer/v0.rs
Original file line number Diff line number Diff line change
Expand Up @@ -506,7 +506,7 @@ fn block_proposal_rejection() {
signer_test.wait_for_validate_reject_response(short_timeout, block_signer_signature_hash_2);
assert!(matches!(
reject.reason_code,
ValidateRejectCode::UnknownParent
ValidateRejectCode::InvalidBlock
));

let start_polling = Instant::now();
Expand All @@ -532,7 +532,10 @@ fn block_proposal_rejection() {
assert!(matches!(reason_code, RejectCode::SortitionViewMismatch));
} else if signer_signature_hash == block_signer_signature_hash_2 {
found_signer_signature_hash_2 = true;
assert!(matches!(reason_code, RejectCode::ValidationFailed(_)));
assert!(matches!(
reason_code,
RejectCode::ValidationFailed(ValidateRejectCode::InvalidBlock)
));
} else {
continue;
}
Expand Down

0 comments on commit 230a946

Please sign in to comment.