Skip to content

Commit 514c0d0

Browse files
committed
Fix VRF proof calculation and update test to be more expansive
Signed-off-by: Jacinta Ferrant <[email protected]>
1 parent b9438fa commit 514c0d0

File tree

3 files changed

+257
-87
lines changed

3 files changed

+257
-87
lines changed

testnet/stacks-node/src/nakamoto_node/miner.rs

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,8 @@ pub enum MinerReason {
109109
/// sortition.
110110
burn_view_consensus_hash: ConsensusHash,
111111
},
112+
/// The miner thread was spawned to initialize a prior empty tenure
113+
EmptyTenure,
112114
}
113115

114116
impl std::fmt::Display for MinerReason {
@@ -121,6 +123,7 @@ impl std::fmt::Display for MinerReason {
121123
f,
122124
"Extended: burn_view_consensus_hash = {burn_view_consensus_hash:?}",
123125
),
126+
MinerReason::EmptyTenure => write!(f, "EmptyTenure"),
124127
}
125128
}
126129
}
@@ -919,22 +922,25 @@ impl BlockMinerThread {
919922
fn make_vrf_proof(&mut self) -> Option<VRFProof> {
920923
// if we're a mock miner, then make sure that the keychain has a keypair for the mocked VRF
921924
// key
925+
let sortition_hash = if matches!(self.reason, MinerReason::EmptyTenure) {
926+
self.burn_election_block.sortition_hash
927+
} else {
928+
self.burn_block.sortition_hash
929+
};
922930
let vrf_proof = if self.config.get_node_config(false).mock_mining {
923-
self.keychain.generate_proof(
924-
VRF_MOCK_MINER_KEY,
925-
self.burn_block.sortition_hash.as_bytes(),
926-
)
931+
self.keychain
932+
.generate_proof(VRF_MOCK_MINER_KEY, sortition_hash.as_bytes())
927933
} else {
928934
self.keychain.generate_proof(
929935
self.registered_key.target_block_height,
930-
self.burn_block.sortition_hash.as_bytes(),
936+
sortition_hash.as_bytes(),
931937
)
932938
};
933939

934940
debug!(
935941
"Generated VRF Proof: {} over {} ({},{}) with key {}",
936942
vrf_proof.to_hex(),
937-
&self.burn_block.sortition_hash,
943+
&sortition_hash,
938944
&self.burn_block.block_height,
939945
&self.burn_block.burn_header_hash,
940946
&self.registered_key.vrf_public_key.to_hex()
@@ -1155,7 +1161,7 @@ impl BlockMinerThread {
11551161
};
11561162

11571163
let (tenure_change_tx, coinbase_tx) = match &self.reason {
1158-
MinerReason::BlockFound => {
1164+
MinerReason::BlockFound | MinerReason::EmptyTenure => {
11591165
let tenure_change_tx =
11601166
self.generate_tenure_change_tx(current_miner_nonce, payload)?;
11611167
let coinbase_tx =

testnet/stacks-node/src/nakamoto_node/relayer.rs

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -901,6 +901,7 @@ impl RelayerThread {
901901
"Relayer: Current burn block had no sortition. Checking for tenure continuation.";
902902
"won_last_sortition" => won_last_sortition,
903903
"current_mining_pkh" => %mining_pkh,
904+
"block_election_snapshot.consensus_hash" => %block_election_snapshot.consensus_hash,
904905
"block_election_snapshot.miner_pk_hash" => ?block_election_snapshot.miner_pk_hash,
905906
"canonical_stacks_tip_id" => %canonical_stacks_tip,
906907
"canonical_stacks_tip_ch" => %canonical_stacks_tip_ch,
@@ -911,13 +912,45 @@ impl RelayerThread {
911912
return Ok(());
912913
}
913914

915+
let tip_info =
916+
NakamotoChainState::get_canonical_block_header(self.chainstate.db(), &self.sortdb)
917+
.map_err(|e| {
918+
error!("Relayer: failed to get canonical block header: {e:?}");
919+
NakamotoNodeError::SnapshotNotFoundForChainTip
920+
})?
921+
.ok_or_else(|| {
922+
error!("Relayer: failed to get canonical block header");
923+
NakamotoNodeError::SnapshotNotFoundForChainTip
924+
})?;
925+
926+
let last_non_empty_sortition_snapshot =
927+
SortitionDB::get_block_snapshot_consensus(self.sortdb.conn(), &tip_info.consensus_hash)
928+
.map_err(|e| {
929+
error!("Relayer: failed to get last non-empty sortition snapshot: {e:?}");
930+
NakamotoNodeError::SnapshotNotFoundForChainTip
931+
})?
932+
.ok_or_else(|| {
933+
error!("Relayer: failed to get last non-empty sortition snapshot");
934+
NakamotoNodeError::SnapshotNotFoundForChainTip
935+
})?;
936+
937+
let won_last_non_empty_sortition_snapshot =
938+
last_non_empty_sortition_snapshot.miner_pk_hash == Some(mining_pkh);
939+
940+
let reason = if !won_last_non_empty_sortition_snapshot {
941+
debug!("Relayer: Failed to issue a tenure change payload in our last tenure. Issue a tenure change payload again.");
942+
MinerReason::EmptyTenure
943+
} else {
944+
debug!("Relayer: Successfully issued a tenure change payload in our last tenure. Issue a continue extend.");
945+
MinerReason::Extended {
946+
burn_view_consensus_hash: new_burn_view,
947+
}
948+
};
914949
match self.start_new_tenure(
915950
canonical_stacks_tip, // For tenure extend, we should be extending off the canonical tip
916951
block_election_snapshot,
917952
burn_tip,
918-
MinerReason::Extended {
919-
burn_view_consensus_hash: new_burn_view,
920-
},
953+
reason,
921954
) {
922955
Ok(()) => {
923956
debug!("Relayer: successfully started new tenure.");

0 commit comments

Comments
 (0)