Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat/remove-pox-sunset #3129

Merged
merged 1 commit into from
May 9, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
86 changes: 17 additions & 69 deletions src/burnchains/burnchain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,6 @@ impl BurnchainStateTransition {
parent_snapshot: &BlockSnapshot,
block_ops: &Vec<BlockstackOperationType>,
missed_commits: &Vec<MissedBlockCommit>,
sunset_end: u64,
) -> Result<BurnchainStateTransition, burnchain_error> {
// block commits and support burns discovered in this block.
let mut block_commits: Vec<LeaderBlockCommitOp> = vec![];
Expand Down Expand Up @@ -167,9 +166,7 @@ impl BurnchainStateTransition {
let mut windowed_block_commits = vec![block_commits];
let mut windowed_missed_commits = vec![];

if !burnchain.is_in_prepare_phase(parent_snapshot.block_height + 1)
&& parent_snapshot.block_height + 1 <= burnchain.pox_constants.sunset_end
{
if !burnchain.is_in_prepare_phase(parent_snapshot.block_height + 1) {
// PoX reward-phase is active!
// build a map of intended sortition -> missed commit for the missed commits
// discovered in this block.
Expand Down Expand Up @@ -212,7 +209,7 @@ impl BurnchainStateTransition {
} else {
// PoX reward-phase is not active
debug!(
"Block {} is in a prepare phase or post-PoX sunset, so no windowing will take place",
"Block {} is in a prepare phase, so no windowing will take place",
parent_snapshot.block_height + 1
);

Expand All @@ -224,18 +221,14 @@ impl BurnchainStateTransition {
windowed_block_commits.reverse();
windowed_missed_commits.reverse();

// figure out if the PoX sunset finished during the window,
// and/or which sortitions must be PoB due to them falling in a prepare phase.
// figure out which sortitions must be PoB due to them falling in a prepare phase.
let window_end_height = parent_snapshot.block_height + 1;
let window_start_height = window_end_height + 1 - (windowed_block_commits.len() as u64);
let mut burn_blocks = vec![false; windowed_block_commits.len()];

// set burn_blocks flags to accomodate prepare phases and PoX sunset
// set burn_blocks flags to accomodate prepare phases
for (i, b) in burn_blocks.iter_mut().enumerate() {
if sunset_end <= window_start_height + (i as u64) {
// past PoX sunset, so must burn
*b = true;
} else if burnchain.is_in_prepare_phase(window_start_height + (i as u64)) {
if burnchain.is_in_prepare_phase(window_start_height + (i as u64)) {
// must burn
*b = true;
} else {
Expand Down Expand Up @@ -462,40 +455,6 @@ impl Burnchain {
self.network_id == NETWORK_ID_MAINNET
}

/// the expected sunset burn is:
/// total_commit * (progress through sunset phase) / (sunset phase duration)
pub fn expected_sunset_burn(&self, burn_height: u64, total_commit: u64) -> u64 {
if burn_height < self.pox_constants.sunset_start
|| burn_height >= self.pox_constants.sunset_end
{
return 0;
}

// no sunset burn needed in prepare phase -- it's already getting burnt
if self.is_in_prepare_phase(burn_height) {
return 0;
}

let reward_cycle_height = self.reward_cycle_to_block_height(
self.block_height_to_reward_cycle(burn_height)
.expect("BUG: Sunset start is less than first_block_height"),
);

if reward_cycle_height <= self.pox_constants.sunset_start {
return 0;
}

let sunset_duration =
(self.pox_constants.sunset_end - self.pox_constants.sunset_start) as u128;
let sunset_progress = (reward_cycle_height - self.pox_constants.sunset_start) as u128;

// use u128 to avoid any possibilities of overflowing in the calculation here.
let expected_u128 = (total_commit as u128) * (sunset_progress) / sunset_duration;
u64::try_from(expected_u128)
// should never be possible, because sunset_burn is <= total_commit, which is a u64
.expect("Overflowed u64 in calculating expected sunset_burn")
}

pub fn is_reward_cycle_start(&self, burn_height: u64) -> bool {
let effective_height = burn_height - self.first_block_height;
// first block of the new reward cycle
Expand Down Expand Up @@ -743,20 +702,18 @@ impl Burnchain {
}
}
}
x if x == Opcodes::PreStx as u8 => {
match PreStxOp::from_tx(block_header, burn_tx, burnchain.pox_constants.sunset_end) {
Ok(op) => Some(BlockstackOperationType::PreStx(op)),
Err(e) => {
warn!(
"Failed to parse pre stack stx tx";
"txid" => %burn_tx.txid(),
"data" => %to_hex(&burn_tx.data()),
"error" => ?e,
);
None
}
x if x == Opcodes::PreStx as u8 => match PreStxOp::from_tx(block_header, burn_tx) {
Ok(op) => Some(BlockstackOperationType::PreStx(op)),
Err(e) => {
warn!(
"Failed to parse pre stack stx tx";
"txid" => %burn_tx.txid(),
"data" => %to_hex(&burn_tx.data()),
"error" => ?e,
);
None
}
}
},
x if x == Opcodes::TransferStx as u8 => {
let pre_stx_txid = TransferStxOp::get_sender_txid(burn_tx).ok()?;
let pre_stx_tx = match pre_stx_op_map.get(&pre_stx_txid) {
Expand Down Expand Up @@ -794,12 +751,7 @@ impl Burnchain {
};
if let Some(BlockstackOperationType::PreStx(pre_stack_stx)) = pre_stx_tx {
let sender = &pre_stack_stx.output;
match StackStxOp::from_tx(
block_header,
burn_tx,
sender,
burnchain.pox_constants.sunset_end,
) {
match StackStxOp::from_tx(block_header, burn_tx, sender) {
Ok(op) => Some(BlockstackOperationType::StackStx(op)),
Err(e) => {
warn!(
Expand Down Expand Up @@ -1864,7 +1816,6 @@ pub mod tests {
};

let block_commit_1 = LeaderBlockCommitOp {
sunset_burn: 0,
commit_outs: vec![],
block_header_hash: BlockHeaderHash::from_bytes(
&hex_bytes("2222222222222222222222222222222222222222222222222222222222222222")
Expand Down Expand Up @@ -1905,7 +1856,6 @@ pub mod tests {
};

let block_commit_2 = LeaderBlockCommitOp {
sunset_burn: 0,
commit_outs: vec![],
block_header_hash: BlockHeaderHash::from_bytes(
&hex_bytes("2222222222222222222222222222222222222222222222222222222222222223")
Expand Down Expand Up @@ -1946,7 +1896,6 @@ pub mod tests {
};

let block_commit_3 = LeaderBlockCommitOp {
sunset_burn: 0,
commit_outs: vec![],
block_header_hash: BlockHeaderHash::from_bytes(
&hex_bytes("2222222222222222222222222222222222222222222222222222222222222224")
Expand Down Expand Up @@ -2509,7 +2458,6 @@ pub mod tests {
// insert block commit paired to previous round's leader key, as well as a user burn
if i > 0 {
let next_block_commit = LeaderBlockCommitOp {
sunset_burn: 0,
commit_outs: vec![],
block_header_hash: BlockHeaderHash::from_bytes(&vec![
i, i, i, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
Expand Down
4 changes: 0 additions & 4 deletions src/burnchains/db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -430,8 +430,6 @@ mod tests {

let mut burnchain = Burnchain::regtest(":memory:");
burnchain.pox_constants = PoxConstants::test_default();
burnchain.pox_constants.sunset_start = 999;
burnchain.pox_constants.sunset_end = 1000;

let first_block_header = burnchain_db.get_canonical_chain_tip().unwrap();
assert_eq!(&first_block_header.block_hash, &first_bhh);
Expand Down Expand Up @@ -542,8 +540,6 @@ mod tests {

let mut burnchain = Burnchain::regtest(":memory:");
burnchain.pox_constants = PoxConstants::test_default();
burnchain.pox_constants.sunset_start = 999;
burnchain.pox_constants.sunset_end = 1000;

let first_block_header = burnchain_db.get_canonical_chain_tip().unwrap();
assert_eq!(&first_block_header.block_hash, &first_bhh);
Expand Down
26 changes: 2 additions & 24 deletions src/burnchains/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -301,10 +301,6 @@ pub struct PoxConstants {
/// percentage of liquid STX that must participate for PoX
/// to occur
pub pox_participation_threshold_pct: u64,
/// last+1 block height of sunset phase
pub sunset_end: u64,
/// first block height of sunset phase
pub sunset_start: u64,
/// The auto unlock height for PoX v1 lockups before transition to PoX v2. This
/// also defines the burn height at which PoX reward sets are calculated using
/// PoX v2 rather than v1
Expand All @@ -319,30 +315,25 @@ impl PoxConstants {
anchor_threshold: u32,
pox_rejection_fraction: u64,
pox_participation_threshold_pct: u64,
sunset_start: u64,
sunset_end: u64,
v1_unlock_height: u32,
) -> PoxConstants {
assert!(anchor_threshold > (prepare_length / 2));
assert!(prepare_length < reward_cycle_length);
assert!(sunset_start <= sunset_end);

PoxConstants {
reward_cycle_length,
prepare_length,
anchor_threshold,
pox_rejection_fraction,
pox_participation_threshold_pct,
sunset_start,
sunset_end,
v1_unlock_height,
_shadow: PhantomData,
}
}
#[cfg(test)]
pub fn test_default() -> PoxConstants {
// 20 reward slots; 10 prepare-phase slots
PoxConstants::new(10, 5, 3, 25, 5, 5000, 10000, u32::max_value())
PoxConstants::new(10, 5, 3, 25, 5, u32::max_value())
}

/// Returns the PoX contract that is "active" at the given burn block height
Expand Down Expand Up @@ -375,8 +366,6 @@ impl PoxConstants {
80,
25,
5,
BITCOIN_MAINNET_FIRST_BLOCK_HEIGHT + POX_SUNSET_START,
BITCOIN_MAINNET_FIRST_BLOCK_HEIGHT + POX_SUNSET_END,
POX_V1_MAINNET_EARLY_UNLOCK_HEIGHT,
)
}
Expand All @@ -388,23 +377,12 @@ impl PoxConstants {
40,
12,
2,
BITCOIN_TESTNET_FIRST_BLOCK_HEIGHT + POX_SUNSET_START,
BITCOIN_TESTNET_FIRST_BLOCK_HEIGHT + POX_SUNSET_END,
POX_V1_TESTNET_EARLY_UNLOCK_HEIGHT,
) // total liquid supply is 40000000000000000 µSTX
}

pub fn regtest_default() -> PoxConstants {
PoxConstants::new(
5,
1,
1,
3333333333333333,
1,
BITCOIN_REGTEST_FIRST_BLOCK_HEIGHT + POX_SUNSET_START,
BITCOIN_REGTEST_FIRST_BLOCK_HEIGHT + POX_SUNSET_END,
1_000_000,
)
PoxConstants::new(5, 1, 1, 3333333333333333, 1, 1_000_000)
}
}

Expand Down
3 changes: 1 addition & 2 deletions src/chainstate/burn/db/processing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ impl<'a> SortitionHandleTx<'a> {
let this_block_hash = block_header.block_hash.clone();

// make the burn distribution, and in doing so, identify the user burns that we'll keep
let state_transition = BurnchainStateTransition::from_block_ops(self, burnchain, parent_snapshot, this_block_ops, missed_commits, burnchain.pox_constants.sunset_end)
let state_transition = BurnchainStateTransition::from_block_ops(self, burnchain, parent_snapshot, this_block_ops, missed_commits)
.map_err(|e| {
error!("TRANSACTION ABORTED when converting {} blockstack operations in block {} ({}) to a burn distribution: {:?}", this_block_ops.len(), this_block_height, &this_block_hash, e);
e
Expand Down Expand Up @@ -412,7 +412,6 @@ mod tests {
};

let block_commit = LeaderBlockCommitOp {
sunset_burn: 0,
block_header_hash: BlockHeaderHash([0x22; 32]),
new_seed: VRFSeed::from_hex(
"3333333333333333333333333333333333333333333333333333333333333333",
Expand Down
Loading