Skip to content

Commit

Permalink
WIP: no idea what I am doing
Browse files Browse the repository at this point in the history
Signed-off-by: Jacinta Ferrant <jacinta@trustmachines.co>
  • Loading branch information
jferrant committed Jun 4, 2024
1 parent a84819a commit 73eacae
Show file tree
Hide file tree
Showing 4 changed files with 122 additions and 125 deletions.
2 changes: 1 addition & 1 deletion stackslib/src/chainstate/nakamoto/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -732,7 +732,7 @@ impl NakamotoBlock {
// discontinuous
warn!(
"Invalid block -- discontiguous";
"previosu_tenure_end" => %tc_payload.previous_tenure_end,
"previous_tenure_end" => %tc_payload.previous_tenure_end,
"parent_block_id" => %self.header.parent_block_id
);
return Err(());
Expand Down
115 changes: 50 additions & 65 deletions testnet/stacks-node/src/nakamoto_node/miner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ use stacks::net::stackerdb::StackerDBs;
use stacks_common::codec::read_next;
use stacks_common::types::chainstate::{StacksAddress, StacksBlockId};
use stacks_common::types::{PrivateKey, StacksEpochId};
use stacks_common::util::hash::Hash160;
use stacks_common::util::vrf::VRFProof;
use wsts::curve::point::Point;
use wsts::curve::scalar::Scalar;
Expand Down Expand Up @@ -68,18 +67,21 @@ pub enum MinerDirective {
burnchain_tip: BlockSnapshot,
},
/// The miner should try to continue their tenure if they are the active miner
ContinueTenure { new_burn_view: ConsensusHash },
ContinueTenure {
parent_tenure_start: StacksBlockId,
new_burn_view: ConsensusHash,
},
/// The miner did not win sortition
StopTenure,
}

#[derive(PartialEq, Debug, Clone)]
/// Tenure info needed to construct a tenure change or tenure extend transaction
pub struct ParentTenureInfo {
struct ParentTenureInfo {
/// The number of blocks in the parent tenure
pub parent_tenure_blocks: u64,
parent_tenure_blocks: u64,
/// The consensus hash of the parent tenure
pub parent_tenure_consensus_hash: ConsensusHash,
parent_tenure_consensus_hash: ConsensusHash,
}

/// Metadata required for beginning a new tenure
Expand All @@ -98,8 +100,9 @@ pub enum MinerReason {
BlockFound,
/// The miner thread was spawned to extend an existing tenure
Extended {
/// The parent tenure info to extend
parent_tenure_info: ParentTenureInfo,
/// Current consensus hash on the underlying burnchain. Corresponds to the last-seen
/// sortition.
burn_view_consensus_hash: ConsensusHash,
/// Wether the tenure change transaction was mined
tenure_change_mined: bool,
},
Expand All @@ -109,9 +112,9 @@ impl std::fmt::Display for MinerReason {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
MinerReason::BlockFound => write!(f, "BlockFound"),
MinerReason::Extended { parent_tenure_info, tenure_change_mined } => write!(
MinerReason::Extended { burn_view_consensus_hash, tenure_change_mined } => write!(
f,
"Extended: tenure_info = {parent_tenure_info:?}, tenure_change_mined = {tenure_change_mined:?}",
"Extended: burn_view_consensus_hash = {burn_view_consensus_hash:?}, tenure_change_mined = {tenure_change_mined}",
),
}
}
Expand Down Expand Up @@ -248,7 +251,10 @@ impl BlockMinerThread {
} = &mut self.reason
{
// We should not issue multiple tenure change transactions for the same tenure
*tenure_change_mined = true;
if !*tenure_change_mined {
debug!("Miner: Tenure change mined");
*tenure_change_mined = true;
}
}
}

Expand Down Expand Up @@ -545,24 +551,11 @@ impl BlockMinerThread {
fn generate_tenure_change_tx(
&self,
nonce: u64,
parent_block_id: StacksBlockId,
parent_tenure_consensus_hash: ConsensusHash,
parent_tenure_blocks: u64,
miner_pkh: Hash160,
cause: TenureChangeCause,
payload: TenureChangePayload,
) -> Result<StacksTransaction, NakamotoNodeError> {
let is_mainnet = self.config.is_mainnet();
let chain_id = self.config.burnchain.chain_id;
let tenure_change_tx_payload = TransactionPayload::TenureChange(TenureChangePayload {
tenure_consensus_hash: self.burn_block.consensus_hash.clone(),
prev_tenure_consensus_hash: parent_tenure_consensus_hash,
burn_view_consensus_hash: self.burn_block.consensus_hash.clone(),
previous_tenure_end: parent_block_id,
previous_tenure_blocks: u32::try_from(parent_tenure_blocks)
.expect("FATAL: more than u32 blocks in a tenure"),
cause,
pubkey_hash: miner_pkh,
});
let tenure_change_tx_payload = TransactionPayload::TenureChange(payload);

let mut tx_auth = self.keychain.get_transaction_auth().unwrap();
tx_auth.set_origin_nonce(nonce);
Expand Down Expand Up @@ -847,53 +840,45 @@ impl BlockMinerThread {
vrf_proof: VRFProof,
target_epoch_id: StacksEpochId,
) -> Result<NakamotoTenureInfo, NakamotoNodeError> {
debug!("MAKING TENURE START INFO");
let parent_block_id = parent_block_info.stacks_parent_header.index_block_hash();
let current_miner_nonce = parent_block_info.coinbase_nonce;
let (coinbase_tx, tenure_change_tx) = match &self.reason {
MinerReason::BlockFound => {
// create our coinbase if this is the first block we've mined this tenure
if let Some(ref par_tenure_info) = parent_block_info.parent_tenure {
let tenure_change_tx = self.generate_tenure_change_tx(
current_miner_nonce,
parent_block_id,
par_tenure_info.parent_tenure_consensus_hash,
par_tenure_info.parent_tenure_blocks,
self.keychain.get_nakamoto_pkh(),
TenureChangeCause::BlockFound,
)?;
let coinbase_tx = self.generate_coinbase_tx(
current_miner_nonce + 1,
target_epoch_id,
vrf_proof,
);
(Some(coinbase_tx), Some(tenure_change_tx))
} else {
(None, None)
}
}
MinerReason::Extended {
parent_tenure_info,
let (tenure_change_tx, coinbase_tx) = if let Some(ref parent_tenure_info) =
parent_block_info.parent_tenure
{
debug!("Miner: Constructing tenure change and coinbase transactions");
let num_blocks_so_far = u32::try_from(parent_tenure_info.parent_tenure_blocks)
.expect("FATAL: more than u32 blocks in a tenure");
let mut payload = TenureChangePayload {
tenure_consensus_hash: self.burn_block.consensus_hash.clone(),
prev_tenure_consensus_hash: parent_tenure_info.parent_tenure_consensus_hash,
burn_view_consensus_hash: self.burn_block.consensus_hash.clone(),
previous_tenure_end: parent_block_id,
previous_tenure_blocks: num_blocks_so_far,
cause: TenureChangeCause::BlockFound,
pubkey_hash: self.keychain.get_nakamoto_pkh(),
};
if let MinerReason::Extended {
burn_view_consensus_hash,
tenure_change_mined,
} => {
if !tenure_change_mined {
let tenure_change_tx = self.generate_tenure_change_tx(
current_miner_nonce,
} = &self.reason
{
debug!("Tenure change mined {tenure_change_mined}");
if !*tenure_change_mined {
debug!("Miner: Extending tenure"; "burn_view_consensus_hash" => %burn_view_consensus_hash, "parent_block_id" => %parent_block_id, "num_blocks_so_far" => num_blocks_so_far);
payload = payload.extend(
*burn_view_consensus_hash,
parent_block_id,
parent_tenure_info.parent_tenure_consensus_hash,
parent_tenure_info.parent_tenure_blocks,
self.keychain.get_nakamoto_pkh(),
TenureChangeCause::Extended,
)?;
let coinbase_tx = self.generate_coinbase_tx(
current_miner_nonce + 1,
target_epoch_id,
vrf_proof,
num_blocks_so_far,
);
(Some(coinbase_tx), Some(tenure_change_tx))
} else {
(None, None)
}
}
let tenure_change_tx = self.generate_tenure_change_tx(current_miner_nonce, payload)?;
let coinbase_tx =
self.generate_coinbase_tx(current_miner_nonce + 1, target_epoch_id, vrf_proof);
(Some(tenure_change_tx), Some(coinbase_tx))
} else {
(None, None)
};

Ok(NakamotoTenureInfo {
Expand Down
76 changes: 27 additions & 49 deletions testnet/stacks-node/src/nakamoto_node/relayer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ use super::{
BLOCK_PROCESSOR_STACK_SIZE,
};
use crate::burnchains::BurnchainController;
use crate::nakamoto_node::miner::{BlockMinerThread, MinerDirective, ParentTenureInfo};
use crate::nakamoto_node::miner::{BlockMinerThread, MinerDirective};
use crate::neon_node::{
fault_injection_skip_mining, open_chainstate_with_faults, LeaderKeyRegistrationState,
};
Expand Down Expand Up @@ -302,7 +302,7 @@ impl RelayerThread {

/// Given the pointer to a recently processed sortition, see if we won the sortition.
///
/// Returns `true` if we won this last sortition.
/// Returns a directive to the relayer thread to either start, stop, or continue a tenure.
pub fn process_sortition(
&mut self,
consensus_hash: ConsensusHash,
Expand Down Expand Up @@ -341,6 +341,7 @@ impl RelayerThread {
}
} else {
MinerDirective::ContinueTenure {
parent_tenure_start: committed_index_hash,
new_burn_view: consensus_hash,
}
}
Expand Down Expand Up @@ -546,6 +547,9 @@ impl RelayerThread {
parent_tenure_id: StacksBlockId,
reason: MinerReason,
) -> Result<BlockMinerThread, NakamotoNodeError> {
debug!("Relayer: creating block miner thread";
"reason" => %reason
);
if fault_injection_skip_mining(&self.config.node.rpc_bind, last_burn_block.block_height) {
debug!(
"Relayer: fault injection skip mining at block height {}",
Expand All @@ -560,7 +564,7 @@ impl RelayerThread {

let burn_chain_tip = burn_chain_sn.burn_header_hash.clone();

if burn_chain_tip != burn_header_hash {
if burn_chain_tip != burn_header_hash && matches!(reason, MinerReason::BlockFound) {
debug!(
"Relayer: Drop stale RunTenure for {}: current sortition is for {}",
&burn_header_hash, &burn_chain_tip
Expand Down Expand Up @@ -647,7 +651,11 @@ impl RelayerThread {
Ok(())
}

fn continue_tenure(&mut self, new_burn_view: ConsensusHash) -> Result<(), NakamotoNodeError> {
fn continue_tenure(
&mut self,
parent_tenure_start: StacksBlockId,
new_burn_view: ConsensusHash,
) -> Result<(), NakamotoNodeError> {
if let Err(e) = self.stop_tenure() {
error!("Relayer: Failed to stop tenure: {:?}", e);
return Ok(());
Expand All @@ -669,45 +677,14 @@ impl RelayerThread {
"block_snapshot_winning_block_txid" => %block_snapshot.winning_block_txid
);
return Ok(());
};

let block_header = NakamotoChainState::get_block_header_by_consensus_hash(
self.chainstate.db(),
&block_snapshot.consensus_hash,
)
.map_err(|e| {
error!("Relayer: failed to get block header for the last sortition snapshsot: {e:?}");
NakamotoNodeError::MissingTenureStartBlockHeader
})?
.ok_or_else(|| {
error!("Relayer: failed to find block header for the last sortition snapshsot");
NakamotoNodeError::MissingTenureStartBlockHeader
})?;

let last_parent_tenure_header =
NakamotoChainState::get_nakamoto_tenure_finish_block_header(
self.chainstate.db(),
&block_header.consensus_hash,
)
.map_err(|e| {
error!("Relayer: failed to get last block of parent tenure: {e:?}");
NakamotoNodeError::ParentNotFound
})?
.ok_or_else(|| {
error!("Relayer: failed to find block header for parent tenure");
NakamotoNodeError::ParentNotFound
})?;

let parent_tenure_info = ParentTenureInfo {
parent_tenure_blocks: 1 + last_parent_tenure_header.stacks_block_height
- block_header.stacks_block_height,
parent_tenure_consensus_hash: new_burn_view,
} else {
debug!("Relayer: the miner won the last sortition. Continuing tenure.");
};
match self.start_new_tenure(
block_header.index_block_hash(),
parent_tenure_start,
block_snapshot,
MinerReason::Extended {
parent_tenure_info,
burn_view_consensus_hash: new_burn_view,
tenure_change_mined: false,
},
) {
Expand Down Expand Up @@ -746,17 +723,18 @@ impl RelayerThread {
error!("Relayer: Failed to start new tenure: {:?}", e);
}
},
MinerDirective::ContinueTenure { new_burn_view } => {
match self.continue_tenure(new_burn_view) {
Ok(()) => {
debug!("Relayer: successfully handled continue tenure.");
}
Err(e) => {
error!("Relayer: Failed to continue tenure: {:?}", e);
return false;
}
MinerDirective::ContinueTenure {
new_burn_view,
parent_tenure_start,
} => match self.continue_tenure(parent_tenure_start, new_burn_view) {
Ok(()) => {
debug!("Relayer: successfully handled continue tenure.");
}
}
Err(e) => {
error!("Relayer: Failed to continue tenure: {:?}", e);
return false;
}
},
MinerDirective::StopTenure => match self.stop_tenure() {
Ok(()) => {
debug!("Relayer: successfully stopped tenure.");
Expand Down
Loading

0 comments on commit 73eacae

Please sign in to comment.