Skip to content

Commit efb8225

Browse files
committed
Use CLI arg or default instead of hardcoded Clarity3
Pass user-specified Clarity version when provided, otherwise use default for CLI epoch.
1 parent f205ccc commit efb8225

File tree

1 file changed

+51
-26
lines changed

1 file changed

+51
-26
lines changed

stackslib/src/clarity_cli.rs

Lines changed: 51 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,6 @@ fn run_analysis_free<C: ClarityStorage>(
206206
save_contract: bool,
207207
clarity_version: ClarityVersion,
208208
) -> Result<ContractAnalysis, Box<(CheckError, LimitedCostTracker)>> {
209-
let clarity_version = ClarityVersion::default_for_epoch(DEFAULT_CLI_EPOCH);
210209
analysis::run_analysis(
211210
contract_identifier,
212211
expressions,
@@ -229,7 +228,6 @@ fn run_analysis<C: ClarityStorage>(
229228
clarity_version: ClarityVersion,
230229
) -> Result<ContractAnalysis, Box<(CheckError, LimitedCostTracker)>> {
231230
let mainnet = header_db.is_mainnet();
232-
let clarity_version = ClarityVersion::Clarity3;
233231
let cost_track = LimitedCostTracker::new(
234232
mainnet,
235233
default_chain_id(mainnet),
@@ -994,6 +992,22 @@ pub fn add_serialized_output(result: &mut serde_json::Value, value: Value) {
994992
result["output_serialized"] = serde_json::to_value(result_raw.as_str()).unwrap();
995993
}
996994

995+
/// Parse --clarity_version flag. Defaults to version for DEFAULT_CLI_EPOCH.
996+
fn parse_clarity_version_flag(argv: &mut Vec<String>) -> ClarityVersion {
997+
if let Ok(optarg) = consume_arg(argv, &["--clarity_version"], true) {
998+
if let Some(s) = optarg {
999+
friendly_expect(
1000+
s.parse::<ClarityVersion>(),
1001+
&format!("Invalid clarity version: {}", s),
1002+
)
1003+
} else {
1004+
ClarityVersion::default_for_epoch(DEFAULT_CLI_EPOCH)
1005+
}
1006+
} else {
1007+
ClarityVersion::default_for_epoch(DEFAULT_CLI_EPOCH)
1008+
}
1009+
}
1010+
9971011
/// Returns (process-exit-code, Option<json-output>)
9981012
pub fn invoke_command(invoked_by: &str, args: &[String]) -> (i32, Option<serde_json::Value>) {
9991013
if args.is_empty() {
@@ -1118,13 +1132,14 @@ pub fn invoke_command(invoked_by: &str, args: &[String]) -> (i32, Option<serde_j
11181132
"check" => {
11191133
if args.len() < 2 {
11201134
eprintln!(
1121-
"Usage: {} {} [program-file.clar] [--contract_id CONTRACT_ID] [--output_analysis] [--costs] [--testnet] (vm-state.db)",
1135+
"Usage: {} {} [program-file.clar] [--contract_id CONTRACT_ID] [--output_analysis] [--costs] [--testnet] [--clarity_version N] (vm-state.db)",
11221136
invoked_by, args[0]
11231137
);
11241138
panic_test!();
11251139
}
11261140

11271141
let mut argv = args.to_vec();
1142+
let clarity_version = parse_clarity_version_flag(&mut argv);
11281143
let contract_id = if let Ok(optarg) = consume_arg(&mut argv, &["--contract_id"], true) {
11291144
optarg
11301145
.map(|optarg_str| {
@@ -1172,9 +1187,8 @@ pub fn invoke_command(invoked_by: &str, args: &[String]) -> (i32, Option<serde_j
11721187
)
11731188
};
11741189

1175-
// TODO: Add --clarity_version as command line argument
11761190
let mut ast = friendly_expect(
1177-
parse(&contract_id, &content, ClarityVersion::Clarity3),
1191+
parse(&contract_id, &content, clarity_version),
11781192
"Failed to parse program",
11791193
);
11801194

@@ -1195,7 +1209,7 @@ pub fn invoke_command(invoked_by: &str, args: &[String]) -> (i32, Option<serde_j
11951209

11961210
let result = at_chaintip(&argv[2], marf_kv, |mut marf| {
11971211
let result =
1198-
run_analysis(&contract_id, &mut ast, &header_db, &mut marf, false);
1212+
run_analysis(&contract_id, &mut ast, &header_db, &mut marf, false, clarity_version);
11991213
(marf, result)
12001214
});
12011215
result
@@ -1210,6 +1224,7 @@ pub fn invoke_command(invoked_by: &str, args: &[String]) -> (i32, Option<serde_j
12101224
&header_db,
12111225
&mut analysis_marf,
12121226
false,
1227+
clarity_version,
12131228
)
12141229
}
12151230
};
@@ -1248,6 +1263,7 @@ pub fn invoke_command(invoked_by: &str, args: &[String]) -> (i32, Option<serde_j
12481263
}
12491264
"repl" => {
12501265
let mut argv = args.to_vec();
1266+
let clarity_version = parse_clarity_version_flag(&mut argv);
12511267
let mainnet = !matches!(consume_arg(&mut argv, &["--testnet"], false), Ok(Some(_)));
12521268
let mut marf = MemoryBackingStore::new();
12531269
let mut vm_env = OwnedEnvironment::new_free(
@@ -1258,7 +1274,7 @@ pub fn invoke_command(invoked_by: &str, args: &[String]) -> (i32, Option<serde_j
12581274
);
12591275
let placeholder_context = ContractContext::new(
12601276
QualifiedContractIdentifier::transient(),
1261-
ClarityVersion::Clarity2,
1277+
clarity_version
12621278
);
12631279
let mut exec_env = vm_env.get_exec_environment(None, None, &placeholder_context);
12641280
let mut analysis_marf = MemoryBackingStore::new();
@@ -1285,7 +1301,7 @@ pub fn invoke_command(invoked_by: &str, args: &[String]) -> (i32, Option<serde_j
12851301
}
12861302
};
12871303

1288-
let mut ast = match parse(&contract_id, &content, ClarityVersion::Clarity3) {
1304+
let mut ast = match parse(&contract_id, &content, clarity_version) {
12891305
Ok(val) => val,
12901306
Err(error) => {
12911307
println!("Parse error:\n{error}");
@@ -1298,7 +1314,7 @@ pub fn invoke_command(invoked_by: &str, args: &[String]) -> (i32, Option<serde_j
12981314
&mut ast,
12991315
&mut analysis_marf,
13001316
true,
1301-
ClarityVersion::Clarity3,
1317+
clarity_version,
13021318
) {
13031319
Ok(_) => (),
13041320
Err(boxed) => {
@@ -1320,6 +1336,8 @@ pub fn invoke_command(invoked_by: &str, args: &[String]) -> (i32, Option<serde_j
13201336
}
13211337
}
13221338
"eval_raw" => {
1339+
let mut argv = args.to_vec();
1340+
let clarity_version = parse_clarity_version_flag(&mut argv);
13231341
let content: String = {
13241342
let mut buffer = String::new();
13251343
friendly_expect(
@@ -1341,19 +1359,19 @@ pub fn invoke_command(invoked_by: &str, args: &[String]) -> (i32, Option<serde_j
13411359
let contract_id = QualifiedContractIdentifier::transient();
13421360
let placeholder_context = ContractContext::new(
13431361
QualifiedContractIdentifier::transient(),
1344-
ClarityVersion::Clarity3,
1362+
clarity_version
13451363
);
13461364

13471365
let mut ast = friendly_expect(
1348-
parse(&contract_id, &content, ClarityVersion::Clarity3),
1366+
parse(&contract_id, &content, clarity_version),
13491367
"Failed to parse program.",
13501368
);
13511369
match run_analysis_free(
13521370
&contract_id,
13531371
&mut ast,
13541372
&mut analysis_marf,
13551373
true,
1356-
ClarityVersion::Clarity3,
1374+
clarity_version,
13571375
) {
13581376
Ok(_) => {
13591377
let result = vm_env
@@ -1391,6 +1409,7 @@ pub fn invoke_command(invoked_by: &str, args: &[String]) -> (i32, Option<serde_j
13911409
}
13921410
"eval" => {
13931411
let mut argv = args.to_vec();
1412+
let clarity_version = parse_clarity_version_flag(&mut argv);
13941413

13951414
let costs = matches!(consume_arg(&mut argv, &["--costs"], false), Ok(Some(_)));
13961415

@@ -1405,7 +1424,7 @@ pub fn invoke_command(invoked_by: &str, args: &[String]) -> (i32, Option<serde_j
14051424
let mainnet = header_db.is_mainnet();
14061425
let placeholder_context = ContractContext::new(
14071426
QualifiedContractIdentifier::transient(),
1408-
ClarityVersion::Clarity3,
1427+
clarity_version
14091428
);
14101429

14111430
let (_, _, result_and_cost) = in_block(header_db, marf_kv, |header_db, mut marf| {
@@ -1446,12 +1465,17 @@ pub fn invoke_command(invoked_by: &str, args: &[String]) -> (i32, Option<serde_j
14461465
}
14471466
"eval_at_chaintip" => {
14481467
let mut argv = args.to_vec();
1468+
let clarity_version = parse_clarity_version_flag(&mut argv);
14491469

14501470
let costs = matches!(consume_arg(&mut argv, &["--costs"], false), Ok(Some(_)));
14511471
let coverage_folder = consume_arg(&mut argv, &["--c"], true).unwrap_or(None);
14521472

14531473
let evalInput = get_eval_input(invoked_by, &argv);
1454-
let vm_filename = if argv.len() == 3 { &argv[2] } else { &argv[3] };
1474+
let vm_filename = if argv.len() == 3 {
1475+
&argv[2].clone()
1476+
} else {
1477+
&argv[3].clone()
1478+
};
14551479
let header_db =
14561480
friendly_expect(CLIHeadersDB::resume(vm_filename), "Failed to open CLI DB");
14571481
let marf_kv = friendly_expect(
@@ -1462,7 +1486,7 @@ pub fn invoke_command(invoked_by: &str, args: &[String]) -> (i32, Option<serde_j
14621486
let mainnet = header_db.is_mainnet();
14631487
let placeholder_context = ContractContext::new(
14641488
QualifiedContractIdentifier::transient(),
1465-
ClarityVersion::Clarity3,
1489+
clarity_version
14661490
);
14671491
let mut coverage = if coverage_folder.is_some() {
14681492
Some(CoverageReporter::new())
@@ -1516,17 +1540,18 @@ pub fn invoke_command(invoked_by: &str, args: &[String]) -> (i32, Option<serde_j
15161540
}
15171541
"eval_at_block" => {
15181542
let mut argv = args.to_vec();
1543+
let clarity_version = parse_clarity_version_flag(&mut argv);
15191544

15201545
let costs = matches!(consume_arg(&mut argv, &["--costs"], false), Ok(Some(_)));
15211546

15221547
if argv.len() != 4 {
15231548
eprintln!(
1524-
"Usage: {} {} [--costs] [index-block-hash] [contract-identifier] [vm/clarity dir]",
1549+
"Usage: {} {} [--costs] [index-block-hash] [contract-identifier] [--clarity_version N] [vm/clarity dir]",
15251550
invoked_by, &argv[0]
15261551
);
15271552
panic_test!();
15281553
}
1529-
let chain_tip = &argv[1];
1554+
let chain_tip = &argv[1].clone();
15301555
let contract_identifier = friendly_expect(
15311556
QualifiedContractIdentifier::parse(&argv[2]),
15321557
"Failed to parse contract identifier.",
@@ -1550,7 +1575,7 @@ pub fn invoke_command(invoked_by: &str, args: &[String]) -> (i32, Option<serde_j
15501575
let mainnet = header_db.is_mainnet();
15511576
let placeholder_context = ContractContext::new(
15521577
QualifiedContractIdentifier::transient(),
1553-
ClarityVersion::Clarity3,
1578+
clarity_version
15541579
);
15551580
let result_and_cost = at_block(chain_tip, marf_kv, |mut marf| {
15561581
let result_and_cost =
@@ -1590,6 +1615,7 @@ pub fn invoke_command(invoked_by: &str, args: &[String]) -> (i32, Option<serde_j
15901615
}
15911616
"launch" => {
15921617
let mut argv = args.to_vec();
1618+
let clarity_version = parse_clarity_version_flag(&mut argv);
15931619
let coverage_folder = consume_arg(&mut argv, &["--c"], true).unwrap_or(None);
15941620

15951621
let costs = matches!(consume_arg(&mut argv, &["--costs"], false), Ok(Some(_)));
@@ -1601,13 +1627,13 @@ pub fn invoke_command(invoked_by: &str, args: &[String]) -> (i32, Option<serde_j
16011627

16021628
if argv.len() < 4 {
16031629
eprintln!(
1604-
"Usage: {} {} [--costs] [--assets] [--output_analysis] [contract-identifier] [contract-definition.clar] [vm-state.db]",
1630+
"Usage: {} {} [--costs] [--assets] [--output_analysis] [contract-identifier] [contract-definition.clar] [--clarity_version N] [vm-state.db]",
16051631
invoked_by, argv[0]
16061632
);
16071633
panic_test!();
16081634
}
16091635

1610-
let vm_filename = &argv[3];
1636+
let vm_filename = &argv[3].clone();
16111637
let contract_src_file = &args[2];
16121638
let contract_identifier = friendly_expect(
16131639
QualifiedContractIdentifier::parse(&argv[1]),
@@ -1619,12 +1645,11 @@ pub fn invoke_command(invoked_by: &str, args: &[String]) -> (i32, Option<serde_j
16191645
&format!("Error reading file: {}", contract_src_file),
16201646
);
16211647

1622-
// TODO: Add --clarity_version as command line argument
16231648
let mut ast = friendly_expect(
16241649
parse(
16251650
&contract_identifier,
16261651
&contract_content,
1627-
ClarityVersion::Clarity3,
1652+
clarity_version
16281653
),
16291654
"Failed to parse program.",
16301655
);
@@ -1660,7 +1685,7 @@ pub fn invoke_command(invoked_by: &str, args: &[String]) -> (i32, Option<serde_j
16601685
let (_, _, analysis_result_and_cost) =
16611686
in_block(header_db, marf_kv, |header_db, mut marf| {
16621687
let analysis_result =
1663-
run_analysis(&contract_identifier, &mut ast, &header_db, &mut marf, true);
1688+
run_analysis(&contract_identifier, &mut ast, &header_db, &mut marf, true, clarity_version);
16641689
match analysis_result {
16651690
Err(e) => (header_db, marf, Err(e)),
16661691
Ok(analysis) => {
@@ -1672,7 +1697,7 @@ pub fn invoke_command(invoked_by: &str, args: &[String]) -> (i32, Option<serde_j
16721697
|vm_env| {
16731698
vm_env.initialize_versioned_contract(
16741699
contract_identifier,
1675-
ClarityVersion::Clarity3,
1700+
clarity_version,
16761701
&contract_content,
16771702
None,
16781703
)
@@ -1733,13 +1758,14 @@ pub fn invoke_command(invoked_by: &str, args: &[String]) -> (i32, Option<serde_j
17331758
}
17341759
"execute" => {
17351760
let mut argv = args.to_vec();
1761+
let clarity_version = parse_clarity_version_flag(&mut argv);
17361762
let coverage_folder = consume_arg(&mut argv, &["--c"], true).unwrap_or(None);
17371763

17381764
let costs = matches!(consume_arg(&mut argv, &["--costs"], false), Ok(Some(_)));
17391765
let assets = matches!(consume_arg(&mut argv, &["--assets"], false), Ok(Some(_)));
17401766

17411767
if argv.len() < 5 {
1742-
eprintln!("Usage: {} {} [--costs] [--assets] [vm-state.db] [contract-identifier] [public-function-name] [sender-address] [args...]", invoked_by, argv[0]);
1768+
eprintln!("Usage: {} {} [--costs] [--assets] [--clarity_version N] [vm-state.db] [contract-identifier] [public-function-name] [sender-address] [args...]", invoked_by, argv[0]);
17431769
panic_test!();
17441770
}
17451771

@@ -1771,7 +1797,6 @@ pub fn invoke_command(invoked_by: &str, args: &[String]) -> (i32, Option<serde_j
17711797
let arguments: Vec<_> = argv[5..]
17721798
.iter()
17731799
.map(|argument| {
1774-
let clarity_version = ClarityVersion::Clarity3;
17751800
let argument_parsed = friendly_expect(
17761801
vm_execute(argument, clarity_version),
17771802
&format!("Error parsing argument \"{}\"", argument),

0 commit comments

Comments
 (0)