From 04fbd00a1244afeb124cf14cabb1b45f83b198ae Mon Sep 17 00:00:00 2001 From: Brice Dobry Date: Wed, 11 Dec 2024 10:30:47 -0500 Subject: [PATCH 1/9] fix: set epoch to 3.1 in Clarity DB --- stackslib/src/chainstate/stacks/db/blocks.rs | 3 +-- stackslib/src/clarity_vm/clarity.rs | 26 ++++++++++++++++++++ 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/stackslib/src/chainstate/stacks/db/blocks.rs b/stackslib/src/chainstate/stacks/db/blocks.rs index 233a9d5978..dbb14d8f46 100644 --- a/stackslib/src/chainstate/stacks/db/blocks.rs +++ b/stackslib/src/chainstate/stacks/db/blocks.rs @@ -4104,8 +4104,7 @@ 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 => { diff --git a/stackslib/src/clarity_vm/clarity.rs b/stackslib/src/clarity_vm/clarity.rs index a5497cea24..ada6292add 100644 --- a/stackslib/src/clarity_vm/clarity.rs +++ b/stackslib/src/clarity_vm/clarity.rs @@ -1524,6 +1524,32 @@ impl<'a, 'b> ClarityBlockConnection<'a, 'b> { }) } + pub fn initialize_epoch_3_1(&mut self) -> Result, 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; From d99d566ec98afea713b1d91b17fac74067649b4f Mon Sep 17 00:00:00 2001 From: Jude Nelson Date: Wed, 11 Dec 2024 11:25:25 -0500 Subject: [PATCH 2/9] chore: set new 3.1 epoch marker --- stackslib/src/core/mod.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/stackslib/src/core/mod.rs b/stackslib/src/core/mod.rs index ba4dbf14d2..0f43c40756 100644 --- a/stackslib/src/core/mod.rs +++ b/stackslib/src/core/mod.rs @@ -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() { From 8e02cf0a75b56b9a183bb06d1f2932f94114f8bd Mon Sep 17 00:00:00 2001 From: Jude Nelson Date: Wed, 11 Dec 2024 12:07:14 -0500 Subject: [PATCH 3/9] chore: check both clarity tx and clarity db epoch versions at each epoch transition --- stackslib/src/chainstate/nakamoto/mod.rs | 6 ++++- stackslib/src/chainstate/stacks/db/blocks.rs | 23 +++++++++++++++++++- stackslib/src/clarity_vm/clarity.rs | 15 +++++++++++++ 3 files changed, 42 insertions(+), 2 deletions(-) diff --git a/stackslib/src/chainstate/nakamoto/mod.rs b/stackslib/src/chainstate/nakamoto/mod.rs index 35f6e5d1e1..adf9dddc0e 100644 --- a/stackslib/src/chainstate/nakamoto/mod.rs +++ b/stackslib/src/chainstate/nakamoto/mod.rs @@ -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"; diff --git a/stackslib/src/chainstate/stacks/db/blocks.rs b/stackslib/src/chainstate/stacks/db/blocks.rs index dbb14d8f46..5f6b236973 100644 --- a/stackslib/src/chainstate/stacks/db/blocks.rs +++ b/stackslib/src/chainstate/stacks/db/blocks.rs @@ -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), Error> { // is this stacks block the first of a new epoch? @@ -4111,6 +4112,22 @@ impl StacksChainState { 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" + ); + } } } @@ -5197,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 {}/{}", diff --git a/stackslib/src/clarity_vm/clarity.rs b/stackslib/src/clarity_vm/clarity.rs index ada6292add..ee8795cadd 100644 --- a/stackslib/src/clarity_vm/clarity.rs +++ b/stackslib/src/clarity_vm/clarity.rs @@ -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 { + 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 { From 56ded5342eef74555e6a82e29b36939da8e8f24c Mon Sep 17 00:00:00 2001 From: Brice Dobry Date: Thu, 12 Dec 2024 12:18:42 -0500 Subject: [PATCH 4/9] chore: add changelog --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f85ed6526b..9007e510ad 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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] From 97910c5c5d930c9d776a84f19caaa9017ad55916 Mon Sep 17 00:00:00 2001 From: wileyj <2847772+wileyj@users.noreply.github.com> Date: Fri, 13 Dec 2024 09:14:41 -0800 Subject: [PATCH 5/9] Adding changelog for 3.1.0.0.2.x --- CHANGELOG.md | 14 +++----------- stacks-signer/CHANGELOG.md | 7 +++++-- 2 files changed, 8 insertions(+), 13 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9007e510ad..d19470075d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,19 +9,9 @@ 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] - -### Added - -- A miner will now generate a tenure-extend when at least 70% of the signers have confirmed that they are willing to allow one, via the new timestamp included in block responses. This allows the miner to refresh its budget in between Bitcoin blocks. ([#5476](https://github.com/stacks-network/stacks-core/discussions/5476)) - -### Changed - -## [3.1.0.0.0] +## [3.1.0.0.2] ### Added @@ -30,6 +20,8 @@ and this project adheres to the versioning scheme outlined in the [README.md](RE - `/v2/clarity/marf/:marf_key_hash` - `/v2/clarity/metadata/:principal/:contract_name/:clarity_metadata_key` - When a proposed block is validated by a node, the block can be validated even when the block version is different than the node's default ([#5539](https://github.com/stacks-network/stacks-core/pull/5539)) +- A miner will now generate a tenure-extend when at least 70% of the signers have confirmed that they are willing to allow one, via the new timestamp included in block responses. This allows the miner to refresh its budget in between Bitcoin blocks. ([#5476](https://github.com/stacks-network/stacks-core/discussions/5476)) +- Set the epoch to 3.1 in the Clarity DB upon activation. ### Changed diff --git a/stacks-signer/CHANGELOG.md b/stacks-signer/CHANGELOG.md index 2f1187de51..fd38fe9775 100644 --- a/stacks-signer/CHANGELOG.md +++ b/stacks-signer/CHANGELOG.md @@ -11,15 +11,18 @@ and this project adheres to the versioning scheme outlined in the [README.md](RE ## Changed -## [3.1.0.0.1.0] +## [3.1.0.0.2.0] -### Added +## Added + +- **SIP-029 consensus rules, activating in epoch 3.1 at block 875,000** (see [SIP-029](https://github.com/will-corcoran/sips/blob/feat/sip-029-halving-alignment/sips/sip-029/sip-029-halving-alignment.md) for details) ### Changed - Added tenure extend timestamp to signer block responses - Added tenure_idle_timeout_secs configuration option for determining when a time-based tenure extend will be accepted + ## [3.1.0.0.0.0] ### Added From f97a6bea4d15901b59521331791b936c16fdb72e Mon Sep 17 00:00:00 2001 From: wileyj <2847772+wileyj@users.noreply.github.com> Date: Fri, 20 Dec 2024 12:35:40 -0800 Subject: [PATCH 6/9] re-adding line from e486b9e19e9bc2c73835d3f7cb6c9c1a3f5e6153 --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 53e7d29fbb..e34ade9a33 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,8 @@ and this project adheres to the versioning scheme outlined in the [README.md](RE ### Changed +- Nodes will assume that all PoX anchor blocks exist by default, and stall initial block download indefinitely to await their arrival (#5502) + ## [3.1.0.0.2] ### Added From 0279bc02a2663292610ee2f0bdd772eed6491ef9 Mon Sep 17 00:00:00 2001 From: Jacinta Ferrant Date: Mon, 23 Dec 2024 14:06:06 -0500 Subject: [PATCH 7/9] Do not process block validation responses for the wrong reward cycle Signed-off-by: Jacinta Ferrant --- stacks-signer/src/v0/signer.rs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/stacks-signer/src/v0/signer.rs b/stacks-signer/src/v0/signer.rs index 5a5128cce4..476e2a5898 100644 --- a/stacks-signer/src/v0/signer.rs +++ b/stacks-signer/src/v0/signer.rs @@ -584,6 +584,14 @@ impl Signer { // For mutability reasons, we need to take the block_info out of the map and add it back after processing let mut block_info = match self.signer_db.block_lookup(&signer_signature_hash) { Ok(Some(block_info)) => { + if block_info.reward_cycle != self.reward_cycle { + // We are not signing for this reward cycle. Ignore the block. + debug!( + "{self}: Received a block validation response for a different reward cycle. Ignore it."; + "requested_reward_cycle" => block_info.reward_cycle, + ); + return None; + } if block_info.is_locally_finalized() { debug!("{self}: Received block validation for a block that is already marked as {}. Ignoring...", block_info.state); return None; @@ -655,6 +663,14 @@ impl Signer { } let mut block_info = match self.signer_db.block_lookup(&signer_signature_hash) { Ok(Some(block_info)) => { + if block_info.reward_cycle != self.reward_cycle { + // We are not signing for this reward cycle. Ignore the block. + debug!( + "{self}: Received a block validation response for a different reward cycle. Ignore it."; + "requested_reward_cycle" => block_info.reward_cycle, + ); + return None; + } if block_info.is_locally_finalized() { debug!("{self}: Received block validation for a block that is already marked as {}. Ignoring...", block_info.state); return None; From 1eb99245fde79ef1fd8c40e2faa07128d2d55ce0 Mon Sep 17 00:00:00 2001 From: Jacinta Ferrant Date: Mon, 23 Dec 2024 14:32:14 -0500 Subject: [PATCH 8/9] Add changelog Signed-off-by: Jacinta Ferrant --- stacks-signer/CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/stacks-signer/CHANGELOG.md b/stacks-signer/CHANGELOG.md index 3c7ec2d0c1..45bf42fada 100644 --- a/stacks-signer/CHANGELOG.md +++ b/stacks-signer/CHANGELOG.md @@ -8,6 +8,7 @@ and this project adheres to the versioning scheme outlined in the [README.md](RE ## [Unreleased] ## Added +- Prevent old reward cycle signers from processing block validation response messages that do not apply to blocks from their cycle. - Introduced the `block_proposal_max_age_secs` configuration option for signers, enabling them to automatically ignore block proposals that exceed the specified age in seconds. From d930f44eebc1db15f5dc08e167d738f1a00eb4e9 Mon Sep 17 00:00:00 2001 From: Jacinta Ferrant Date: Mon, 23 Dec 2024 14:34:24 -0500 Subject: [PATCH 9/9] FIx changelog Signed-off-by: Jacinta Ferrant --- stacks-signer/CHANGELOG.md | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/stacks-signer/CHANGELOG.md b/stacks-signer/CHANGELOG.md index 45bf42fada..04d2d76a7a 100644 --- a/stacks-signer/CHANGELOG.md +++ b/stacks-signer/CHANGELOG.md @@ -8,7 +8,6 @@ and this project adheres to the versioning scheme outlined in the [README.md](RE ## [Unreleased] ## Added -- Prevent old reward cycle signers from processing block validation response messages that do not apply to blocks from their cycle. - Introduced the `block_proposal_max_age_secs` configuration option for signers, enabling them to automatically ignore block proposals that exceed the specified age in seconds. @@ -16,6 +15,14 @@ and this project adheres to the versioning scheme outlined in the [README.md](RE - Improvements to the stale signer cleanup logic: deletes the prior signer if it has no remaining unprocessed blocks in its database - Signers now listen to new block events from the stacks node to determine whether a block has been successfully appended to the chain tip +# [3.1.0.0.2.1] + +## Added + +## Changed + +- Prevent old reward cycle signers from processing block validation response messages that do not apply to blocks from their cycle. + ## [3.1.0.0.2.0] ## Added