Skip to content

Commit

Permalink
Merge pull request #3693 from stacks-network/feat/2.3-traits-only-fix
Browse files Browse the repository at this point in the history
Epoch 2.3: Fix trait invocations via canonicalization
  • Loading branch information
kantai committed May 2, 2023
2 parents 225549c + 0c23a83 commit 6741e3c
Show file tree
Hide file tree
Showing 27 changed files with 990 additions and 39 deletions.
1 change: 1 addition & 0 deletions .github/workflows/bitcoin-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ jobs:
- tests::epoch_22::pox_2_unlock_all
- tests::epoch_22::disable_pox
- tests::epoch_22::test_pox_reorg_one_flap
- tests::epoch_23::trait_invocation_behavior
- tests::neon_integrations::bad_microblock_pubkey
steps:
- uses: actions/checkout@v2
Expand Down
2 changes: 1 addition & 1 deletion clarity/src/vm/analysis/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ pub fn run_analysis(
StacksEpochId::Epoch20 | StacksEpochId::Epoch2_05 => {
TypeChecker2_05::run_pass(&epoch, &mut contract_analysis, db)
}
StacksEpochId::Epoch21 | StacksEpochId::Epoch22 => {
StacksEpochId::Epoch21 | StacksEpochId::Epoch22 | StacksEpochId::Epoch23 => {
TypeChecker2_1::run_pass(&epoch, &mut contract_analysis, db)
}
StacksEpochId::Epoch10 => unreachable!("Epoch 1.0 is not a valid epoch for analysis"),
Expand Down
4 changes: 4 additions & 0 deletions clarity/src/vm/analysis/trait_checker/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ use stacks_common::types::StacksEpochId;
#[case(ClarityVersion::Clarity1, StacksEpochId::Epoch2_05)]
#[case(ClarityVersion::Clarity1, StacksEpochId::Epoch21)]
#[case(ClarityVersion::Clarity2, StacksEpochId::Epoch21)]
#[case(ClarityVersion::Clarity1, StacksEpochId::Epoch22)]
#[case(ClarityVersion::Clarity2, StacksEpochId::Epoch22)]
#[case(ClarityVersion::Clarity1, StacksEpochId::Epoch23)]
#[case(ClarityVersion::Clarity2, StacksEpochId::Epoch23)]
fn test_clarity_versions_trait_checker(
#[case] version: ClarityVersion,
#[case] epoch: StacksEpochId,
Expand Down
4 changes: 2 additions & 2 deletions clarity/src/vm/analysis/type_checker/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ impl FunctionType {
StacksEpochId::Epoch20 | StacksEpochId::Epoch2_05 => {
self.check_args_2_05(accounting, args)
}
StacksEpochId::Epoch21 | StacksEpochId::Epoch22 => {
StacksEpochId::Epoch21 | StacksEpochId::Epoch22 | StacksEpochId::Epoch23 => {
self.check_args_2_1(accounting, args, clarity_version)
}
StacksEpochId::Epoch10 => unreachable!("Epoch10 is not supported"),
Expand All @@ -68,7 +68,7 @@ impl FunctionType {
StacksEpochId::Epoch20 | StacksEpochId::Epoch2_05 => {
self.check_args_by_allowing_trait_cast_2_05(db, func_args)
}
StacksEpochId::Epoch21 | StacksEpochId::Epoch22 => {
StacksEpochId::Epoch21 | StacksEpochId::Epoch22 | StacksEpochId::Epoch23 => {
self.check_args_by_allowing_trait_cast_2_1(db, clarity_version, func_args)
}
StacksEpochId::Epoch10 => unreachable!("Epoch10 is not supported"),
Expand Down
4 changes: 4 additions & 0 deletions clarity/src/vm/analysis/type_checker/v2_1/tests/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,10 @@ pub mod contracts;
#[case(ClarityVersion::Clarity1, StacksEpochId::Epoch2_05)]
#[case(ClarityVersion::Clarity1, StacksEpochId::Epoch21)]
#[case(ClarityVersion::Clarity2, StacksEpochId::Epoch21)]
#[case(ClarityVersion::Clarity1, StacksEpochId::Epoch22)]
#[case(ClarityVersion::Clarity2, StacksEpochId::Epoch22)]
#[case(ClarityVersion::Clarity1, StacksEpochId::Epoch23)]
#[case(ClarityVersion::Clarity2, StacksEpochId::Epoch23)]
fn test_clarity_versions_type_checker(
#[case] version: ClarityVersion,
#[case] epoch: StacksEpochId,
Expand Down
4 changes: 3 additions & 1 deletion clarity/src/vm/costs/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -699,7 +699,9 @@ impl LimitedCostTracker {
}
StacksEpochId::Epoch20 => COSTS_1_NAME.to_string(),
StacksEpochId::Epoch2_05 => COSTS_2_NAME.to_string(),
StacksEpochId::Epoch21 | StacksEpochId::Epoch22 => COSTS_3_NAME.to_string(),
StacksEpochId::Epoch21 | StacksEpochId::Epoch22 | StacksEpochId::Epoch23 => {
COSTS_3_NAME.to_string()
}
}
}
}
Expand Down
2 changes: 2 additions & 0 deletions clarity/src/vm/functions/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ macro_rules! switch_on_global_epoch {
StacksEpochId::Epoch21 => $Epoch205Version(args, env, context),
// Note: We reuse 2.05 for 2.2.
StacksEpochId::Epoch22 => $Epoch205Version(args, env, context),
// Note: We reuse 2.05 for 2.3.
StacksEpochId::Epoch23 => $Epoch205Version(args, env, context),
}
}
};
Expand Down
4 changes: 4 additions & 0 deletions clarity/src/vm/tests/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ use crate::vm::ContractContext;
#[case(ClarityVersion::Clarity1, StacksEpochId::Epoch2_05)]
#[case(ClarityVersion::Clarity1, StacksEpochId::Epoch21)]
#[case(ClarityVersion::Clarity2, StacksEpochId::Epoch21)]
#[case(ClarityVersion::Clarity1, StacksEpochId::Epoch22)]
#[case(ClarityVersion::Clarity2, StacksEpochId::Epoch22)]
#[case(ClarityVersion::Clarity1, StacksEpochId::Epoch23)]
#[case(ClarityVersion::Clarity2, StacksEpochId::Epoch23)]
fn test_epoch_clarity_versions(#[case] version: ClarityVersion, #[case] epoch: StacksEpochId) {}

#[apply(test_epoch_clarity_versions)]
Expand Down
21 changes: 17 additions & 4 deletions clarity/src/vm/types/signatures.rs
Original file line number Diff line number Diff line change
Expand Up @@ -529,7 +529,9 @@ impl TypeSignature {
pub fn admits_type(&self, epoch: &StacksEpochId, other: &TypeSignature) -> Result<bool> {
match epoch {
StacksEpochId::Epoch20 | StacksEpochId::Epoch2_05 => self.admits_type_v2_0(&other),
StacksEpochId::Epoch21 | StacksEpochId::Epoch22 => self.admits_type_v2_1(other),
StacksEpochId::Epoch21 | StacksEpochId::Epoch22 | StacksEpochId::Epoch23 => {
self.admits_type_v2_1(other)
}
StacksEpochId::Epoch10 => unreachable!("epoch 1.0 not supported"),
}
}
Expand Down Expand Up @@ -722,8 +724,13 @@ impl TypeSignature {
/// types for the specified epoch.
pub fn canonicalize(&self, epoch: &StacksEpochId) -> TypeSignature {
match epoch {
StacksEpochId::Epoch21 => self.canonicalize_v2_1(),
_ => self.clone(),
StacksEpochId::Epoch10
| StacksEpochId::Epoch20
| StacksEpochId::Epoch2_05
// Epoch-2.2 had a regression in canonicalization, so it must be preserved here.
| StacksEpochId::Epoch22 => self.clone(),
// Note for future epochs: Epochs >= 2.3 should use the canonicalize_v2_1() routine
StacksEpochId::Epoch21 | StacksEpochId::Epoch23 => self.canonicalize_v2_1(),
}
}

Expand Down Expand Up @@ -1045,7 +1052,9 @@ impl TypeSignature {
) -> Result<TypeSignature> {
match epoch {
StacksEpochId::Epoch20 | StacksEpochId::Epoch2_05 => Self::least_supertype_v2_0(a, b),
StacksEpochId::Epoch21 | StacksEpochId::Epoch22 => Self::least_supertype_v2_1(a, b),
StacksEpochId::Epoch21 | StacksEpochId::Epoch22 | StacksEpochId::Epoch23 => {
Self::least_supertype_v2_1(a, b)
}
StacksEpochId::Epoch10 => unreachable!("Clarity 1.0 is not supported"),
}
}
Expand Down Expand Up @@ -1932,6 +1941,10 @@ mod test {
#[case(ClarityVersion::Clarity1, StacksEpochId::Epoch2_05)]
#[case(ClarityVersion::Clarity1, StacksEpochId::Epoch21)]
#[case(ClarityVersion::Clarity2, StacksEpochId::Epoch21)]
#[case(ClarityVersion::Clarity2, StacksEpochId::Epoch22)]
#[case(ClarityVersion::Clarity2, StacksEpochId::Epoch23)]
#[case(ClarityVersion::Clarity1, StacksEpochId::Epoch22)]
#[case(ClarityVersion::Clarity1, StacksEpochId::Epoch23)]
fn test_clarity_versions_signatures(
#[case] version: ClarityVersion,
#[case] epoch: StacksEpochId,
Expand Down
1 change: 1 addition & 0 deletions clarity/src/vm/version.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ impl ClarityVersion {
StacksEpochId::Epoch2_05 => ClarityVersion::Clarity1,
StacksEpochId::Epoch21 => ClarityVersion::Clarity2,
StacksEpochId::Epoch22 => ClarityVersion::Clarity2,
StacksEpochId::Epoch23 => ClarityVersion::Clarity2,
}
}
}
Expand Down
43 changes: 39 additions & 4 deletions src/chainstate/burn/db/sortdb.rs
Original file line number Diff line number Diff line change
Expand Up @@ -501,7 +501,7 @@ impl FromRow<StacksEpoch> for StacksEpoch {
}
}

pub const SORTITION_DB_VERSION: &'static str = "5";
pub const SORTITION_DB_VERSION: &'static str = "6";

const SORTITION_DB_INITIAL_SCHEMA: &'static [&'static str] = &[
r#"
Expand Down Expand Up @@ -707,6 +707,9 @@ const SORTITION_DB_SCHEMA_4: &'static [&'static str] = &[
const SORTITION_DB_SCHEMA_5: &'static [&'static str] = &[r#"
DELETE FROM epochs;"#];

const SORTITION_DB_SCHEMA_6: &'static [&'static str] = &[r#"
DELETE FROM epochs;"#];

// update this to add new indexes
const LAST_SORTITION_DB_INDEX: &'static str = "index_delegate_stx_burn_header_hash";

Expand Down Expand Up @@ -2663,6 +2666,7 @@ impl SortitionDB {
SortitionDB::apply_schema_3(&db_tx)?;
SortitionDB::apply_schema_4(&db_tx)?;
SortitionDB::apply_schema_5(&db_tx, epochs_ref)?;
SortitionDB::apply_schema_6(&db_tx, epochs_ref)?;

db_tx.instantiate_index()?;

Expand Down Expand Up @@ -2856,12 +2860,24 @@ impl SortitionDB {
|| version == "3"
|| version == "4"
|| version == "5"
|| version == "6"
}
StacksEpochId::Epoch2_05 => {
version == "2" || version == "3" || version == "4" || version == "5"
version == "2"
|| version == "3"
|| version == "4"
|| version == "5"
|| version == "6"
}
StacksEpochId::Epoch21 => {
version == "3" || version == "4" || version == "5" || version == "6"
}
StacksEpochId::Epoch22 => {
version == "3" || version == "4" || version == "5" || version == "6"
}
StacksEpochId::Epoch23 => {
version == "3" || version == "4" || version == "5" || version == "6"
}
StacksEpochId::Epoch21 => version == "3" || version == "4" || version == "5",
StacksEpochId::Epoch22 => version == "3" || version == "4" || version == "5",
}
}

Expand Down Expand Up @@ -2948,6 +2964,21 @@ impl SortitionDB {
Ok(())
}

fn apply_schema_6(tx: &DBTx, epochs: &[StacksEpoch]) -> Result<(), db_error> {
for sql_exec in SORTITION_DB_SCHEMA_6 {
tx.execute_batch(sql_exec)?;
}

SortitionDB::validate_and_insert_epochs(&tx, epochs)?;

tx.execute(
"INSERT OR REPLACE INTO db_config (version) VALUES (?1)",
&["6"],
)?;

Ok(())
}

fn check_schema_version_or_error(&mut self) -> Result<(), db_error> {
match SortitionDB::get_schema_version(self.conn()) {
Ok(Some(version)) => {
Expand Down Expand Up @@ -2990,6 +3021,10 @@ impl SortitionDB {
let tx = self.tx_begin()?;
SortitionDB::apply_schema_5(&tx.deref(), epochs)?;
tx.commit()?;
} else if version == "5" {
let tx = self.tx_begin()?;
SortitionDB::apply_schema_6(&tx.deref(), epochs)?;
tx.commit()?;
} else if version == expected_version {
return Ok(());
} else {
Expand Down
4 changes: 3 additions & 1 deletion src/chainstate/burn/operations/leader_block_commit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ use crate::chainstate::stacks::index::storage::TrieFileStorage;
use crate::chainstate::stacks::{StacksPrivateKey, StacksPublicKey};
use crate::codec::{write_next, Error as codec_error, StacksMessageCodec};
use crate::core::STACKS_EPOCH_2_2_MARKER;
use crate::core::STACKS_EPOCH_2_3_MARKER;
use crate::core::{StacksEpoch, StacksEpochId};
use crate::core::{STACKS_EPOCH_2_05_MARKER, STACKS_EPOCH_2_1_MARKER};
use crate::net::Error as net_error;
Expand Down Expand Up @@ -755,6 +756,7 @@ impl LeaderBlockCommitOp {
StacksEpochId::Epoch2_05 => self.check_epoch_commit_marker(STACKS_EPOCH_2_05_MARKER),
StacksEpochId::Epoch21 => self.check_epoch_commit_marker(STACKS_EPOCH_2_1_MARKER),
StacksEpochId::Epoch22 => self.check_epoch_commit_marker(STACKS_EPOCH_2_2_MARKER),
StacksEpochId::Epoch23 => self.check_epoch_commit_marker(STACKS_EPOCH_2_3_MARKER),
}
}

Expand All @@ -769,7 +771,7 @@ impl LeaderBlockCommitOp {
) -> Result<SortitionId, op_error> {
let tx_tip = tx.context.chain_tip.clone();
let intended_sortition = match epoch_id {
StacksEpochId::Epoch21 | StacksEpochId::Epoch22 => {
StacksEpochId::Epoch21 | StacksEpochId::Epoch22 | StacksEpochId::Epoch23 => {
// correct behavior -- uses *sortition height* to find the intended sortition ID
let sortition_height = self
.block_height
Expand Down
6 changes: 4 additions & 2 deletions src/chainstate/coordinator/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2991,8 +2991,10 @@ impl<
return Ok(Some(pox_anchor));
}
}
StacksEpochId::Epoch21 | StacksEpochId::Epoch22 => {
// 2.1 behavior: the anchor block must also be the
StacksEpochId::Epoch21
| StacksEpochId::Epoch22
| StacksEpochId::Epoch23 => {
// 2.1 and onward behavior: the anchor block must also be the
// heaviest-confirmed anchor block by BTC weight, and the highest
// such anchor block if there are multiple contenders.
if let Some(pox_anchor) =
Expand Down
4 changes: 3 additions & 1 deletion src/chainstate/stacks/boot/contract_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ lazy_static! {

pub struct ClarityTestSim {
marf: MarfedKV,
height: u64,
pub height: u64,
fork: u64,
/// This vec specifies the transitions for each epoch.
/// It is a list of heights at which the simulated chain transitions
Expand Down Expand Up @@ -379,6 +379,8 @@ impl BurnStateDB for TestSimBurnStateDB {
0 => StacksEpochId::Epoch20,
1 => StacksEpochId::Epoch2_05,
2 => StacksEpochId::Epoch21,
3 => StacksEpochId::Epoch22,
4 => StacksEpochId::Epoch23,
_ => panic!("Epoch unknown"),
};

Expand Down
41 changes: 34 additions & 7 deletions src/chainstate/stacks/db/blocks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4892,6 +4892,13 @@ impl StacksChainState {
receipts.append(&mut clarity_tx.block.initialize_epoch_2_2()?);
applied = true;
}
StacksEpochId::Epoch23 => {
receipts.push(clarity_tx.block.initialize_epoch_2_05()?);
receipts.append(&mut clarity_tx.block.initialize_epoch_2_1()?);
receipts.append(&mut clarity_tx.block.initialize_epoch_2_2()?);
receipts.append(&mut clarity_tx.block.initialize_epoch_2_3()?);
applied = true;
}
_ => {
panic!("Bad Stacks epoch transition; parent_epoch = {}, current_epoch = {}", &stacks_parent_epoch, &sortition_epoch.epoch_id);
}
Expand All @@ -4906,21 +4913,41 @@ impl StacksChainState {
receipts.append(&mut clarity_tx.block.initialize_epoch_2_2()?);
applied = true;
}
StacksEpochId::Epoch23 => {
receipts.append(&mut clarity_tx.block.initialize_epoch_2_1()?);
receipts.append(&mut clarity_tx.block.initialize_epoch_2_2()?);
receipts.append(&mut clarity_tx.block.initialize_epoch_2_3()?);
applied = true;
}
_ => {
panic!("Bad Stacks epoch transition; parent_epoch = {}, current_epoch = {}", &stacks_parent_epoch, &sortition_epoch.epoch_id);
}
},
StacksEpochId::Epoch21 => match sortition_epoch.epoch_id {
StacksEpochId::Epoch22 => {
receipts.append(&mut clarity_tx.block.initialize_epoch_2_2()?);
applied = true;
}
StacksEpochId::Epoch23 => {
receipts.append(&mut clarity_tx.block.initialize_epoch_2_2()?);
receipts.append(&mut clarity_tx.block.initialize_epoch_2_3()?);
applied = true;
}
_ => {
panic!("Bad Stacks epoch transition; parent_epoch = {}, current_epoch = {}", &stacks_parent_epoch, &sortition_epoch.epoch_id);
}
},
StacksEpochId::Epoch21 => {
StacksEpochId::Epoch22 => {
assert_eq!(
sortition_epoch.epoch_id,
StacksEpochId::Epoch22,
"Should only transition from Epoch21 to Epoch22"
StacksEpochId::Epoch23,
"Should only transition from Epoch22 to Epoch23"
);
receipts.append(&mut clarity_tx.block.initialize_epoch_2_2()?);
receipts.append(&mut clarity_tx.block.initialize_epoch_2_3()?);
applied = true;
}
StacksEpochId::Epoch22 => {
panic!("No defined transition from Epoch22 forward")
StacksEpochId::Epoch23 => {
panic!("No defined transition from Epoch23 forward")
}
}
}
Expand Down Expand Up @@ -5507,7 +5534,7 @@ impl StacksChainState {
// The DelegateStx bitcoin wire format does not exist before Epoch 2.1.
Ok((stack_ops, transfer_ops, vec![]))
}
StacksEpochId::Epoch21 | StacksEpochId::Epoch22 => {
StacksEpochId::Epoch21 | StacksEpochId::Epoch22 | StacksEpochId::Epoch23 => {
StacksChainState::get_stacking_and_transfer_and_delegate_burn_ops_v210(
chainstate_tx,
parent_index_hash,
Expand Down
1 change: 1 addition & 0 deletions src/chainstate/stacks/db/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,7 @@ impl DBConfig {
}
StacksEpochId::Epoch21 => self.version == "3" || self.version == "4",
StacksEpochId::Epoch22 => self.version == "3" || self.version == "4",
StacksEpochId::Epoch23 => self.version == "3" || self.version == "4",
}
}
}
Expand Down
1 change: 1 addition & 0 deletions src/chainstate/stacks/db/transactions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8356,6 +8356,7 @@ pub mod test {
StacksEpochId::Epoch2_05 => self.get_stacks_epoch(1),
StacksEpochId::Epoch21 => self.get_stacks_epoch(2),
StacksEpochId::Epoch22 => self.get_stacks_epoch(3),
StacksEpochId::Epoch23 => self.get_stacks_epoch(4),
}
}
fn get_pox_payout_addrs(
Expand Down
2 changes: 1 addition & 1 deletion src/chainstate/stacks/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ pub use stacks_common::address::{
C32_ADDRESS_VERSION_TESTNET_MULTISIG, C32_ADDRESS_VERSION_TESTNET_SINGLESIG,
};

pub const STACKS_BLOCK_VERSION: u8 = 5;
pub const STACKS_BLOCK_VERSION: u8 = 6;
pub const STACKS_BLOCK_VERSION_AST_PRECHECK_SIZE: u8 = 1;

pub const MAX_BLOCK_LEN: u32 = 2 * 1024 * 1024;
Expand Down
Loading

0 comments on commit 6741e3c

Please sign in to comment.