diff --git a/src/chia_dialect.rs b/src/chia_dialect.rs index 1e48cb24..d6222294 100644 --- a/src/chia_dialect.rs +++ b/src/chia_dialect.rs @@ -68,15 +68,12 @@ impl Dialect for ChiaDialect { o: NodePtr, argument_list: NodePtr, max_cost: Cost, - _extension: OperatorSet, + extension: OperatorSet, ) -> Response { let flags = self.flags | match extension { OperatorSet::Default => 0, - OperatorSet::BLS => ENABLE_BLS_OPS_OUTSIDE_GUARD, - OperatorSet::Keccak => { - ENABLE_KECCAK_OPS_OUTSIDE_GUARD | ENABLE_BLS_OPS_OUTSIDE_GUARD - } + OperatorSet::Keccak => ENABLE_KECCAK_OPS_OUTSIDE_GUARD, }; let op_len = allocator.atom_len(o); @@ -188,7 +185,6 @@ impl Dialect for ChiaDialect { match ext { // The BLS extensions (and coinid) operators were brought into the // main operator set as part of the hard fork - 0 => OperatorSet::BLS, 1 if (self.flags & ENABLE_KECCAK) != 0 => OperatorSet::Keccak, // new extensions go here _ => OperatorSet::Default, diff --git a/src/dialect.rs b/src/dialect.rs index 7e662c54..eea313a2 100644 --- a/src/dialect.rs +++ b/src/dialect.rs @@ -6,8 +6,7 @@ use crate::reduction::Response; #[derive(Clone, Copy, Eq, PartialEq)] pub enum OperatorSet { Default, - BLS, // BLS and coinid operators - Keccak, // keccak256 operator (as well as BLS) + Keccak, // keccak256 operator } pub trait Dialect { diff --git a/src/run_program.rs b/src/run_program.rs index fd5e0f78..1117a886 100644 --- a/src/run_program.rs +++ b/src/run_program.rs @@ -549,14 +549,11 @@ pub fn run_program_with_counters<'a, D: Dialect>( mod tests { use super::*; - use crate::chia_dialect::NO_UNKNOWN_OPS; + use crate::chia_dialect::{ENABLE_KECCAK, ENABLE_KECCAK_OPS_OUTSIDE_GUARD, NO_UNKNOWN_OPS}; use crate::test_ops::parse_exp; use rstest::rstest; - #[cfg(test)] - use crate::chia_dialect::{ENABLE_KECCAK, ENABLE_KECCAK_OPS_OUTSIDE_GUARD, NO_UNKNOWN_OPS}; - struct RunProgramTest<'a> { prg: &'a str, args: &'a str, @@ -1302,267 +1299,254 @@ mod tests { run_test_case(t); } } -} - -#[cfg(test)] -fn check(res: (NodePtr, &str)) -> NodePtr { - assert_eq!(res.1, ""); - res.0 -} -#[cfg(test)] -fn run_test_case(t: &RunProgramTest) { - use crate::chia_dialect::ChiaDialect; - use crate::test_ops::node_eq; - let mut allocator = Allocator::new(); - - let program = check(parse_exp(&mut allocator, t.prg)); - let args = check(parse_exp(&mut allocator, t.args)); - let expected_result = &t.result.map(|v| check(parse_exp(&mut allocator, v))); - - let dialect = ChiaDialect::new(t.flags); - println!("prg: {}", t.prg); - match run_program(&mut allocator, &dialect, program, args, t.cost) { - Ok(Reduction(cost, prg_result)) => { - assert!(node_eq(&allocator, prg_result, expected_result.unwrap())); - assert_eq!(cost, t.cost); - - // now, run the same program again but with the cost limit 1 too low, to - // ensure it fails with the correct error - let expected_cost_exceeded = - run_program(&mut allocator, &dialect, program, args, t.cost - 1).unwrap_err(); - assert_eq!(expected_cost_exceeded.1, "cost exceeded"); - } - Err(err) => { - println!("FAILED: {}", err.1); - assert_eq!(err.1, t.err); - assert!(expected_result.is_none()); - } + fn check(res: (NodePtr, &str)) -> NodePtr { + assert_eq!(res.1, ""); + res.0 } -} -#[test] -fn test_run_program() { - for t in TEST_CASES { - run_test_case(t); + fn run_test_case(t: &RunProgramTest) { + use crate::chia_dialect::ChiaDialect; + use crate::test_ops::node_eq; + let mut allocator = Allocator::new(); + + let program = check(parse_exp(&mut allocator, t.prg)); + let args = check(parse_exp(&mut allocator, t.args)); + let expected_result = &t.result.map(|v| check(parse_exp(&mut allocator, v))); + + let dialect = ChiaDialect::new(t.flags); + println!("prg: {}", t.prg); + match run_program(&mut allocator, &dialect, program, args, t.cost) { + Ok(Reduction(cost, prg_result)) => { + assert!(node_eq(&allocator, prg_result, expected_result.unwrap())); + assert_eq!(cost, t.cost); + + // now, run the same program again but with the cost limit 1 too low, to + // ensure it fails with the correct error + let expected_cost_exceeded = + run_program(&mut allocator, &dialect, program, args, t.cost - 1).unwrap_err(); + assert_eq!(expected_cost_exceeded.1, "cost exceeded"); + } + Err(err) => { + println!("FAILED: {}", err.1); + assert_eq!(err.1, t.err); + assert!(expected_result.is_none()); + } + } } -} -#[cfg(test)] -use rstest::rstest; - -// the test cases for this test consists of: -// prg: the program to run inside the softfork guard -// cost: the expected cost of the program (the test adds the apply-operator) -// enabled: the softfork extension number that enables operator in prg -// hard_fork_flag: the flag that enables the program to be run outside the guard -// err: the expected error message, empty string means OK -// The test programs are carefully crafted such that they fail with "clvm raise" -// when run in consensus mode and the operators are unknown. e.g. (coinid ...) -// returns NIL in that case, which compares not equal to the coin ID, which -// raises the exception. -// This property is relied on for the non-mempool and fork-not-activated cases. -#[cfg(test)] -#[rstest] -// make sure we can execute the coinid operator under softfork 0 -// this program raises an exception if the computed coin ID matches the -// expected -#[case::coinid("(i (= (coinid (q . 0x1234500000000000000000000000000000000000000000000000000000000000) (q . 0x6789abcdef000000000000000000000000000000000000000000000000000000) (q . 123456789)) (q . 0x69bfe81b052bfc6bd7f3fb9167fec61793175b897c16a35827f947d5cc98e4bd)) (q . 0) (q x))", + // the test cases for this test consists of: + // prg: the program to run inside the softfork guard + // cost: the expected cost of the program (the test adds the apply-operator) + // enabled: the softfork extension number that enables operator in prg + // hard_fork_flag: the flag that enables the program to be run outside the guard + // err: the expected error message, empty string means OK + // The test programs are carefully crafted such that they fail with "clvm raise" + // when run in consensus mode and the operators are unknown. e.g. (coinid ...) + // returns NIL in that case, which compares not equal to the coin ID, which + // raises the exception. + // This property is relied on for the non-mempool and fork-not-activated cases. + #[rstest] + // make sure we can execute the coinid operator under softfork 0 + // this program raises an exception if the computed coin ID matches the + // expected + #[case::coinid("(i (= (coinid (q . 0x1234500000000000000000000000000000000000000000000000000000000000) (q . 0x6789abcdef000000000000000000000000000000000000000000000000000000) (q . 123456789)) (q . 0x69bfe81b052bfc6bd7f3fb9167fec61793175b897c16a35827f947d5cc98e4bd)) (q . 0) (q x))", (1432, 0, ENABLE_BLS_OPS_OUTSIDE_GUARD), "clvm raise")] -// also test the opposite. This program is the same as above but it raises -// if the coin ID is a mismatch -#[case::coinid("(i (= (coinid (q . 0x1234500000000000000000000000000000000000000000000000000000000000) (q . 0x6789abcdef000000000000000000000000000000000000000000000000000000) (q . 123456789)) (q . 0x69bfe81b052bfc6bd7f3fb9167fec61793175b897c16a35827f947d5cc98e4bc)) (q . 0) (q x))", + // also test the opposite. This program is the same as above but it raises + // if the coin ID is a mismatch + #[case::coinid("(i (= (coinid (q . 0x1234500000000000000000000000000000000000000000000000000000000000) (q . 0x6789abcdef000000000000000000000000000000000000000000000000000000) (q . 123456789)) (q . 0x69bfe81b052bfc6bd7f3fb9167fec61793175b897c16a35827f947d5cc98e4bc)) (q . 0) (q x))", (1432, 0, ENABLE_BLS_OPS_OUTSIDE_GUARD), "")] -// modpow -#[case::modpow( + // modpow + #[case::modpow( "(i (= (modpow (q . 12345) (q . 6789) (q . 44444444444)) (q . 13456191581)) (q . 0) (q x))", (18241, 0, 0), "" )] -#[case::modpow( + #[case::modpow( "(i (= (modpow (q . 12345) (q . 6789) (q . 44444444444)) (q . 13456191582)) (q . 0) (q x))", (18241, 0, 0), "clvm raise" )] -// mod -#[case::modulus( + // mod + #[case::modulus( "(i (= (% (q . 80001) (q . 73)) (q . 66)) (q . 0) (q x))", (1564, 0, 0), "" )] -#[case::modulus( + #[case::modulus( "(i (= (% (q . 80001) (q . 73)) (q . 67)) (q . 0) (q x))", (1564, 0, 0), "clvm raise" )] -// g1_multiply -#[case::g1_mul("(i (= (g1_multiply (q . 0x97f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb) (q . 2)) (q . 0xa572cbea904d67468808c8eb50a9450c9721db309128012543902d0ac358a62ae28f75bb8f1c7c42c39a8c5529bf0f4e)) (q . 0) (q x))", + // g1_multiply + #[case::g1_mul("(i (= (g1_multiply (q . 0x97f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb) (q . 2)) (q . 0xa572cbea904d67468808c8eb50a9450c9721db309128012543902d0ac358a62ae28f75bb8f1c7c42c39a8c5529bf0f4e)) (q . 0) (q x))", (706634, 0, 0), "")] -#[case::g1_mul( + #[case::g1_mul( "(i (= (g1_multiply (q . 0x97f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb) (q . 2)) (q . 0xa572cbea904d67468808c8eb50a9450c9721db309128012543902d0ac358a62ae28f75bb8f1c7c42c39a8c5529bf0f4f)) (q . 0) (q x))", (706634, 0, 0), "clvm raise")] -#[case::g1_neg("(i (= (g1_negate (q . 0xb7f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb)) (q . 0xb7f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb)) (q . 0) (q x))", (706634, 0, 0), "clvm raise")] -#[case::g1_neg("(i (= (g1_negate (q . 0xb2f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb)) (q . 0xb7f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb)) (q . 0) (q x))", + #[case::g1_neg("(i (= (g1_negate (q . 0xb7f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb)) (q . 0xb7f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb)) (q . 0) (q x))", (706634, 0, 0), "clvm raise")] + #[case::g1_neg("(i (= (g1_negate (q . 0xb2f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb)) (q . 0xb7f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb)) (q . 0) (q x))", (706634, 0, 0), "atom is not a valid G1 point")] -#[case::g2_add("(i (= (g2_add (q . 0x93e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb8) (q . 0x93e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb8)) (q . 0xaa4edef9c1ed7f729f520e47730a124fd70662a904ba1074728114d1031e1572c6c886f6b57ec72a6178288c47c335771638533957d540a9d2370f17cc7ed5863bc0b995b8825e0ee1ea1e1e4d00dbae81f14b0bf3611b78c952aacab827a053)) (q . 0) (q x))", + #[case::g2_add("(i (= (g2_add (q . 0x93e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb8) (q . 0x93e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb8)) (q . 0xaa4edef9c1ed7f729f520e47730a124fd70662a904ba1074728114d1031e1572c6c886f6b57ec72a6178288c47c335771638533957d540a9d2370f17cc7ed5863bc0b995b8825e0ee1ea1e1e4d00dbae81f14b0bf3611b78c952aacab827a053)) (q . 0) (q x))", (3981700, 0, 0), "")] -#[case::g2_add("(i (= (g2_add (q . 0x93e12b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb8) (q . 0x93e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb8)) (q . 0xaa4edef9c1ed7f729f520e47730a124fd70662a904ba1074728114d1031e1572c6c886f6b57ec72a6178288c47c335771638533957d540a9d2370f17cc7ed5863bc0b995b8825e0ee1ea1e1e4d00dbae81f14b0bf3611b78c952aacab827a053)) (q . 0) (q x))", + #[case::g2_add("(i (= (g2_add (q . 0x93e12b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb8) (q . 0x93e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb8)) (q . 0xaa4edef9c1ed7f729f520e47730a124fd70662a904ba1074728114d1031e1572c6c886f6b57ec72a6178288c47c335771638533957d540a9d2370f17cc7ed5863bc0b995b8825e0ee1ea1e1e4d00dbae81f14b0bf3611b78c952aacab827a053)) (q . 0) (q x))", (3981700, 0, 0), "atom is not a G2 point")] -fn test_softfork( - #[case] prg: &'static str, - #[case] fields: (u64, u8, u32), // cost, enabled, hard_fork_flag - #[case] err: &'static str, - #[values(0)] flags: u32, - #[values(false, true)] mempool: bool, - #[values(0, 1)] test_ext: u8, -) { - let (cost, enabled, hard_fork_flag) = fields; - let softfork_prg = - format!("(softfork (q . {cost}) (q . {test_ext}) (q . (a {prg} (q . 0))) (q . 0))"); - #[case::keccak( - "(i (= (keccak256 (q . \"foobar\")) (q . 0x38d18acb67d25c8bb9942764b62f18e17054f66a817bd4295423adf9ed98873e)) (q . 0) (q x))", - (1134, 1, ENABLE_KECCAK_OPS_OUTSIDE_GUARD), - "" -)] - #[case::keccak( - "(i (= (keccak256 (q . \"foobar\")) (q . 0x38d18acb67d25c8bb9942764b62f18e17054f66a817bd4295423adf9ed98873f)) (q . 0) (q x))", - (1134, 1, ENABLE_KECCAK_OPS_OUTSIDE_GUARD), - "clvm raise" -)] fn test_softfork( #[case] prg: &'static str, #[case] fields: (u64, u8, u32), // cost, enabled, hard_fork_flag #[case] err: &'static str, - #[values(0, ENABLE_KECCAK)] flags: u32, + #[values(0)] flags: u32, #[values(false, true)] mempool: bool, - #[values(0, 1, 2)] test_ext: u8, + #[values(0, 1)] test_ext: u8, ) { let (cost, enabled, hard_fork_flag) = fields; let softfork_prg = format!("(softfork (q . {cost}) (q . {test_ext}) (q . (a {prg} (q . 0))) (q . 0))"); + #[case::keccak( + "(i (= (keccak256 (q . \"foobar\")) (q . 0x38d18acb67d25c8bb9942764b62f18e17054f66a817bd4295423adf9ed98873e)) (q . 0) (q x))", + (1134, 1, ENABLE_KECCAK_OPS_OUTSIDE_GUARD), + "" +)] + #[case::keccak( + "(i (= (keccak256 (q . \"foobar\")) (q . 0x38d18acb67d25c8bb9942764b62f18e17054f66a817bd4295423adf9ed98873f)) (q . 0) (q x))", + (1134, 1, ENABLE_KECCAK_OPS_OUTSIDE_GUARD), + "clvm raise" +)] + fn test_softfork( + #[case] prg: &'static str, + #[case] fields: (u64, u8, u32), // cost, enabled, hard_fork_flag + #[case] err: &'static str, + #[values(0, ENABLE_KECCAK)] flags: u32, + #[values(false, true)] mempool: bool, + #[values(0, 1, 2)] test_ext: u8, + ) { + let (cost, enabled, hard_fork_flag) = fields; + let softfork_prg = + format!("(softfork (q . {cost}) (q . {test_ext}) (q . (a {prg} (q . 0))) (q . 0))"); + + let flags = flags | if mempool { NO_UNKNOWN_OPS } else { 0 }; + + // softfork extensions that are enabled + let ext_enabled = match test_ext { + 0 => true, + 1 => (flags & ENABLE_KECCAK) != 0, + _ => false, + }; - let flags = flags | if mempool { NO_UNKNOWN_OPS } else { 0 }; - - // softfork extensions that are enabled - let ext_enabled = match test_ext { - 0 => true, - 1 => (flags & ENABLE_KECCAK) != 0, - _ => false, - }; - - println!("mempool: {mempool} ext: {test_ext} flags: {flags}"); - let expect_err = match (ext_enabled as u8, (test_ext >= enabled) as u8) { - // the extension we're running has not been activated, and we're not - // running an extension that supports the operator - (0, 0) => { - if mempool { - "unimplemented operator" - } else { - "" + println!("mempool: {mempool} ext: {test_ext} flags: {flags}"); + let expect_err = match (ext_enabled as u8, (test_ext >= enabled) as u8) { + // the extension we're running has not been activated, and we're not + // running an extension that supports the operator + (0, 0) => { + if mempool { + "unimplemented operator" + } else { + "" + } } - } - // the softfork extension hasn't been activated yet. It's a failure in - // mempool mode but ignored in consensus mode - (0, 1) => { - if mempool { - "unknown softfork extension" - } else { - "" + // the softfork extension hasn't been activated yet. It's a failure in + // mempool mode but ignored in consensus mode + (0, 1) => { + if mempool { + "unknown softfork extension" + } else { + "" + } } - } - // the extension we're invoking has been enabled, but the operator is - // not part of this extension. In mempool mode it's an error, in - // consensus mode the operator is considered unknown, returning - // NIL/false. This in turn will make the return value test fail, and - // raise an exception. - (1, 0) => { - if mempool { - "unimplemented operator" - } else { - "clvm raise" + // the extension we're invoking has been enabled, but the operator is + // not part of this extension. In mempool mode it's an error, in + // consensus mode the operator is considered unknown, returning + // NIL/false. This in turn will make the return value test fail, and + // raise an exception. + (1, 0) => { + if mempool { + "unimplemented operator" + } else { + "clvm raise" + } } - } - // the extension we're running has been activated, and we're running an - // extension the operator is available in. The program is executed and - // we get the expected result. - (1, 1) => err, - _ => unreachable!(), - }; + // the extension we're running has been activated, and we're running an + // extension the operator is available in. The program is executed and + // we get the expected result. + (1, 1) => err, + _ => unreachable!(), + }; - println!("expect: {expect_err} cost: {cost}"); - let t = RunProgramTest { - prg: softfork_prg.as_str(), - args: "()", - flags, - result: if expect_err.is_empty() { - Some("()") - } else { - None - }, - cost: cost + 81, - err: expect_err, - }; + println!("expect: {expect_err} cost: {cost}"); + let t = RunProgramTest { + prg: softfork_prg.as_str(), + args: "()", + flags, + result: if expect_err.is_empty() { + Some("()") + } else { + None + }, + cost: cost + 81, + err: expect_err, + }; - run_test_case(&t); + run_test_case(&t); - // now test outside the guard (should fail unless hard_fork_flag is set). + // now test outside the guard (should fail unless hard_fork_flag is set). - let outside_guard_prg = format!("(a {prg} (q . 0))"); + let outside_guard_prg = format!("(a {prg} (q . 0))"); - // without the hard fork flag - println!("outside guard, no hard fork"); - let t = RunProgramTest { - prg: outside_guard_prg.as_str(), - args: "()", - flags, - result: if err.is_empty() { Some("()") } else { None }, - cost: cost - 140, - err, - }; - run_test_case(&t); - - // with the hard fork flag - println!("outside guard, hard fork activated"); - let t = RunProgramTest { - prg: outside_guard_prg.as_str(), - args: "()", - flags: flags | hard_fork_flag, - result: if err.is_empty() { Some("()") } else { None }, - cost: cost - 140, - err, - }; - run_test_case(&t); - } + // without the hard fork flag + println!("outside guard, no hard fork"); + let t = RunProgramTest { + prg: outside_guard_prg.as_str(), + args: "()", + flags, + result: if err.is_empty() { Some("()") } else { None }, + cost: cost - 140, + err, + }; + run_test_case(&t); + + // with the hard fork flag + println!("outside guard, hard fork activated"); + let t = RunProgramTest { + prg: outside_guard_prg.as_str(), + args: "()", + flags: flags | hard_fork_flag, + result: if err.is_empty() { Some("()") } else { None }, + cost: cost - 140, + err, + }; + run_test_case(&t); + } - #[cfg(feature = "counters")] - #[test] - fn test_counters() { - use crate::chia_dialect::ChiaDialect; + #[cfg(feature = "counters")] + #[test] + fn test_counters() { + use crate::chia_dialect::ChiaDialect; - let mut a = Allocator::new(); + let mut a = Allocator::new(); - let program = check(parse_exp(&mut a, "(a (q 2 2 (c 2 (c 5 (c 11 ())))) (c (q 2 (i (= 11 ()) (q 1 . 1) (q 18 5 (a 2 (c 2 (c 5 (c (- 11 (q . 1)) ())))))) 1) 1))")); - let args = check(parse_exp(&mut a, "(5033 1000)")); - let cost = 15073165; + let program = check(parse_exp(&mut a, "(a (q 2 2 (c 2 (c 5 (c 11 ())))) (c (q 2 (i (= 11 ()) (q 1 . 1) (q 18 5 (a 2 (c 2 (c 5 (c (- 11 (q . 1)) ())))))) 1) 1))")); + let args = check(parse_exp(&mut a, "(5033 1000)")); + let cost = 15073165; - let (counters, result) = - run_program_with_counters(&mut a, &ChiaDialect::new(0), program, args, cost); + let (counters, result) = + run_program_with_counters(&mut a, &ChiaDialect::new(0), program, args, cost); - assert_eq!(counters.val_stack_usage, 3015); - assert_eq!(counters.env_stack_usage, 1005); - assert_eq!(counters.op_stack_usage, 3014); - assert_eq!(counters.atom_count, 998); - assert_eq!(counters.small_atom_count, 1042); - assert_eq!(counters.pair_count, 22077); - assert_eq!(counters.heap_size, 769963); + assert_eq!(counters.val_stack_usage, 3015); + assert_eq!(counters.env_stack_usage, 1005); + assert_eq!(counters.op_stack_usage, 3014); + assert_eq!(counters.atom_count, 998); + assert_eq!(counters.small_atom_count, 1042); + assert_eq!(counters.pair_count, 22077); + assert_eq!(counters.heap_size, 769963); - assert_eq!(result.unwrap().0, cost); + assert_eq!(result.unwrap().0, cost); + } } }