diff --git a/src/chia_dialect.rs b/src/chia_dialect.rs index d6222294..3bc5b290 100644 --- a/src/chia_dialect.rs +++ b/src/chia_dialect.rs @@ -73,6 +73,7 @@ impl Dialect for ChiaDialect { let flags = self.flags | match extension { OperatorSet::Default => 0, + OperatorSet::BLS => 0, OperatorSet::Keccak => ENABLE_KECCAK_OPS_OUTSIDE_GUARD, }; @@ -185,6 +186,7 @@ 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 eea313a2..3f024913 100644 --- a/src/dialect.rs +++ b/src/dialect.rs @@ -6,6 +6,7 @@ use crate::reduction::Response; #[derive(Clone, Copy, Eq, PartialEq)] pub enum OperatorSet { Default, + BLS, Keccak, // keccak256 operator } diff --git a/src/run_program.rs b/src/run_program.rs index 6785f5a6..c0c03f8e 100644 --- a/src/run_program.rs +++ b/src/run_program.rs @@ -1165,9 +1165,9 @@ mod tests { err: "softfork specified cost mismatch", }, - // without the flag to enable the BLS extensions, it's an unknown extension + // without the flag to enable the keccak extensions, it's an unknown extension RunProgramTest { - prg: "(softfork (q . 161) (q . 1) (q . (q . 42)) (q . ()))", + prg: "(softfork (q . 161) (q . 2) (q . (q . 42)) (q . ()))", args: "()", flags: NO_UNKNOWN_OPS, result: None, @@ -1175,6 +1175,57 @@ mod tests { err: "unknown softfork extension", }, + // coinid is also available under softfork extension 1 + RunProgramTest { + prg: "(softfork (q . 1432) (q . 1) (q a (i (= (coinid (q . 0x1234500000000000000000000000000000000000000000000000000000000000) (q . 0x6789abcdef000000000000000000000000000000000000000000000000000000) (q . 123456789)) (q . 0x69bfe81b052bfc6bd7f3fb9167fec61793175b897c16a35827f947d5cc98e4bc)) (q . 0) (q x)) (q . ())) (q . ()))", + args: "()", + flags: ENABLE_KECCAK, + result: Some("()"), + cost: 1513, + err: "", + }, + + // keccak256 is available when the softfork has activated + RunProgramTest { + prg: "(softfork (q . 1134) (q . 1) (q a (i (= (keccak256 (q . \"foobar\")) (q . 0x38d18acb67d25c8bb9942764b62f18e17054f66a817bd4295423adf9ed98873e)) (q . 0) (q x)) (q . ())) (q . ()))", + args: "()", + flags: ENABLE_KECCAK, + result: Some("()"), + cost: 1215, + err: "", + }, + // make sure keccak is actually executed, by comparing with the wrong output + RunProgramTest { + prg: "(softfork (q . 1134) (q . 1) (q a (i (= (keccak256 (q . \"foobar\")) (q . 0x58d18acb67d25c8bb9942764b62f18e17054f66a817bd4295423adf9ed98873e)) (q . 0) (q x)) (q . ())) (q . ()))", + args: "()", + flags: ENABLE_KECCAK, + result: None, + cost: 1215, + err: "clvm raise", + }, + // keccak is ignored when the softfork has not activated + RunProgramTest { + prg: "(softfork (q . 1134) (q . 1) (q a (i (= (keccak256 (q . \"foobar\")) (q . 0x58d18acb67d25c8bb9942764b62f18e17054f66a817bd4295423adf9ed98873e)) (q . 0) (q x)) (q . ())) (q . ()))", + args: "()", + flags: 0, + result: Some("()"), + cost: 1215, + err: "", + }, + + // === HARD FORK === + // new operators *outside* the softfork guard + + // keccak256 is available outside the guard with the appropriate flag + RunProgramTest { + prg: "(a (i (= (keccak256 (q . \"foobar\")) (q . 0x38d18acb67d25c8bb9942764b62f18e17054f66a817bd4295423adf9ed98873e)) (q . 0) (q x)) (q . ()))", + args: "()", + flags: ENABLE_KECCAK | ENABLE_KECCAK_OPS_OUTSIDE_GUARD, + result: Some("()"), + cost: 994, + err: "", + }, + // coinid extension // make sure we can execute the coinid operator under softfork 0 // this program raises an exception if the computed coin ID matches the @@ -1315,54 +1366,71 @@ mod tests { // 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, 0), - "clvm raise")] + #[case::coinid( + "(i (= (coinid (q . 0x1234500000000000000000000000000000000000000000000000000000000000) (q . 0x6789abcdef000000000000000000000000000000000000000000000000000000) (q . 123456789)) (q . 0x69bfe81b052bfc6bd7f3fb9167fec61793175b897c16a35827f947d5cc98e4bd)) (q . 0) (q x))", + (1432, 0, 0), + "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))", - (1432, 0, 0), - "")] + #[case::coinid( + "(i (= (coinid (q . 0x1234500000000000000000000000000000000000000000000000000000000000) (q . 0x6789abcdef000000000000000000000000000000000000000000000000000000) (q . 123456789)) (q . 0x69bfe81b052bfc6bd7f3fb9167fec61793175b897c16a35827f947d5cc98e4bc)) (q . 0) (q x))", + (1432, 0, 0), + "" + )] // modpow #[case::modpow( - "(i (= (modpow (q . 12345) (q . 6789) (q . 44444444444)) (q . 13456191581)) (q . 0) (q x))", - (18241, 0, 0), - "" -)] + "(i (= (modpow (q . 12345) (q . 6789) (q . 44444444444)) (q . 13456191581)) (q . 0) (q x))", + (18241, 0, 0), + "" + )] #[case::modpow( - "(i (= (modpow (q . 12345) (q . 6789) (q . 44444444444)) (q . 13456191582)) (q . 0) (q x))", - (18241, 0, 0), - "clvm raise" -)] + "(i (= (modpow (q . 12345) (q . 6789) (q . 44444444444)) (q . 13456191582)) (q . 0) (q x))", + (18241, 0, 0), + "clvm raise" + )] // mod #[case::modulus( - "(i (= (% (q . 80001) (q . 73)) (q . 66)) (q . 0) (q x))", - (1564, 0, 0), - "" -)] + "(i (= (% (q . 80001) (q . 73)) (q . 66)) (q . 0) (q x))", + (1564, 0, 0), + "" + )] #[case::modulus( - "(i (= (% (q . 80001) (q . 73)) (q . 67)) (q . 0) (q x))", - (1564, 0, 0), - "clvm raise" -)] + "(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))", - (706634, 0, 0), - "")] #[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))", - (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))", - (3981700, 0, 0), - "")] - #[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")] + "(i (= (g1_multiply (q . 0x97f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb) (q . 2)) (q . 0xa572cbea904d67468808c8eb50a9450c9721db309128012543902d0ac358a62ae28f75bb8f1c7c42c39a8c5529bf0f4e)) (q . 0) (q x))", + (706634, 0, 0), + "" + )] + #[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))", + (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))", + (3981700, 0, 0), + "" + )] + #[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" + )] #[case::keccak( "(i (= (keccak256 (q . \"foobar\")) (q . 0x38d18acb67d25c8bb9942764b62f18e17054f66a817bd4295423adf9ed98873e)) (q . 0) (q x))", (1134, 1, ENABLE_KECCAK_OPS_OUTSIDE_GUARD), @@ -1459,9 +1527,19 @@ mod tests { prg: outside_guard_prg.as_str(), args: "()", flags, - result: if err.is_empty() { Some("()") } else { None }, + result: if err.is_empty() && hard_fork_flag == 0 { + Some("()") + } else { + None + }, cost: cost - 140, - err, + err: if hard_fork_flag == 0 { + err + } else if mempool { + "unimplemented operator" + } else { + "clvm raise" + }, }; run_test_case(&t);