Skip to content

Commit 9c13b5f

Browse files
committed
Merge branch 'develop' of https://github.com/stacks-network/stacks-core into chore/merge-develop-to-aac-client-breaking
2 parents 8d6248b + ab68e4a commit 9c13b5f

19 files changed

+1741
-697
lines changed

clarity-types/src/errors/mod.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,6 @@ pub enum RuntimeError {
192192
PoxAlreadyLocked,
193193
/// Block time unavailable during execution.
194194
BlockTimeNotAvailable,
195-
Unreachable,
196195
}
197196

198197
#[derive(Debug, PartialEq)]

clarity/src/vm/version.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,13 @@ impl ClarityVersion {
2929
ClarityVersion::Clarity4
3030
}
3131

32+
pub const ALL: &'static [ClarityVersion] = &[
33+
ClarityVersion::Clarity1,
34+
ClarityVersion::Clarity2,
35+
ClarityVersion::Clarity3,
36+
ClarityVersion::Clarity4,
37+
];
38+
3239
pub fn default_for_epoch(epoch_id: StacksEpochId) -> ClarityVersion {
3340
match epoch_id {
3441
StacksEpochId::Epoch10 => {

pox-locking/src/pox_4.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ use clarity::vm::contexts::GlobalContext;
1919
use clarity::vm::costs::cost_functions::ClarityCostFunction;
2020
use clarity::vm::costs::runtime_cost;
2121
use clarity::vm::database::{ClarityDatabase, STXBalance};
22-
use clarity::vm::errors::{RuntimeError, VmExecutionError};
22+
use clarity::vm::errors::{RuntimeError, VmExecutionError, VmInternalError};
2323
use clarity::vm::events::{STXEventType, STXLockEventData, StacksTransactionEvent};
2424
use clarity::vm::types::{PrincipalData, QualifiedContractIdentifier};
2525
use clarity::vm::{Environment, Value};
@@ -401,13 +401,16 @@ pub fn handle_contract_call(
401401
global_context.log_stacking(sender, *amount)?;
402402
}
403403
_ => {
404+
let msg = "Unreachable: failed to log STX delegation in PoX-4 delegate-stx call";
404405
// This should be unreachable!
405406
error!(
406-
"Unreachable: failed to log STX delegation in PoX-4 delegate-stx call";
407+
"{msg}";
407408
"sender" => ?sender_opt,
408409
"arg0" => ?args.first(),
409410
);
410-
return Err(VmExecutionError::Runtime(RuntimeError::Unreachable, None));
411+
return Err(VmExecutionError::Internal(VmInternalError::Expect(
412+
msg.into(),
413+
)));
411414
}
412415
}
413416
}

stacks-common/src/types/mod.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -447,6 +447,13 @@ impl StacksEpochId {
447447
StacksEpochId::Epoch32
448448
}
449449

450+
pub const ALL_GTE_30: &'static [StacksEpochId] = &[
451+
StacksEpochId::Epoch30,
452+
StacksEpochId::Epoch31,
453+
StacksEpochId::Epoch32,
454+
StacksEpochId::Epoch33,
455+
];
456+
450457
/// In this epoch, how should the mempool perform garbage collection?
451458
pub fn mempool_garbage_behavior(&self) -> MempoolCollectionBehavior {
452459
match self {

stacks-node/src/nakamoto_node/miner.rs

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1029,18 +1029,13 @@ impl BlockMinerThread {
10291029
let burn_view_ch =
10301030
NakamotoChainState::get_block_burn_view(sort_db, block, &parent_block_info)?;
10311031
let mut sortition_handle = sort_db.index_handle_at_ch(&burn_view_ch)?;
1032-
let chainstate_config = chain_state.config();
1033-
let (headers_conn, staging_tx) = chain_state.headers_conn_and_staging_tx_begin()?;
10341032
let accepted = NakamotoChainState::accept_block(
1035-
&chainstate_config,
1033+
chain_state,
10361034
block,
10371035
&mut sortition_handle,
1038-
&staging_tx,
1039-
headers_conn,
10401036
reward_set,
10411037
NakamotoBlockObtainMethod::Mined,
10421038
)?;
1043-
staging_tx.commit()?;
10441039

10451040
if !accepted {
10461041
// this can happen if the p2p network and relayer manage to receive this block prior to

stackslib/src/chainstate/nakamoto/mod.rs

Lines changed: 5 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -2391,76 +2391,6 @@ impl NakamotoChainState {
23912391
Ok(())
23922392
}
23932393

2394-
/// Insert a Nakamoto block into the staging blocks DB.
2395-
/// We only store a block in the following cases:
2396-
///
2397-
/// * No block with this block's sighash exists in the DB
2398-
/// * A block with this block's sighash exists, AND
2399-
/// * this block represents more signing power
2400-
///
2401-
/// If neither of the above is true, then this is a no-op.
2402-
pub(crate) fn store_block_if_better(
2403-
staging_db_tx: &NakamotoStagingBlocksTx,
2404-
block: &NakamotoBlock,
2405-
burn_attachable: bool,
2406-
signing_weight: u32,
2407-
obtain_method: NakamotoBlockObtainMethod,
2408-
) -> Result<bool, ChainstateError> {
2409-
let block_id = block.block_id();
2410-
let block_hash = block.header.block_hash();
2411-
2412-
// case 1 -- no block with this sighash exists.
2413-
if staging_db_tx.try_store_block_with_new_signer_sighash(
2414-
block,
2415-
burn_attachable,
2416-
signing_weight,
2417-
obtain_method,
2418-
)? {
2419-
debug!("Stored block with new sighash";
2420-
"block_id" => %block_id,
2421-
"block_hash" => %block_hash);
2422-
return Ok(true);
2423-
}
2424-
2425-
// case 2 -- the block exists. Consider replacing it, but only if its
2426-
// signing weight is higher.
2427-
let (existing_block_id, _processed, orphaned, existing_signing_weight) = staging_db_tx.conn().get_block_processed_and_signed_weight(&block.header.consensus_hash, &block_hash)?
2428-
.ok_or_else(|| {
2429-
// this should be unreachable -- there's no record of this block
2430-
error!("Could not store block {} ({}) with block hash {} -- no record of its processed status or signing weight!", &block_id, &block.header.consensus_hash, &block_hash);
2431-
ChainstateError::NoSuchBlockError
2432-
})?;
2433-
2434-
if orphaned {
2435-
// nothing to do
2436-
debug!("Will not store alternative copy of block {} ({}) with block hash {}, since a block with the same block hash was orphaned", &block_id, &block.header.consensus_hash, &block_hash);
2437-
return Ok(false);
2438-
}
2439-
2440-
let ret = if existing_signing_weight < signing_weight {
2441-
staging_db_tx.replace_block(block, signing_weight, obtain_method)?;
2442-
debug!("Replaced block";
2443-
"existing_block_id" => %existing_block_id,
2444-
"block_id" => %block_id,
2445-
"block_hash" => %block_hash,
2446-
"existing_signing_weight" => existing_signing_weight,
2447-
"signing_weight" => signing_weight);
2448-
true
2449-
} else {
2450-
if existing_signing_weight > signing_weight {
2451-
debug!("Will not store alternative copy of block {} ({}) with block hash {}, since it has less signing power", &block_id, &block.header.consensus_hash, &block_hash);
2452-
} else {
2453-
debug!(
2454-
"Will not store duplicate copy of block {} ({}) with block hash {}",
2455-
&block_id, &block.header.consensus_hash, &block_hash
2456-
);
2457-
}
2458-
false
2459-
};
2460-
2461-
return Ok(ret);
2462-
}
2463-
24642394
/// Accept a Nakamoto block into the staging blocks DB.
24652395
/// Fails if:
24662396
/// * the public key cannot be recovered from the miner's signature
@@ -2470,17 +2400,17 @@ impl NakamotoChainState {
24702400
/// * we already have the block
24712401
/// Returns true if we stored the block; false if not.
24722402
pub fn accept_block(
2473-
config: &ChainstateConfig,
2403+
chainstate: &mut StacksChainState,
24742404
block: &NakamotoBlock,
24752405
db_handle: &mut SortitionHandleConn,
2476-
staging_db_tx: &NakamotoStagingBlocksTx,
2477-
headers_conn: &Connection,
24782406
reward_set: &RewardSet,
24792407
obtain_method: NakamotoBlockObtainMethod,
24802408
) -> Result<bool, ChainstateError> {
24812409
let block_id = block.block_id();
24822410
test_debug!("Consider Nakamoto block {block_id}");
2411+
let config = chainstate.config();
24832412
// do nothing if we already have this block
2413+
let (headers_conn, staging_db_tx) = chainstate.headers_conn_and_staging_tx_begin()?;
24842414
if Self::get_block_header(headers_conn, &block_id)?.is_some() {
24852415
debug!("Already have block {block_id}");
24862416
return Ok(false);
@@ -2555,13 +2485,13 @@ impl NakamotoChainState {
25552485
// same sortition history as `db_handle` (and thus it must be burn_attachable)
25562486
let burn_attachable = true;
25572487

2558-
let ret = Self::store_block_if_better(
2559-
staging_db_tx,
2488+
let ret = staging_db_tx.store_block_if_better(
25602489
block,
25612490
burn_attachable,
25622491
signing_weight,
25632492
obtain_method,
25642493
)?;
2494+
staging_db_tx.commit()?;
25652495
if ret {
25662496
test_debug!("Stored Nakamoto block {block_id}");
25672497
} else {

stackslib/src/chainstate/nakamoto/shadow.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -865,7 +865,7 @@ impl NakamotoStagingBlocksTx<'_> {
865865
// shadow blocks cannot be replaced
866866
let signing_weight = u32::MAX;
867867

868-
self.store_block(
868+
self.store_block_if_better(
869869
shadow_block,
870870
burn_attachable,
871871
signing_weight,

stackslib/src/chainstate/nakamoto/staging_blocks.rs

Lines changed: 79 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -590,8 +590,81 @@ impl NakamotoStagingBlocksTx<'_> {
590590
Ok(())
591591
}
592592

593+
/// Insert a Nakamoto block into the staging blocks DB.
594+
/// We only store a block in the following cases:
595+
///
596+
/// * No block with this block's sighash exists in the DB
597+
/// * A block with this block's sighash exists, AND
598+
/// * this block represents more signing power
599+
///
600+
/// If neither of the above is true, then this is a no-op.
601+
/// NOTE: This is intentionally the only public access into
602+
/// storing additional blocks inside the staging blocks DB
603+
pub fn store_block_if_better(
604+
&self,
605+
block: &NakamotoBlock,
606+
burn_attachable: bool,
607+
signing_weight: u32,
608+
obtain_method: NakamotoBlockObtainMethod,
609+
) -> Result<bool, ChainstateError> {
610+
let block_id = block.block_id();
611+
let block_hash = block.header.block_hash();
612+
let consensus_hash = block.header.consensus_hash.clone();
613+
614+
// case 1 -- no block with this sighash exists.
615+
if self.try_store_block_with_new_signer_sighash(
616+
block,
617+
burn_attachable,
618+
signing_weight,
619+
obtain_method,
620+
)? {
621+
debug!("Stored block with new sighash";
622+
"block_id" => %block_id,
623+
"block_hash" => %block_hash);
624+
return Ok(true);
625+
}
626+
627+
// case 2 -- the block exists. Consider replacing it, but only if its
628+
// signing weight is higher.
629+
let (existing_block_id, _processed, orphaned, existing_signing_weight) = self.conn().get_block_processed_and_signed_weight(&consensus_hash, &block_hash)?
630+
.ok_or_else(|| {
631+
// this should be unreachable -- there's no record of this block
632+
error!("Could not store block {block_id} ({consensus_hash}) with block hash {block_hash} -- no record of its processed status or signing weight!");
633+
ChainstateError::NoSuchBlockError
634+
})?;
635+
636+
if orphaned {
637+
// nothing to do
638+
debug!("Will not store alternative copy of block {block_id} ({consensus_hash}) with block hash {block_hash}, since a block with the same block hash was orphaned");
639+
return Ok(false);
640+
}
641+
642+
let ret = if existing_signing_weight < signing_weight {
643+
self.replace_block(block, signing_weight, obtain_method)?;
644+
debug!("Replaced block";
645+
"existing_block_id" => %existing_block_id,
646+
"block_id" => %block_id,
647+
"block_hash" => %block_hash,
648+
"existing_signing_weight" => existing_signing_weight,
649+
"signing_weight" => signing_weight);
650+
true
651+
} else {
652+
if existing_signing_weight > signing_weight {
653+
debug!("Will not store alternative copy of block {block_id} ({consensus_hash}) with block hash {block_hash}, since it has less signing power");
654+
} else {
655+
debug!(
656+
"Will not store duplicate copy of block {block_id} ({consensus_hash}) with block hash {block_hash}"
657+
);
658+
}
659+
false
660+
};
661+
662+
Ok(ret)
663+
}
664+
593665
/// Store a block into the staging DB.
594-
pub(crate) fn store_block(
666+
/// NOTE: This should not be made public
667+
fn store_block(
595668
&self,
596669
block: &NakamotoBlock,
597670
burn_attachable: bool,
@@ -665,7 +738,7 @@ impl NakamotoStagingBlocksTx<'_> {
665738

666739
/// Do we have a block with the given signer sighash?
667740
/// NOTE: the block hash and sighash are the same for Nakamoto blocks
668-
pub(crate) fn has_nakamoto_block_with_block_hash(
741+
fn has_nakamoto_block_with_block_hash(
669742
&self,
670743
consensus_hash: &ConsensusHash,
671744
block_hash: &BlockHeaderHash,
@@ -681,7 +754,8 @@ impl NakamotoStagingBlocksTx<'_> {
681754
/// NOTE: the block hash and sighash are the same for Nakamoto blocks, so this is equivalent to
682755
/// storing a new block.
683756
/// Return true if stored; false if not.
684-
pub(crate) fn try_store_block_with_new_signer_sighash(
757+
/// NOTE: This should not be made public
758+
fn try_store_block_with_new_signer_sighash(
685759
&self,
686760
block: &NakamotoBlock,
687761
burn_attachable: bool,
@@ -698,7 +772,8 @@ impl NakamotoStagingBlocksTx<'_> {
698772

699773
/// Replace an already-stored block with a newer copy with more signing
700774
/// power. Arguments will not be validated; the caller must do this.
701-
pub(crate) fn replace_block(
775+
/// NOTE: This should not be made public
776+
fn replace_block(
702777
&self,
703778
block: &NakamotoBlock,
704779
signing_weight: u32,

0 commit comments

Comments
 (0)