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

fix: set epoch to 3.1 in Clarity DB #5561

Merged
merged 4 commits into from
Dec 16, 2024
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
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ and this project adheres to the versioning scheme outlined in the [README.md](RE

### Added

- Set the epoch to 3.1 in the Clarity DB upon activation.

### Changed

## [3.1.0.0.1]
Expand Down
6 changes: 5 additions & 1 deletion stackslib/src/chainstate/nakamoto/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3937,7 +3937,11 @@ impl NakamotoChainState {

// is this stacks block the first of a new epoch?
let (applied_epoch_transition, mut tx_receipts) =
StacksChainState::process_epoch_transition(&mut clarity_tx, burn_header_height)?;
StacksChainState::process_epoch_transition(
&mut clarity_tx,
sortition_dbconn.as_burn_state_db(),
burn_header_height,
)?;

debug!(
"Setup block: Processed epoch transition";
Expand Down
26 changes: 23 additions & 3 deletions stackslib/src/chainstate/stacks/db/blocks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4044,6 +4044,7 @@ impl StacksChainState {
/// Return (applied?, receipts)
pub fn process_epoch_transition(
clarity_tx: &mut ClarityTx,
burn_dbconn: &dyn BurnStateDB,
chain_tip_burn_header_height: u32,
) -> Result<(bool, Vec<StacksTransactionReceipt>), Error> {
// is this stacks block the first of a new epoch?
Expand Down Expand Up @@ -4104,14 +4105,29 @@ impl StacksChainState {
current_epoch = StacksEpochId::Epoch30;
}
StacksEpochId::Epoch30 => {
// no special initialization is needed, since only the coinbase emission
// schedule is changing.
receipts.append(&mut clarity_tx.block.initialize_epoch_3_1()?);
current_epoch = StacksEpochId::Epoch31;
}
StacksEpochId::Epoch31 => {
panic!("No defined transition from Epoch31 forward")
}
}

if current_epoch > StacksEpochId::Epoch2_05 {
// clarity tx should now have the current epoch
assert_eq!(
clarity_tx.block.get_epoch(),
current_epoch,
"FATAL: clarity_tx does not have the current epoch"
);

// clarity DB should now have the current epoch
assert_eq!(
clarity_tx.block.get_clarity_db_epoch_version(burn_dbconn)?,
current_epoch,
"FATAL: clarity DB does not report the current epoch"
);
}
}
}

Expand Down Expand Up @@ -5198,7 +5214,11 @@ impl StacksChainState {

// is this stacks block the first of a new epoch?
let (applied_epoch_transition, mut tx_receipts) =
StacksChainState::process_epoch_transition(&mut clarity_tx, burn_tip_height)?;
StacksChainState::process_epoch_transition(
&mut clarity_tx,
burn_dbconn,
burn_tip_height,
)?;

debug!(
"Setup block: Processed epoch transition at {}/{}",
Expand Down
41 changes: 41 additions & 0 deletions stackslib/src/clarity_vm/clarity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,21 @@ impl<'a, 'b> ClarityBlockConnection<'a, 'b> {
None => None,
}
}

/// Load the epoch ID from the clarity DB.
/// Used to sanity-check epoch transitions.
pub fn get_clarity_db_epoch_version(
&mut self,
burn_state_db: &dyn BurnStateDB,
) -> Result<StacksEpochId, Error> {
let mut db = self.datastore.as_clarity_db(self.header_db, burn_state_db);
// NOTE: the begin/roll_back shouldn't be necessary with how this gets used in practice,
// but is put here defensively.
db.begin();
let result = db.get_clarity_epoch_version();
db.roll_back()?;
Ok(result?)
}
}

impl ClarityInstance {
Expand Down Expand Up @@ -1524,6 +1539,32 @@ impl<'a, 'b> ClarityBlockConnection<'a, 'b> {
})
}

pub fn initialize_epoch_3_1(&mut self) -> Result<Vec<StacksTransactionReceipt>, Error> {
// use the `using!` statement to ensure that the old cost_tracker is placed
// back in all branches after initialization
using!(self.cost_track, "cost tracker", |old_cost_tracker| {
// epoch initialization is *free*.
// NOTE: this also means that cost functions won't be evaluated.
self.cost_track.replace(LimitedCostTracker::new_free());
self.epoch = StacksEpochId::Epoch31;
self.as_transaction(|tx_conn| {
// bump the epoch in the Clarity DB
tx_conn
.with_clarity_db(|db| {
db.set_clarity_epoch_version(StacksEpochId::Epoch31)?;
Ok(())
})
.unwrap();

// require 3.1 rules henceforth in this connection as well
tx_conn.epoch = StacksEpochId::Epoch31;
});

debug!("Epoch 3.1 initialized");
(old_cost_tracker, Ok(vec![]))
})
}

pub fn start_transaction_processing<'c>(&'c mut self) -> ClarityTransactionConnection<'c, 'a> {
let store = &mut self.datastore;
let cost_track = &mut self.cost_track;
Expand Down
5 changes: 4 additions & 1 deletion stackslib/src/core/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -496,7 +496,10 @@ pub static STACKS_EPOCH_3_0_MARKER: u8 = 0x0b;

/// Stacks 3.1 epoch marker. All block-commits in 3.1 must have a memo bitfield with this value
/// *or greater*.
pub static STACKS_EPOCH_3_1_MARKER: u8 = 0x0c;
/// NOTE: it has to be 0x0d because a prior release of 3.1 with 0x0c before activation had a
/// consensus bug. This forces miners with this buggy release off the network if they are still
/// running it prior to 3.1 activation.
pub static STACKS_EPOCH_3_1_MARKER: u8 = 0x0d;

#[test]
fn test_ord_for_stacks_epoch() {
Expand Down