mirror of
https://github.com/alexgo-io/stacks-puppet-node.git
synced 2026-01-13 08:40:45 +08:00
fix: address PR feedback, and make it so that the test framework generates the correct UTXO linkage data (so the new MEV algorithm won't disqualify Nakamoto miners using TestPeer)
This commit is contained in:
@@ -131,12 +131,15 @@ impl BurnchainStateTransition {
|
||||
|
||||
if block_total_burns.len() == 0 {
|
||||
return Some(0);
|
||||
} else if block_total_burns.len() == 1 {
|
||||
return Some(block_total_burns[0])
|
||||
} else if block_total_burns.len() % 2 != 0 {
|
||||
let idx = block_total_burns.len() / 2;
|
||||
return block_total_burns.get(idx).map(|b| *b);
|
||||
} else {
|
||||
let idx_left = block_total_burns.len() / 2;
|
||||
let idx_right = block_total_burns.len() / 2 + 1;
|
||||
// NOTE: the `- 1` is safe because block_total_burns.len() >= 2
|
||||
let idx_left = block_total_burns.len() / 2 - 1;
|
||||
let idx_right = block_total_burns.len() / 2;
|
||||
let burn_left = block_total_burns.get(idx_left)?;
|
||||
let burn_right = block_total_burns.get(idx_right)?;
|
||||
return Some((burn_left + burn_right) / 2);
|
||||
@@ -252,6 +255,7 @@ impl BurnchainStateTransition {
|
||||
|
||||
windowed_missed_commits.push(missed_commits_at_height);
|
||||
}
|
||||
test_debug!("Block {} is in a reward phase with PoX. Miner commit window is {}: {:?}", parent_snapshot.block_height + 1, windowed_block_commits.len(), &windowed_block_commits);
|
||||
} else {
|
||||
// PoX reward-phase is not active
|
||||
debug!(
|
||||
|
||||
@@ -452,7 +452,7 @@ impl TestBurnchainBlock {
|
||||
leader_key.block_height as u32,
|
||||
leader_key.vtxindex as u16,
|
||||
burn_fee,
|
||||
&input,
|
||||
&(parent.txid.clone(), (1 + parent.commit_outs.len()) as u32),
|
||||
&apparent_sender,
|
||||
);
|
||||
txop
|
||||
|
||||
@@ -18,12 +18,16 @@ use stacks_common::util::uint::Uint256;
|
||||
|
||||
use crate::stacks_common::util::uint::BitArray;
|
||||
|
||||
/// A fixed-point numerical representation for ATC. THe integer and fractional parts are both 64
|
||||
/// bits.
|
||||
/// A fixed-point numerical representation for ATC. The integer and fractional parts are both 64
|
||||
/// bits. Internally, this is a Uint256 so that safe addition and multiplication can be done.
|
||||
///
|
||||
/// Bits 0-63 are the fraction.
|
||||
/// Bits 64-127 are the integer.
|
||||
/// Bits 128-256 are 0's to facilitate safe addition and multiplication.
|
||||
///
|
||||
/// The reasons we use this instead of f64 for ATC calculations are as follows:
|
||||
/// * This avoids unrepresentable states, like NaN or +/- INF
|
||||
/// * This avoids ambituous states, like +0.0 and -0.0.
|
||||
/// * This avoids ambiguous states, like +0.0 and -0.0.
|
||||
/// * This integrates better into the sortition-sampling system, which uses a u256 to represent a
|
||||
/// probability range (which is what this is going to be used for)
|
||||
#[derive(Debug, Clone, PartialEq, Copy, Eq, Hash)]
|
||||
@@ -271,7 +275,7 @@ mod test {
|
||||
|
||||
/// Calculate the logic advantage curve for the null miner.
|
||||
/// This function's parameters are chosen such that:
|
||||
/// * if the ATC carryover has diminished by less than 20%, the null miner has negligeable
|
||||
/// * if the ATC carryover has diminished by less than 20%, the null miner has negligible
|
||||
/// chances of winning. This is to avoid punishing honest miners when there are flash blocks.
|
||||
/// * If the ATC carryover has diminished by between 20% and 80%, the null miner has a
|
||||
/// better-than-linear probability of winning. That is, if the burnchain MEV miner pays less
|
||||
@@ -365,7 +369,7 @@ mod test {
|
||||
/// assumed total commit carryover -- the ratio between what the winning miner paid in this
|
||||
/// block-commit to the median of what they historically paid (for an epoch-defined search window
|
||||
/// size). A value greater than 1.0 means that the miner paid all of the assumed commit
|
||||
/// carry-over, and the null miner has negligeable chances of winning. A value less than 1.0 means
|
||||
/// carry-over, and the null miner has negligible chances of winning. A value less than 1.0 means
|
||||
/// that the miner underpaid relative to their past performance, and the closer to 0.0 this ratio
|
||||
/// is, the more likely the null miner wins and this miner loses.
|
||||
///
|
||||
|
||||
@@ -187,7 +187,7 @@ impl BlockSnapshot {
|
||||
}
|
||||
|
||||
/// Select the next Stacks block header hash using cryptographic sortition.
|
||||
/// Go through all block commits at this height, find out how any burn tokens
|
||||
/// Go through all block commits at this height, find out how many burn tokens
|
||||
/// were spent for them, and select one at random using the relative burn amounts
|
||||
/// to weight the sample. Use HASH(sortition_hash ++ last_VRF_seed) to pick the
|
||||
/// winning block commit, and by extension, the next VRF seed.
|
||||
@@ -382,7 +382,7 @@ impl BlockSnapshot {
|
||||
///
|
||||
/// This is NullP(atc) = (1 - atc) + atc * adv(atc).
|
||||
///
|
||||
/// Where atv(x) is an "advantage function", such that the null miner is more heavily favored
|
||||
/// Where adv(x) is an "advantage function", such that the null miner is more heavily favored
|
||||
/// to win based on how comparatively little commit carryover there is. Here, adv(x) is a
|
||||
/// logistic function.
|
||||
///
|
||||
@@ -439,8 +439,8 @@ impl BlockSnapshot {
|
||||
// make the block header hash different, to render it different from the winner.
|
||||
// Just flip the block header bits.
|
||||
let mut bhh_bytes = null_winner.block_header_hash.0.clone();
|
||||
for i in 0..bhh_bytes.len() {
|
||||
bhh_bytes[i] = !bhh_bytes[i];
|
||||
for byte in bhh_bytes.iter_mut() {
|
||||
*byte = !*byte;
|
||||
}
|
||||
BlockHeaderHash(bhh_bytes)
|
||||
};
|
||||
@@ -452,7 +452,7 @@ impl BlockSnapshot {
|
||||
|
||||
// AtcRational's integer part is only 64 bits, so we need to scale it up so that it occupes the
|
||||
// upper 64 bits of the burn sample point ranges so as to accurately represent the fraction
|
||||
// fo mining power the null miner has.
|
||||
// of mining power the null miner has.
|
||||
let null_prob_u256 = if null_prob.0 >= AtcRational::one().0 {
|
||||
// prevent left-shift overflow
|
||||
AtcRational::one_sup().into_inner() << 192
|
||||
@@ -655,7 +655,7 @@ impl BlockSnapshot {
|
||||
// * if the winning miner didn't mine in more than k of n blocks of the window, then their chances of
|
||||
// winning are 0.
|
||||
// * There exists a "null miner" that can win sortition, in which case there is no
|
||||
// sortition. This happens if the assumed total commit with carry-over is sufficently low.
|
||||
// sortition. This happens if the assumed total commit with carry-over is sufficiently low.
|
||||
let mut reject_winner_reason = None;
|
||||
if epoch_id >= StacksEpochId::Epoch30 {
|
||||
if !Self::check_miner_is_active(
|
||||
|
||||
Reference in New Issue
Block a user