Skip to content

Commit ecaf4e2

Browse files
committed
Merge branch 'feat/clarity-5' into feat/increase-stack-depth
2 parents 076501f + 3d081c3 commit ecaf4e2

16 files changed

+845
-771
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
66
and this project adheres to the versioning scheme outlined in the [README.md](README.md).
77

8+
## [Unreleased]
9+
10+
### Added
11+
12+
- Setup for epoch 3.4 and Clarity version 5. Epoch 3.4 is currently set to activate at Bitcoin height 3,400,000 (very far in the future) until an activation height is selected. Clarity will activate with epoch 3.4.
13+
814
## [3.3.0.0.4]
915

1016
### Added

CONTRIBUTING.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -386,6 +386,25 @@ A test should be marked `#[ignore]` if:
386386
| `bitcoind` | tests requiring bitcoin daemon |
387387
| `flaky` | tests that exhibit flaky behavior |
388388

389+
- **Consensus tests use `insta` to record snapshots** and then compare results across runs to ensure that there are no accidental consensus changes.
390+
1. Install `insta`:
391+
392+
```bash
393+
cargo install cargo-insta
394+
```
395+
396+
2. Run snapshot tests with `insta`:
397+
398+
```bash
399+
cargo insta test -p stackslib --unreferenced=delete -- chainstate::tests --include-ignored
400+
```
401+
402+
3. Review/accept snapshot updates:
403+
404+
```bash
405+
cargo insta review
406+
```
407+
389408
## Formatting
390409

391410
PRs will be checked against `rustfmt` and will _fail_ if not properly formatted.

README.md

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -79,24 +79,6 @@ cargo nextest run
7979

8080
_On Windows, many tests will fail, mainly due to parallelism. To mitigate the issue you may need to run the tests individually._
8181

82-
**Install `insta` for snapshot tests:**
83-
84-
```bash
85-
cargo install cargo-insta
86-
```
87-
88-
**Run snapshot tests with `insta`:**
89-
90-
```bash
91-
cargo insta test
92-
```
93-
94-
**Review/accept snapshot updates:**
95-
96-
```bash
97-
cargo insta review
98-
```
99-
10082
## Run the testnet
10183

10284
You can observe the state machine in action locally by running:

clarity/src/vm/tests/proptest_utils.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,8 @@ use crate::vm::database::STXBalance;
4141
use crate::vm::errors::{ClarityEvalError, VmExecutionError};
4242
use crate::vm::{ClarityVersion, execute_with_parameters_and_call_in_global_context};
4343

44-
const DEFAULT_EPOCH: StacksEpochId = StacksEpochId::Epoch34;
45-
const DEFAULT_CLARITY_VERSION: ClarityVersion = ClarityVersion::Clarity5;
44+
const DEFAULT_EPOCH: StacksEpochId = StacksEpochId::latest();
45+
const DEFAULT_CLARITY_VERSION: ClarityVersion = ClarityVersion::latest();
4646
const INITIAL_BALANCE: u128 = 1_000_000_000;
4747
const UTF8_SNIPPET_MAX_SEGMENTS: usize = 16;
4848
const UTF8_SIMPLE_ESCAPES: [&str; 6] = ["\\\"", "\\\\", "\\n", "\\t", "\\r", "\\0"];

clarity/src/vm/version.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ impl fmt::Display for ClarityVersion {
3939
}
4040

4141
impl ClarityVersion {
42-
pub fn latest() -> ClarityVersion {
42+
pub const fn latest() -> ClarityVersion {
4343
ClarityVersion::Clarity4
4444
}
4545

stacks-node/src/tests/nakamoto_integrations.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14198,6 +14198,20 @@ fn test_epoch_3_3_activation() {
1419814198
naka_conf.node.pox_sync_sample_secs = 180;
1419914199
naka_conf.burnchain.max_rbf = 10_000_000;
1420014200

14201+
// Remove epochs beyond 3.3 for this test and extend epoch 3.3 to max height
14202+
{
14203+
let epochs = naka_conf
14204+
.burnchain
14205+
.epochs
14206+
.as_mut()
14207+
.expect("Missing burnchain epochs in config");
14208+
epochs.truncate_after(StacksEpochId::Epoch33);
14209+
epochs
14210+
.get_mut(StacksEpochId::Epoch33)
14211+
.expect("Missing epoch 3.3 in config")
14212+
.end_height = STACKS_EPOCH_MAX;
14213+
}
14214+
1420114215
let sender_signer_sk = Secp256k1PrivateKey::random();
1420214216
let sender_signer_addr = tests::to_addr(&sender_signer_sk);
1420314217
let mut signers = TestSigners::new(vec![sender_signer_sk.clone()]);

stacks-node/src/tests/signer/v0/mod.rs

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ use stacks::core::test_util::{
5151
insert_tx_in_mempool, make_contract_call, make_contract_publish,
5252
make_stacks_transfer_serialized,
5353
};
54-
use stacks::core::{StacksEpochId, CHAIN_ID_TESTNET};
54+
use stacks::core::{StacksEpochId, CHAIN_ID_TESTNET, STACKS_EPOCH_MAX};
5555
use stacks::libstackerdb::StackerDBChunkData;
5656
use stacks::net::api::getsigner::GetSignerResponse;
5757
use stacks::net::api::postblock_proposal::{
@@ -2803,14 +2803,10 @@ fn mock_sign_epoch_25() {
28032803
|node_config| {
28042804
node_config.miner.pre_nakamoto_mock_signing = true;
28052805
let epochs = node_config.burnchain.epochs.as_mut().unwrap();
2806+
epochs.truncate_after(StacksEpochId::Epoch30);
28062807
epochs[StacksEpochId::Epoch25].end_height = 251;
28072808
epochs[StacksEpochId::Epoch30].start_height = 251;
2808-
epochs[StacksEpochId::Epoch30].end_height = 265;
2809-
epochs[StacksEpochId::Epoch31].start_height = 265;
2810-
epochs[StacksEpochId::Epoch31].end_height = 285;
2811-
epochs[StacksEpochId::Epoch32].start_height = 285;
2812-
epochs[StacksEpochId::Epoch32].end_height = 305;
2813-
epochs[StacksEpochId::Epoch33].start_height = 305;
2809+
epochs[StacksEpochId::Epoch30].end_height = STACKS_EPOCH_MAX;
28142810
},
28152811
None,
28162812
None,
@@ -2925,14 +2921,10 @@ fn multiple_miners_mock_sign_epoch_25() {
29252921
|config| {
29262922
config.miner.pre_nakamoto_mock_signing = true;
29272923
let epochs = config.burnchain.epochs.as_mut().unwrap();
2924+
epochs.truncate_after(StacksEpochId::Epoch30);
29282925
epochs[StacksEpochId::Epoch25].end_height = 251;
29292926
epochs[StacksEpochId::Epoch30].start_height = 251;
2930-
epochs[StacksEpochId::Epoch30].end_height = 265;
2931-
epochs[StacksEpochId::Epoch31].start_height = 265;
2932-
epochs[StacksEpochId::Epoch31].end_height = 285;
2933-
epochs[StacksEpochId::Epoch32].start_height = 285;
2934-
epochs[StacksEpochId::Epoch32].end_height = 305;
2935-
epochs[StacksEpochId::Epoch33].start_height = 305;
2927+
epochs[StacksEpochId::Epoch30].end_height = STACKS_EPOCH_MAX;
29362928
},
29372929
|_| {},
29382930
);

stackslib/src/chainstate/nakamoto/coordinator/tests.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1073,6 +1073,8 @@ fn block_info_tests(use_primary_testnet: bool) {
10731073
ClarityVersion::Clarity2 => panic!("Clarity2 not supported in this test"),
10741074
ClarityVersion::Clarity3 => &clar3_contract_id,
10751075
ClarityVersion::Clarity4 => &clar4_contract_id,
1076+
// Later versions of Clarity are just running the same code as Clarity4 for now
1077+
// so it's not necessary to test them all individually here.
10761078
ClarityVersion::Clarity5 => panic!("Clarity5 not supported in this test"),
10771079
};
10781080
peer.with_db_state(|sortdb, chainstate, _, _| {

stackslib/src/chainstate/stacks/block.rs

Lines changed: 43 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -586,10 +586,17 @@ impl StacksBlock {
586586
}
587587
}
588588
if let TransactionPayload::SmartContract(_, ref version_opt) = &tx.payload {
589-
if version_opt.is_some() && epoch_id < StacksEpochId::Epoch21 {
590-
// not supported
591-
error!("Versioned smart contracts not supported before Stacks 2.1");
592-
return false;
589+
if let Some(version) = version_opt {
590+
if epoch_id < StacksEpochId::Epoch21 {
591+
// not supported
592+
error!("Versioned smart contracts not supported before Stacks 2.1"; "txid" => %tx.txid());
593+
return false;
594+
}
595+
if *version > ClarityVersion::default_for_epoch(epoch_id) {
596+
// not supported
597+
error!("Smart contract version {version} not supported in Epoch {epoch_id}"; "txid" => %tx.txid());
598+
return false;
599+
}
593600
}
594601
}
595602
if let TransactionPayload::TenureChange(..) = &tx.payload {
@@ -2075,6 +2082,38 @@ mod test {
20752082
);
20762083
}
20772084

2085+
#[test]
2086+
fn test_validate_transaction_static_epoch_rejects_future_clarity_version() {
2087+
let privk = StacksPrivateKey::random();
2088+
let origin_auth = TransactionAuth::Standard(
2089+
TransactionSpendingCondition::new_singlesig_p2pkh(StacksPublicKey::from_private(
2090+
&privk,
2091+
))
2092+
.unwrap(),
2093+
);
2094+
2095+
let tx_future_clarity = StacksTransaction::new(
2096+
TransactionVersion::Testnet,
2097+
origin_auth,
2098+
TransactionPayload::SmartContract(
2099+
TransactionSmartContract {
2100+
name: ContractName::try_from("future-clarity").unwrap(),
2101+
code_body: StacksString::from_str("(print \"hi\")").unwrap(),
2102+
},
2103+
Some(ClarityVersion::Clarity5),
2104+
),
2105+
);
2106+
2107+
assert!(!StacksBlock::validate_transaction_static_epoch(
2108+
&tx_future_clarity,
2109+
StacksEpochId::Epoch33
2110+
));
2111+
assert!(StacksBlock::validate_transaction_static_epoch(
2112+
&tx_future_clarity,
2113+
StacksEpochId::Epoch34
2114+
));
2115+
}
2116+
20782117
// TODO:
20792118
// * size limits
20802119
}

stackslib/src/chainstate/tests/snapshots/blockstack_lib__chainstate__tests__runtime_analysis_tests__runtime_check_error_kind_type_value_error_cdeploy.snap

Lines changed: 25 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ expression: result
124124
),
125125
)),
126126
Success(ExpectedBlockOutput(
127-
marf_hash: "d97ac1a81d416d203e31c2d2dd5df5799678570ae74437b634f81893655d9d7f",
127+
marf_hash: "81565262f144b87f9a1e18dff14d76c347aea39af8ae479eb4550685d19274eb",
128128
evaluated_epoch: Epoch34,
129129
transactions: [
130130
ExpectedTransactionOutput(
@@ -137,24 +137,24 @@ expression: result
137137
)),
138138
)),
139139
cost: ExecutionCost(
140-
write_length: 317,
140+
write_length: 61,
141141
write_count: 2,
142142
read_length: 1,
143143
read_count: 1,
144-
runtime: 21506,
144+
runtime: 11778,
145145
),
146146
),
147147
],
148148
total_block_cost: ExecutionCost(
149-
write_length: 317,
149+
write_length: 61,
150150
write_count: 2,
151151
read_length: 1,
152152
read_count: 1,
153-
runtime: 21506,
153+
runtime: 11778,
154154
),
155155
)),
156156
Success(ExpectedBlockOutput(
157-
marf_hash: "4c4d05e4f21378260832a34e3fdbbe2a41690d1d652146a116b2d59f9b6f7ee8",
157+
marf_hash: "f495dd8ffa77bc1eb67ac5f4ce1c6b33265052b0097268a8dfa0f85418476263",
158158
evaluated_epoch: Epoch34,
159159
transactions: [
160160
ExpectedTransactionOutput(
@@ -167,24 +167,24 @@ expression: result
167167
)),
168168
)),
169169
cost: ExecutionCost(
170-
write_length: 317,
170+
write_length: 61,
171171
write_count: 2,
172172
read_length: 1,
173173
read_count: 1,
174-
runtime: 21505,
174+
runtime: 11777,
175175
),
176176
),
177177
],
178178
total_block_cost: ExecutionCost(
179-
write_length: 317,
179+
write_length: 61,
180180
write_count: 2,
181181
read_length: 1,
182182
read_count: 1,
183-
runtime: 21505,
183+
runtime: 11777,
184184
),
185185
)),
186186
Success(ExpectedBlockOutput(
187-
marf_hash: "be35362c8a84c147289373b6d9760a3fc5099562cbe5d29d9a4399cac0126d99",
187+
marf_hash: "64469320b976be3dbc1c33ac4bdb30a79a1970913efda5d47d906e4f66b2cdd4",
188188
evaluated_epoch: Epoch34,
189189
transactions: [
190190
ExpectedTransactionOutput(
@@ -197,24 +197,24 @@ expression: result
197197
)),
198198
)),
199199
cost: ExecutionCost(
200-
write_length: 317,
200+
write_length: 61,
201201
write_count: 2,
202202
read_length: 1,
203203
read_count: 1,
204-
runtime: 21505,
204+
runtime: 11777,
205205
),
206206
),
207207
],
208208
total_block_cost: ExecutionCost(
209-
write_length: 317,
209+
write_length: 61,
210210
write_count: 2,
211211
read_length: 1,
212212
read_count: 1,
213-
runtime: 21505,
213+
runtime: 11777,
214214
),
215215
)),
216216
Success(ExpectedBlockOutput(
217-
marf_hash: "9fdaef3be137cc6eb023d8783478afb25ad4cbbc2b0063f54fa17a9f943c3c8c",
217+
marf_hash: "58b8bf7b6c0e7ab4c37bf5fc81d98bd0f67c7be14c8d89dfbb379472753c28c6",
218218
evaluated_epoch: Epoch34,
219219
transactions: [
220220
ExpectedTransactionOutput(
@@ -227,24 +227,24 @@ expression: result
227227
)),
228228
)),
229229
cost: ExecutionCost(
230-
write_length: 317,
230+
write_length: 61,
231231
write_count: 2,
232232
read_length: 1,
233233
read_count: 1,
234-
runtime: 21505,
234+
runtime: 11777,
235235
),
236236
),
237237
],
238238
total_block_cost: ExecutionCost(
239-
write_length: 317,
239+
write_length: 61,
240240
write_count: 2,
241241
read_length: 1,
242242
read_count: 1,
243-
runtime: 21505,
243+
runtime: 11777,
244244
),
245245
)),
246246
Success(ExpectedBlockOutput(
247-
marf_hash: "038c5362749db3ffdf88a56f598e823b02abd27c01c97552efe6102c1b280532",
247+
marf_hash: "ee614f81fb04d25637dd7347ec1146739236fcdc8ef76ee6bb6763d80e545281",
248248
evaluated_epoch: Epoch34,
249249
transactions: [
250250
ExpectedTransactionOutput(
@@ -257,20 +257,20 @@ expression: result
257257
)),
258258
)),
259259
cost: ExecutionCost(
260-
write_length: 317,
260+
write_length: 61,
261261
write_count: 2,
262262
read_length: 1,
263263
read_count: 1,
264-
runtime: 21505,
264+
runtime: 11777,
265265
),
266266
),
267267
],
268268
total_block_cost: ExecutionCost(
269-
write_length: 317,
269+
write_length: 61,
270270
write_count: 2,
271271
read_length: 1,
272272
read_count: 1,
273-
runtime: 21505,
273+
runtime: 11777,
274274
),
275275
)),
276276
]

0 commit comments

Comments
 (0)