From 2edca108d3f1e66ace2a6e00d128d4b857178a64 Mon Sep 17 00:00:00 2001 From: Roshan Date: Wed, 5 Jun 2024 22:27:08 +0800 Subject: [PATCH 01/18] feat: add support for BSC --- Cargo.lock | 920 +++++++++++++++++++---- crates/interpreter/Cargo.toml | 1 + crates/precompile/Cargo.toml | 8 + crates/precompile/src/cometbft.rs | 85 ++- crates/precompile/src/double_sign.rs | 202 +++++ crates/precompile/src/iavl.rs | 208 +++++ crates/precompile/src/lib.rs | 166 ++++ crates/precompile/src/tendermint.rs | 55 ++ crates/precompile/src/tm_secp256k1.rs | 130 ++++ crates/primitives/Cargo.toml | 1 + crates/primitives/src/env.rs | 15 + crates/primitives/src/env/handler_cfg.rs | 34 + crates/primitives/src/specification.rs | 368 ++++++++- crates/revm/Cargo.toml | 1 + crates/revm/src/bsc.rs | 7 + crates/revm/src/bsc/handler_register.rs | 115 +++ crates/revm/src/builder.rs | 11 + crates/revm/src/handler.rs | 33 +- crates/revm/src/lib.rs | 2 + 19 files changed, 2177 insertions(+), 185 deletions(-) create mode 100644 crates/precompile/src/double_sign.rs create mode 100644 crates/precompile/src/iavl.rs create mode 100644 crates/precompile/src/tendermint.rs create mode 100644 crates/precompile/src/tm_secp256k1.rs create mode 100644 crates/revm/src/bsc.rs create mode 100644 crates/revm/src/bsc/handler_register.rs diff --git a/Cargo.lock b/Cargo.lock index d4d59295..1928f084 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -119,20 +119,20 @@ checksum = "db8aa973e647ec336810a9356af8aea787249c9d00b1525359f3db29a68d231b" dependencies = [ "alloy-rlp", "arbitrary", - "bytes", + "bytes 1.6.0", "cfg-if", "const-hex", "derive_arbitrary", "derive_more", "ethereum_ssz", - "getrandom", + "getrandom 0.2.15", "hex-literal", "itoa", - "k256", + "k256 0.13.3", "keccak-asm", "proptest", "proptest-derive", - "rand", + "rand 0.8.5", "ruint", "serde", "tiny-keccak", @@ -174,7 +174,7 @@ checksum = "b155716bab55763c95ba212806cf43d05bcc70e5f35b02bad20cf5ec7fe11fed" dependencies = [ "alloy-rlp-derive", "arrayvec", - "bytes", + "bytes 1.6.0", ] [[package]] @@ -256,8 +256,8 @@ dependencies = [ "alloy-primitives", "async-trait", "auto_impl", - "elliptic-curve", - "k256", + "elliptic-curve 0.13.8", + "k256 0.13.3", "thiserror", ] @@ -351,12 +351,36 @@ dependencies = [ "url", ] +[[package]] +name = "android-tzdata" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + [[package]] name = "anes" version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299" +[[package]] +name = "anomaly" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "550632e31568ae1a5f47998c3aa48563030fc49b9ec91913ca337cf64fbc5ccb" +dependencies = [ + "backtrace", +] + [[package]] name = "ansi_term" version = "0.12.1" @@ -549,7 +573,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1df2c09229cbc5a028b1d70e00fdb2acee28b1055dfb5ca73eea49c5a25c4e7c" dependencies = [ "num-traits", - "rand", + "rand 0.8.5", ] [[package]] @@ -559,7 +583,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94893f1e0c6eeab764ade8dc4c0db24caf4fe7cbbaafc0eba0a9030f447b5185" dependencies = [ "num-traits", - "rand", + "rand 0.8.5", ] [[package]] @@ -635,7 +659,7 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0aef7712851e524f35fbbb74fa6599c5cd8692056a1c36f9ca0d2001b670e7e5" dependencies = [ - "hex", + "hex 0.4.3", "num", ] @@ -741,17 +765,40 @@ dependencies = [ "serde", ] +[[package]] +name = "bitvec" +version = "0.18.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98fcd36dda4e17b7d7abc64cb549bf0201f4ab71e00700c798ca7e62ed3761fa" +dependencies = [ + "funty 1.1.0", + "radium 0.3.0", + "wyz 0.2.0", +] + [[package]] name = "bitvec" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" dependencies = [ - "funty", - "radium", + "funty 2.0.0", + "radium 0.7.0", "serde", "tap", - "wyz", + "wyz 0.5.1", +] + +[[package]] +name = "block-buffer" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0940dc441f31689269e10ac70eb1002a3a1d3ad1390e030043662eb7fe4688b" +dependencies = [ + "block-padding", + "byte-tools", + "byteorder", + "generic-array 0.12.4", ] [[package]] @@ -760,7 +807,7 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" dependencies = [ - "generic-array", + "generic-array 0.14.7", ] [[package]] @@ -769,7 +816,16 @@ version = "0.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" dependencies = [ - "generic-array", + "generic-array 0.14.7", +] + +[[package]] +name = "block-padding" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa79dedbb091f449f1f39e53edf88d5dbe95f895dae6135a8d7b881fb5af73f5" +dependencies = [ + "byte-tools", ] [[package]] @@ -784,7 +840,7 @@ dependencies = [ "ark-serialize 0.4.2", "ark-std 0.4.0", "hkdf", - "hmac", + "hmac 0.12.1", "libm", "sha2 0.10.8", ] @@ -801,6 +857,17 @@ dependencies = [ "zeroize", ] +[[package]] +name = "bstr" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba3569f383e8f1598449f1a423e72e99569137b47740b1da11ef19af3d5c3223" +dependencies = [ + "lazy_static", + "memchr", + "regex-automata 0.1.10", +] + [[package]] name = "bumpalo" version = "3.16.0" @@ -813,12 +880,24 @@ version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3ac9f8b63eca6fd385229b3675f6cc0dc5c8a5c8a54a59d4f52ffd670d87b0c" +[[package]] +name = "byte-tools" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7" + [[package]] name = "byteorder" version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" +[[package]] +name = "bytes" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e4cec68f03f32e44924783795810fa50a7035d8c8ebe78580ad7e6c703fba38" + [[package]] name = "bytes" version = "1.6.0" @@ -837,7 +916,7 @@ dependencies = [ "blst", "cc", "glob", - "hex", + "hex 0.4.3", "libc", "serde", ] @@ -866,7 +945,13 @@ version = "0.4.38" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" dependencies = [ + "android-tzdata", + "iana-time-zone", + "js-sys", "num-traits", + "serde", + "wasm-bindgen", + "windows-targets 0.52.5", ] [[package]] @@ -941,23 +1026,23 @@ name = "cometbft" version = "0.1.0-alpha.2" source = "git+https://github.com/bnb-chain/greenfield-cometbft-rs.git?rev=1282547#12825470f8b2df8e960e39a84ad4c9921492f512" dependencies = [ - "bytes", + "bytes 1.6.0", "cometbft-proto", "digest 0.10.7", - "ed25519", + "ed25519 2.2.3", "ed25519-consensus", "flex-error", "futures", "num-traits", "once_cell", - "prost", - "prost-types", + "prost 0.12.6", + "prost-types 0.12.6", "serde", "serde_bytes", "serde_json", "serde_repr", "sha2 0.10.8", - "signature", + "signature 2.2.0", "subtle", "subtle-encoding", "time", @@ -973,7 +1058,7 @@ dependencies = [ "flex-error", "serde", "serde_json", - "toml", + "toml 0.8.14", "url", ] @@ -1018,12 +1103,12 @@ name = "cometbft-proto" version = "0.1.0-alpha.2" source = "git+https://github.com/bnb-chain/greenfield-cometbft-rs.git?rev=1282547#12825470f8b2df8e960e39a84ad4c9921492f512" dependencies = [ - "bytes", + "bytes 1.6.0", "flex-error", - "num-derive", + "num-derive 0.4.2", "num-traits", - "prost", - "prost-types", + "prost 0.12.6", + "prost-types 0.12.6", "serde", "serde_bytes", "subtle-encoding", @@ -1036,16 +1121,16 @@ version = "0.1.0-alpha.2" source = "git+https://github.com/bnb-chain/greenfield-cometbft-rs.git?rev=1282547#12825470f8b2df8e960e39a84ad4c9921492f512" dependencies = [ "async-trait", - "bytes", + "bytes 1.6.0", "cometbft", "cometbft-config", "cometbft-proto", "flex-error", "futures", - "getrandom", + "getrandom 0.2.15", "peg", "pin-project", - "rand", + "rand 0.8.5", "reqwest 0.11.27", "semver 1.0.23", "serde", @@ -1083,11 +1168,17 @@ checksum = "70ff96486ccc291d36a958107caf2c0af8c78c0af7d31ae2f35ce055130de1a6" dependencies = [ "cfg-if", "cpufeatures", - "hex", + "hex 0.4.3", "proptest", "serde", ] +[[package]] +name = "const-oid" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f6b64db6932c7e49332728e3a6bd82c6b7e16016607d20923b537c3bc4c0d5f" + [[package]] name = "const-oid" version = "0.9.6" @@ -1218,8 +1309,8 @@ version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" dependencies = [ - "generic-array", - "rand_core", + "generic-array 0.14.7", + "rand_core 0.6.4", "subtle", "zeroize", ] @@ -1230,10 +1321,33 @@ version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" dependencies = [ - "generic-array", + "generic-array 0.14.7", "typenum", ] +[[package]] +name = "crypto-mac" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bff07008ec701e8028e2ceb8f83f0e4274ee62bd2dbdc4fefff2e9a91824081a" +dependencies = [ + "generic-array 0.14.7", + "subtle", +] + +[[package]] +name = "curve25519-dalek" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b9fdf9972b2bd6af2d913799d9ebc165ea4d2e65878e329d9c6b372c4491b61" +dependencies = [ + "byteorder", + "digest 0.9.0", + "rand_core 0.5.1", + "subtle", + "zeroize", +] + [[package]] name = "curve25519-dalek-ng" version = "4.1.1" @@ -1242,7 +1356,7 @@ checksum = "1c359b7249347e46fb28804470d071c921156ad62b3eef5d34e2ba867533dec8" dependencies = [ "byteorder", "digest 0.9.0", - "rand_core", + "rand_core 0.6.4", "subtle-ng", "zeroize", ] @@ -1266,13 +1380,22 @@ version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e8566979429cf69b49a5c740c60791108e86440e8be149bbea4fe54d2c32d6e2" +[[package]] +name = "der" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51f59c66c30bb7445c8320a5f9233e437e3572368099f25532a59054328899b4" +dependencies = [ + "const-oid 0.4.5", +] + [[package]] name = "der" version = "0.7.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f55bf8e7b65898637379c1b74eb1551107c8294ed26d855ceb9fd1a09cfc9bc0" dependencies = [ - "const-oid", + "const-oid 0.9.6", "zeroize", ] @@ -1320,13 +1443,22 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "digest" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5" +dependencies = [ + "generic-array 0.12.4", +] + [[package]] name = "digest" version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" dependencies = [ - "generic-array", + "generic-array 0.14.7", ] [[package]] @@ -1336,7 +1468,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ "block-buffer 0.10.4", - "const-oid", + "const-oid 0.9.6", "crypto-common", "subtle", ] @@ -1353,28 +1485,49 @@ version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0d6ef0072f8a535281e4876be788938b528e9a1d43900b82c2569af7da799125" +[[package]] +name = "ecdsa" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41fbdb4ff710acb4db8ca29f93b897529ea6d6a45626d5183b47e012aa6ae7e4" +dependencies = [ + "elliptic-curve 0.8.5", + "hmac 0.10.1", + "signature 1.2.2", +] + [[package]] name = "ecdsa" version = "0.16.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" dependencies = [ - "der", + "der 0.7.9", "digest 0.10.7", - "elliptic-curve", + "elliptic-curve 0.13.8", "rfc6979", - "signature", + "signature 2.2.0", "spki", ] +[[package]] +name = "ed25519" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4620d40f6d2601794401d6dd95a5cf69b6c157852539470eeda433a99b3c0efc" +dependencies = [ + "serde", + "signature 1.2.2", +] + [[package]] name = "ed25519" version = "2.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "115531babc129696a58c64a4fef0a8bf9e9698629fb97e9e40767d235cfbcd53" dependencies = [ - "pkcs8", - "signature", + "pkcs8 0.10.2", + "signature 2.2.0", ] [[package]] @@ -1384,8 +1537,23 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c8465edc8ee7436ffea81d21a019b16676ee3db267aa8d5a8d729581ecf998b" dependencies = [ "curve25519-dalek-ng", - "hex", - "rand_core", + "hex 0.4.3", + "rand_core 0.6.4", + "sha2 0.9.9", + "zeroize", +] + +[[package]] +name = "ed25519-dalek" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c762bae6dcaf24c4c84667b8579785430908723d5c889f469d76a41d59cc7a9d" +dependencies = [ + "curve25519-dalek", + "ed25519 1.2.0", + "rand 0.7.3", + "serde", + "serde_bytes", "sha2 0.9.9", "zeroize", ] @@ -1396,6 +1564,24 @@ version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3dca9240753cf90908d7e4aac30f630662b02aebaa1b58a3cadabdb23385b58b" +[[package]] +name = "elliptic-curve" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2db227e61a43a34915680bdda462ec0e212095518020a88a1f91acd16092c39" +dependencies = [ + "bitvec 0.18.5", + "digest 0.9.0", + "ff 0.8.0", + "funty 1.1.0", + "generic-array 0.14.7", + "group 0.8.0", + "pkcs8 0.3.3", + "rand_core 0.5.1", + "subtle", + "zeroize", +] + [[package]] name = "elliptic-curve" version = "0.13.8" @@ -1405,11 +1591,11 @@ dependencies = [ "base16ct", "crypto-bigint", "digest 0.10.7", - "ff", - "generic-array", - "group", - "pkcs8", - "rand_core", + "ff 0.13.0", + "generic-array 0.14.7", + "group 0.13.0", + "pkcs8 0.10.2", + "rand_core 0.6.4", "sec1", "subtle", "zeroize", @@ -1437,14 +1623,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2a3d8dc56e02f954cac8eb489772c552c473346fc34f67412bb6244fd647f7e4" dependencies = [ "base64 0.21.7", - "bytes", - "hex", - "k256", + "bytes 1.6.0", + "hex 0.4.3", + "k256 0.13.3", "log", - "rand", + "rand 0.8.5", "rlp", "serde", - "sha3", + "sha3 0.10.8", "zeroize", ] @@ -1482,12 +1668,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7413c5f74cc903ea37386a8965a936cbeb334bd270862fdece542c1b2dcbc898" dependencies = [ "ethereum-types", - "hex", + "hex 0.4.3", "once_cell", "regex", "serde", "serde_json", - "sha3", + "sha3 0.10.8", "thiserror", "uint", ] @@ -1557,16 +1743,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "82d80cc6ad30b14a48ab786523af33b37f28a8623fc06afd55324816ef18fb1f" dependencies = [ "arrayvec", - "bytes", + "bytes 1.6.0", "chrono", "const-hex", - "elliptic-curve", + "elliptic-curve 0.13.8", "ethabi", - "generic-array", - "k256", + "generic-array 0.14.7", + "k256 0.13.3", "num_enum", "open-fastrlp", - "rand", + "rand 0.8.5", "rlp", "serde", "serde_json", @@ -1586,7 +1772,7 @@ dependencies = [ "async-trait", "auto_impl", "base64 0.21.7", - "bytes", + "bytes 1.6.0", "const-hex", "enr", "ethers-core", @@ -1625,6 +1811,34 @@ dependencies = [ "once_cell", ] +[[package]] +name = "failure" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d32e9bd16cc02eae7db7ef620b392808b89f6a5e16bb3497d159c6b92a0f4f86" +dependencies = [ + "backtrace", + "failure_derive", +] + +[[package]] +name = "failure_derive" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa4da3c766cd7a0db8242e326e9e4e081edd567072893ed320008189715366a4" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", + "synstructure", +] + +[[package]] +name = "fake-simd" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed" + [[package]] name = "fastrand" version = "2.1.0" @@ -1639,7 +1853,18 @@ checksum = "139834ddba373bbdd213dffe02c8d110508dcf1726c2be27e8d1f7d7e1856418" dependencies = [ "arrayvec", "auto_impl", - "bytes", + "bytes 1.6.0", +] + +[[package]] +name = "ff" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01646e077d4ebda82b73f1bca002ea1e91561a77df2431a9e79729bcc31950ef" +dependencies = [ + "bitvec 0.18.5", + "rand_core 0.5.1", + "subtle", ] [[package]] @@ -1648,7 +1873,7 @@ version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" dependencies = [ - "rand_core", + "rand_core 0.6.4", "subtle", ] @@ -1660,7 +1885,7 @@ checksum = "835c052cb0c08c1acf6ffd71c022172e18723949c8282f2b9f27efbc51e64534" dependencies = [ "arbitrary", "byteorder", - "rand", + "rand 0.8.5", "rustc-hex", "static_assertions", ] @@ -1704,6 +1929,12 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "funty" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fed34cd105917e91daa4da6b3728c47b068749d6a62c59811f06ed2ac71d9da7" + [[package]] name = "funty" version = "2.0.0" @@ -1824,6 +2055,15 @@ dependencies = [ "byteorder", ] +[[package]] +name = "generic-array" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffdf9f34f1447443d37393cc6c2b8313aebddcd96906caf34e54c68d8e57d7bd" +dependencies = [ + "typenum", +] + [[package]] name = "generic-array" version = "0.14.7" @@ -1835,6 +2075,17 @@ dependencies = [ "zeroize", ] +[[package]] +name = "getrandom" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" +dependencies = [ + "cfg-if", + "libc", + "wasi 0.9.0+wasi-snapshot-preview1", +] + [[package]] name = "getrandom" version = "0.2.15" @@ -1844,7 +2095,7 @@ dependencies = [ "cfg-if", "js-sys", "libc", - "wasi", + "wasi 0.11.0+wasi-snapshot-preview1", "wasm-bindgen", ] @@ -1872,14 +2123,25 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "group" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc11f9f5fbf1943b48ae7c2bf6846e7d827a512d1be4f23af708f5ca5d01dde1" +dependencies = [ + "ff 0.8.0", + "rand_core 0.5.1", + "subtle", +] + [[package]] name = "group" version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" dependencies = [ - "ff", - "rand_core", + "ff 0.13.0", + "rand_core 0.6.4", "subtle", ] @@ -1889,7 +2151,7 @@ version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8" dependencies = [ - "bytes", + "bytes 1.6.0", "fnv", "futures-core", "futures-sink", @@ -1909,7 +2171,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fa82e28a107a8cc405f0839610bdc9b15f1e25ec7d696aa5cf173edbcb1486ab" dependencies = [ "atomic-waker", - "bytes", + "bytes 1.6.0", "fnv", "futures-core", "futures-sink", @@ -2008,6 +2270,12 @@ version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" +[[package]] +name = "hex" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "805026a5d0141ffc30abb3be3173848ad46a1b1664fe632428479619a3644d77" + [[package]] name = "hex" version = "0.4.3" @@ -2029,7 +2297,17 @@ version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7" dependencies = [ - "hmac", + "hmac 0.12.1", +] + +[[package]] +name = "hmac" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1441c6b1e930e2817404b5046f1f989899143a12bf92de603b69f4e0aee1e15" +dependencies = [ + "crypto-mac", + "digest 0.9.0", ] [[package]] @@ -2047,7 +2325,7 @@ version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" dependencies = [ - "bytes", + "bytes 1.6.0", "fnv", "itoa", ] @@ -2058,7 +2336,7 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258" dependencies = [ - "bytes", + "bytes 1.6.0", "fnv", "itoa", ] @@ -2069,7 +2347,7 @@ version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" dependencies = [ - "bytes", + "bytes 1.6.0", "http 0.2.12", "pin-project-lite", ] @@ -2080,7 +2358,7 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1cac85db508abc24a2e48553ba12a996e87244a0395ce011e62b37158745d643" dependencies = [ - "bytes", + "bytes 1.6.0", "http 1.1.0", ] @@ -2090,7 +2368,7 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0475f8b2ac86659c21b64320d5d653f9efe42acd2a4e560073ec61a155a34f1d" dependencies = [ - "bytes", + "bytes 1.6.0", "futures-core", "http 1.1.0", "http-body 1.0.0", @@ -2115,7 +2393,7 @@ version = "0.14.28" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bf96e135eb83a2a8ddf766e426a841d8ddd7449d5f00d34ea02b41d2f19eef80" dependencies = [ - "bytes", + "bytes 1.6.0", "futures-channel", "futures-core", "futures-util", @@ -2139,7 +2417,7 @@ version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fe575dd17d0862a9a33781c8c4696a55c320909004a67a00fb286ba8b1bc496d" dependencies = [ - "bytes", + "bytes 1.6.0", "futures-channel", "futures-util", "h2 0.4.5", @@ -2173,7 +2451,7 @@ version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0" dependencies = [ - "bytes", + "bytes 1.6.0", "http-body-util", "hyper 1.3.1", "hyper-util", @@ -2189,7 +2467,7 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ca38ef113da30126bbff9cd1705f9273e15d45498615d138b0c20279ac7a76aa" dependencies = [ - "bytes", + "bytes 1.6.0", "futures-channel", "futures-util", "http 1.1.0", @@ -2203,6 +2481,44 @@ dependencies = [ "tracing", ] +[[package]] +name = "iana-time-zone" +version = "0.1.60" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "wasm-bindgen", + "windows-core", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + +[[package]] +name = "ics23" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d020eb9116abc920452cb63aec8ff662483bf2b75199680046057389b1128988" +dependencies = [ + "bytes 0.5.6", + "failure", + "hex 0.4.3", + "prost 0.6.1", + "ripemd160 0.8.0", + "sha2 0.8.2", + "sha3 0.8.2", +] + [[package]] name = "idna" version = "0.5.0" @@ -2306,6 +2622,24 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "itertools" +version = "0.7.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d47946d458e94a1b7bcabbf6521ea7c037062c81f534615abcad76e84d4970d" +dependencies = [ + "either", +] + +[[package]] +name = "itertools" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f56a2d0bc861f9165be4eb3442afd3c236d8a98afd426f65d92324ae1091a484" +dependencies = [ + "either", +] + [[package]] name = "itertools" version = "0.10.5" @@ -2353,6 +2687,18 @@ dependencies = [ "simple_asn1", ] +[[package]] +name = "k256" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4476a0808212a9e81ce802eb1a0cfc60e73aea296553bacc0fac7e1268bc572a" +dependencies = [ + "cfg-if", + "ecdsa 0.10.2", + "elliptic-curve 0.8.5", + "sha2 0.9.9", +] + [[package]] name = "k256" version = "0.13.3" @@ -2360,11 +2706,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "956ff9b67e26e1a6a866cb758f12c6f8746208489e3e4a4b5580802f2f0a587b" dependencies = [ "cfg-if", - "ecdsa", - "elliptic-curve", + "ecdsa 0.16.9", + "elliptic-curve 0.13.8", "once_cell", "sha2 0.10.8", - "signature", + "signature 2.2.0", ] [[package]] @@ -2472,7 +2818,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" dependencies = [ "libc", - "wasi", + "wasi 0.11.0+wasi-snapshot-preview1", "windows-sys 0.48.0", ] @@ -2533,6 +2879,17 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" +[[package]] +name = "num-derive" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "876a53fff98e03a936a674b29568b0e605f06b29372c2489ff4de23f1949743d" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "num-derive" version = "0.4.2" @@ -2643,6 +3000,12 @@ version = "11.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575" +[[package]] +name = "opaque-debug" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c" + [[package]] name = "opaque-debug" version = "0.3.1" @@ -2657,7 +3020,7 @@ checksum = "786393f80485445794f6043fd3138854dd109cc6c4bd1a6383db304c9ce9b9ce" dependencies = [ "arrayvec", "auto_impl", - "bytes", + "bytes 1.6.0", "ethereum-types", "open-fastrlp-derive", ] @@ -2668,7 +3031,7 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "003b2be5c6c53c1cfeb0a238b8a1c3915cd410feb684457a36c10038f764bb1c" dependencies = [ - "bytes", + "bytes 1.6.0", "proc-macro2", "quote", "syn 1.0.109", @@ -2724,12 +3087,18 @@ version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c9863ad85fa8f4460f9c48cb909d38a0d689dba1f6f6988a5e3e0d31071bcd4b" dependencies = [ - "ecdsa", - "elliptic-curve", + "ecdsa 0.16.9", + "elliptic-curve 0.13.8", "primeorder", "sha2 0.10.8", ] +[[package]] +name = "parity-bytes" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16b56e3a2420138bdb970f84dfb9c774aea80fa0e7371549eedec0d80c209c67" + [[package]] name = "parity-scale-codec" version = "3.6.12" @@ -2737,7 +3106,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "306800abfa29c7f16596b5970a588435e3d5b3149683d00c12b699cc19f895ee" dependencies = [ "arrayvec", - "bitvec", + "bitvec 1.0.1", "byte-slice-cast", "impl-trait-for-tuples", "parity-scale-codec-derive", @@ -2855,7 +3224,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "48e4cc64c2ad9ebe670cb8fd69dd50ae301650392e81c05f9bfcb2d5bdbc24b0" dependencies = [ "phf_shared", - "rand", + "rand 0.8.5", ] [[package]] @@ -2912,13 +3281,22 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" +[[package]] +name = "pkcs8" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4839a901843f3942576e65857f0ebf2e190ef7024d3c62a94099ba3f819ad1d" +dependencies = [ + "der 0.1.0", +] + [[package]] name = "pkcs8" version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" dependencies = [ - "der", + "der 0.7.9", "spki", ] @@ -2989,7 +3367,7 @@ version = "0.13.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "353e1ca18966c16d9deb1c69278edbc5f194139612772bd9537af60ac231e1e6" dependencies = [ - "elliptic-curve", + "elliptic-curve 0.13.8", ] [[package]] @@ -3059,8 +3437,8 @@ dependencies = [ "bitflags 2.5.0", "lazy_static", "num-traits", - "rand", - "rand_chacha", + "rand 0.8.5", + "rand_chacha 0.3.1", "rand_xorshift", "regex-syntax", "rusty-fork", @@ -3079,14 +3457,61 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "prost" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce49aefe0a6144a45de32927c77bd2859a5f7677b55f220ae5b744e87389c212" +dependencies = [ + "bytes 0.5.6", + "prost-derive 0.6.1", +] + [[package]] name = "prost" version = "0.12.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "deb1435c188b76130da55f17a466d252ff7b1418b2ad3e037d127b94e3411f29" dependencies = [ - "bytes", - "prost-derive", + "bytes 1.6.0", + "prost-derive 0.12.6", +] + +[[package]] +name = "prost-amino" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6dda006a6c21ae45e261a5a756f2a3e5299722eedae2405f4747dd6a5b47556e" +dependencies = [ + "byteorder", + "bytes 0.5.6", +] + +[[package]] +name = "prost-amino-derive" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7bbb97577964b9ff334506e319a7628af460f59a6be1da592b5bdccb6a78e921" +dependencies = [ + "failure", + "itertools 0.7.11", + "proc-macro2", + "quote", + "sha2 0.9.9", + "syn 1.0.109", +] + +[[package]] +name = "prost-derive" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "537aa19b95acde10a12fec4301466386f757403de4cd4e5b4fa78fb5ecb18f72" +dependencies = [ + "anyhow", + "itertools 0.8.2", + "proc-macro2", + "quote", + "syn 1.0.109", ] [[package]] @@ -3102,13 +3527,23 @@ dependencies = [ "syn 2.0.66", ] +[[package]] +name = "prost-types" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1834f67c0697c001304b75be76f67add9c89742eda3a085ad8ee0bb38c3417aa" +dependencies = [ + "bytes 0.5.6", + "prost 0.6.1", +] + [[package]] name = "prost-types" version = "0.12.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9091c90b0a32608e984ff2fa4091273cbdd755d54935c51d520887f4a1dbd5b0" dependencies = [ - "prost", + "prost 0.12.6", ] [[package]] @@ -3126,12 +3561,31 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "radium" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "def50a86306165861203e7f84ecffbbdfdea79f0e51039b33de1e952358c47ac" + [[package]] name = "radium" version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" +[[package]] +name = "rand" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" +dependencies = [ + "getrandom 0.1.16", + "libc", + "rand_chacha 0.2.2", + "rand_core 0.5.1", + "rand_hc", +] + [[package]] name = "rand" version = "0.8.5" @@ -3139,8 +3593,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ "libc", - "rand_chacha", - "rand_core", + "rand_chacha 0.3.1", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_chacha" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" +dependencies = [ + "ppv-lite86", + "rand_core 0.5.1", ] [[package]] @@ -3150,7 +3614,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" dependencies = [ "ppv-lite86", - "rand_core", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_core" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" +dependencies = [ + "getrandom 0.1.16", ] [[package]] @@ -3159,7 +3632,16 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ - "getrandom", + "getrandom 0.2.15", +] + +[[package]] +name = "rand_hc" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" +dependencies = [ + "rand_core 0.5.1", ] [[package]] @@ -3168,7 +3650,7 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d25bf25ec5ae4a3f1b92f929810509a2f53d7dca2f50b794ff57e3face536c8f" dependencies = [ - "rand_core", + "rand_core 0.6.4", ] [[package]] @@ -3208,10 +3690,16 @@ checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c" dependencies = [ "aho-corasick", "memchr", - "regex-automata", + "regex-automata 0.4.6", "regex-syntax", ] +[[package]] +name = "regex-automata" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" + [[package]] name = "regex-automata" version = "0.4.6" @@ -3242,7 +3730,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd67538700a17451e7cba03ac727fb961abb7607553461627b97de0b89cf4a62" dependencies = [ "base64 0.21.7", - "bytes", + "bytes 1.6.0", "encoding_rs", "futures-core", "futures-util", @@ -3284,7 +3772,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "566cafdd92868e0939d3fb961bd0dc25fcfaaed179291093b3d43e6b3150ea10" dependencies = [ "base64 0.22.1", - "bytes", + "bytes 1.6.0", "encoding_rs", "futures-core", "futures-util", @@ -3361,6 +3849,8 @@ dependencies = [ name = "revm-precompile" version = "7.0.0" dependencies = [ + "alloy-primitives", + "alloy-rlp", "aurora-engine-modexp", "bls_on_arkworks", "blst", @@ -3371,11 +3861,12 @@ dependencies = [ "cometbft-proto", "criterion", "eyre", - "k256", + "k256 0.13.3", "once_cell", "p256", - "prost", - "rand", + "parity-bytes", + "prost 0.12.6", + "rand 0.8.5", "revm-primitives", "ripemd", "rstest", @@ -3385,6 +3876,7 @@ dependencies = [ "serde_json", "sha2 0.10.8", "substrate-bn", + "tendermint", ] [[package]] @@ -3394,14 +3886,14 @@ dependencies = [ "alloy-primitives", "auto_impl", "bitflags 2.5.0", - "bitvec", + "bitvec 1.0.1", "c-kzg", "cfg-if", "derive_more", "dyn-clone", "enumn", "hashbrown 0.14.5", - "hex", + "hex 0.4.3", "once_cell", "serde", ] @@ -3412,9 +3904,9 @@ version = "0.1.0" dependencies = [ "alloy-sol-macro", "alloy-sol-types", - "bytes", + "bytes 1.6.0", "eyre", - "hex", + "hex 0.4.3", "microbench", "regex", "revm", @@ -3427,9 +3919,9 @@ dependencies = [ "alloy-rlp", "hash-db", "hashbrown 0.14.5", - "hex", + "hex 0.4.3", "indicatif", - "k256", + "k256 0.13.3", "microbench", "plain_hasher", "revm", @@ -3447,7 +3939,7 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" dependencies = [ - "hmac", + "hmac 0.12.1", "subtle", ] @@ -3474,7 +3966,7 @@ checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" dependencies = [ "cc", "cfg-if", - "getrandom", + "getrandom 0.2.15", "libc", "spin 0.9.8", "untrusted 0.9.0", @@ -3490,13 +3982,35 @@ dependencies = [ "digest 0.10.7", ] +[[package]] +name = "ripemd160" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad5112e0dbbb87577bfbc56c42450235e3012ce336e29c5befd7807bd626da4a" +dependencies = [ + "block-buffer 0.7.3", + "digest 0.8.1", + "opaque-debug 0.2.3", +] + +[[package]] +name = "ripemd160" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2eca4ecc81b7f313189bf73ce724400a07da2a6dac19588b03c8bd76a2dcc251" +dependencies = [ + "block-buffer 0.9.0", + "digest 0.9.0", + "opaque-debug 0.3.1", +] + [[package]] name = "rlp" version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bb919243f34364b6bd2fc10ef797edbfa75f33c252e7998527479c6d6b47e1ec" dependencies = [ - "bytes", + "bytes 1.6.0", "rlp-derive", "rustc-hex", ] @@ -3551,14 +4065,14 @@ dependencies = [ "arbitrary", "ark-ff 0.3.0", "ark-ff 0.4.2", - "bytes", + "bytes 1.6.0", "fastrlp", "num-bigint", "num-traits", "parity-scale-codec", "primitive-types", "proptest", - "rand", + "rand 0.8.5", "rlp", "ruint-macro", "serde", @@ -3763,9 +4277,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" dependencies = [ "base16ct", - "der", - "generic-array", - "pkcs8", + "der 0.7.9", + "generic-array 0.14.7", + "pkcs8 0.10.2", "subtle", "zeroize", ] @@ -3776,7 +4290,7 @@ version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0e0cc0f1cf93f4969faf3ea1c7d8a9faed25918d96affa959720823dfe86d4f3" dependencies = [ - "rand", + "rand 0.8.5", "secp256k1-sys", ] @@ -3942,6 +4456,18 @@ dependencies = [ "digest 0.10.7", ] +[[package]] +name = "sha2" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a256f46ea78a0c0d9ff00077504903ac881a1dafdc20da66545699e7776b3e69" +dependencies = [ + "block-buffer 0.7.3", + "digest 0.8.1", + "fake-simd", + "opaque-debug 0.2.3", +] + [[package]] name = "sha2" version = "0.9.9" @@ -3952,7 +4478,7 @@ dependencies = [ "cfg-if", "cpufeatures", "digest 0.9.0", - "opaque-debug", + "opaque-debug 0.3.1", ] [[package]] @@ -3966,6 +4492,19 @@ dependencies = [ "digest 0.10.7", ] +[[package]] +name = "sha3" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd26bc0e7a2e3a7c959bc494caf58b72ee0c71d67704e9520f736ca7e4853ecf" +dependencies = [ + "block-buffer 0.7.3", + "byte-tools", + "digest 0.8.1", + "keccak", + "opaque-debug 0.2.3", +] + [[package]] name = "sha3" version = "0.10.8" @@ -3986,6 +4525,16 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "signature" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29f060a7d147e33490ec10da418795238fd7545bba241504d6b31a409f2e6210" +dependencies = [ + "digest 0.9.0", + "rand_core 0.5.1", +] + [[package]] name = "signature" version = "2.2.0" @@ -3993,7 +4542,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" dependencies = [ "digest 0.10.7", - "rand_core", + "rand_core 0.6.4", ] [[package]] @@ -4058,7 +4607,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" dependencies = [ "base64ct", - "der", + "der 0.7.9", ] [[package]] @@ -4128,15 +4677,15 @@ dependencies = [ "byteorder", "crunchy", "lazy_static", - "rand", + "rand 0.8.5", "rustc-hex", ] [[package]] name = "subtle" -version = "2.5.0" +version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" +checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" [[package]] name = "subtle-encoding" @@ -4193,6 +4742,18 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" +[[package]] +name = "synstructure" +version = "0.12.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", + "unicode-xid", +] + [[package]] name = "system-configuration" version = "0.5.1" @@ -4232,6 +4793,65 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "tendermint" +version = "0.17.0" +source = "git+https://github.com/forcodedancing/tendermint-rs-parlia?rev=10cfd14bac4cd4f1180a6670ea44edabfeda2519#10cfd14bac4cd4f1180a6670ea44edabfeda2519" +dependencies = [ + "anomaly", + "async-trait", + "bstr", + "byteorder", + "bytes 0.5.6", + "chrono", + "ed25519 1.2.0", + "ed25519-dalek", + "futures", + "hex 0.3.2", + "ics23", + "k256 0.7.3", + "num-traits", + "once_cell", + "parity-bytes", + "prost 0.6.1", + "prost-amino", + "prost-amino-derive", + "prost-types 0.6.1", + "ripemd160 0.9.1", + "serde", + "serde_bytes", + "serde_json", + "serde_repr", + "sha2 0.9.9", + "signature 1.2.2", + "subtle", + "subtle-encoding", + "tendermint-proto", + "thiserror", + "toml 0.5.11", + "zeroize", +] + +[[package]] +name = "tendermint-proto" +version = "0.17.0" +source = "git+https://github.com/forcodedancing/tendermint-rs-parlia?rev=10cfd14bac4cd4f1180a6670ea44edabfeda2519#10cfd14bac4cd4f1180a6670ea44edabfeda2519" +dependencies = [ + "anomaly", + "bytes 0.5.6", + "chrono", + "num-derive 0.3.3", + "num-traits", + "prost 0.6.1", + "prost-amino", + "prost-amino-derive", + "prost-types 0.6.1", + "serde", + "serde_bytes", + "subtle-encoding", + "thiserror", +] + [[package]] name = "textwrap" version = "0.11.0" @@ -4342,7 +4962,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1adbebffeca75fcfd058afa480fb6c0b81e165a0323f9c9d39c9697e37c46787" dependencies = [ "backtrace", - "bytes", + "bytes 1.6.0", "libc", "mio", "num_cpus", @@ -4416,13 +5036,22 @@ version = "0.7.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9cf6b47b3771c49ac75ad09a6162f53ad4b8088b76ac60e8ec1455b31a189fe1" dependencies = [ - "bytes", + "bytes 1.6.0", "futures-core", "futures-sink", "pin-project-lite", "tokio", ] +[[package]] +name = "toml" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234" +dependencies = [ + "serde", +] + [[package]] name = "toml" version = "0.8.14" @@ -4561,12 +5190,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9e3dac10fd62eaf6617d3a904ae222845979aec67c615d1c842b4002c7666fb9" dependencies = [ "byteorder", - "bytes", + "bytes 1.6.0", "data-encoding", "http 0.2.12", "httparse", "log", - "rand", + "rand 0.8.5", "rustls", "sha1", "thiserror", @@ -4595,7 +5224,7 @@ dependencies = [ "arbitrary", "byteorder", "crunchy", - "hex", + "hex 0.4.3", "static_assertions", ] @@ -4731,6 +5360,12 @@ dependencies = [ "try-lock", ] +[[package]] +name = "wasi" +version = "0.9.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" + [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" @@ -4850,6 +5485,15 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[package]] +name = "windows-core" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" +dependencies = [ + "windows-targets 0.52.5", +] + [[package]] name = "windows-sys" version = "0.48.0" @@ -5046,6 +5690,12 @@ dependencies = [ "web-sys", ] +[[package]] +name = "wyz" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85e60b0d1b5f99db2556934e21937020776a5d31520bf169e851ac44e6420214" + [[package]] name = "wyz" version = "0.5.1" diff --git a/crates/interpreter/Cargo.toml b/crates/interpreter/Cargo.toml index 87ecceb7..94d35693 100644 --- a/crates/interpreter/Cargo.toml +++ b/crates/interpreter/Cargo.toml @@ -55,6 +55,7 @@ asm-keccak = ["revm-primitives/asm-keccak"] portable = ["revm-primitives/portable"] parse = ["dep:paste", "dep:phf"] +bsc = ["revm-primitives/bsc"] optimism = ["revm-primitives/optimism"] # Optimism default handler enabled Optimism handler register by default in EvmBuilder. optimism-default-handler = [ diff --git a/crates/precompile/Cargo.toml b/crates/precompile/Cargo.toml index 158f4c94..77de5480 100644 --- a/crates/precompile/Cargo.toml +++ b/crates/precompile/Cargo.toml @@ -46,6 +46,13 @@ cometbft-proto = { git = "https://github.com/bnb-chain/greenfield-cometbft-rs.g cometbft-light-client = { git = "https://github.com/bnb-chain/greenfield-cometbft-rs.git", rev = "1282547" } prost = { version = "0.12.3" } bls_on_arkworks = "0.3.0" +tendermint = { git = "https://github.com/forcodedancing/tendermint-rs-parlia", rev = "10cfd14bac4cd4f1180a6670ea44edabfeda2519", features = ["secp256k1"] } +parity-bytes = { version = "0.1.2", default-features = false } +alloy-rlp = { version = "0.3", default-features = false, features = [ + "arrayvec", + "derive", +] } +alloy-primitives = {version = "0.7.0"} # p256verify precompile p256 = { version = "0.13.2", optional = true, default-features = false, features = ["ecdsa"] } @@ -76,6 +83,7 @@ std = [ hashbrown = ["revm-primitives/hashbrown"] asm-keccak = ["revm-primitives/asm-keccak"] +bsc = ["revm-primitives/bsc"] optimism = ["revm-primitives/optimism", "secp256r1"] # Optimism default handler enabled Optimism handler register by default in EvmBuilder. optimism-default-handler = [ diff --git a/crates/precompile/src/cometbft.rs b/crates/precompile/src/cometbft.rs index 2df72ec9..a4410d07 100644 --- a/crates/precompile/src/cometbft.rs +++ b/crates/precompile/src/cometbft.rs @@ -1,7 +1,5 @@ use crate::{Error, Precompile, PrecompileError, PrecompileResult, PrecompileWithAddress}; -use cometbft::vote::Power; -use cometbft::PublicKey; -use cometbft::{block::signed_header::SignedHeader, validator::Set}; +use cometbft::{block::signed_header::SignedHeader, validator::Set, vote::Power, PublicKey}; use cometbft_light_client::{ predicates::VerificationPredicates, types::{LightBlock, TrustThreshold}, @@ -14,15 +12,19 @@ use cometbft_light_client_verifier::{ use cometbft_proto::types::v1::LightBlock as TmLightBlock; use prost::Message; use revm_primitives::Bytes; -use std::borrow::ToOwned; -use std::string::String; -use std::vec::Vec; +use std::{borrow::ToOwned, string::String, vec::Vec}; pub(crate) const COMETBFT_LIGHT_BLOCK_VALIDATION: PrecompileWithAddress = PrecompileWithAddress( crate::u64_to_address(103), Precompile::Standard(cometbft_light_block_validation_run), ); +pub(crate) const COMETBFT_LIGHT_BLOCK_VALIDATION_BEFORE_HERTZ: PrecompileWithAddress = + PrecompileWithAddress( + crate::u64_to_address(103), + Precompile::Standard(cometbft_light_block_validation_run_before_hertz), + ); + const UINT64_TYPE_LENGTH: u64 = 8; const CONSENSUS_STATE_LENGTH_BYTES_LENGTH: u64 = 32; const VALIDATE_RESULT_METADATA_LENGTH: u64 = 32; @@ -46,6 +48,21 @@ const MAX_CONSENSUS_STATE_LENGTH: u64 = CHAIN_ID_LENGTH + 99 * SINGLE_VALIDATOR_BYTES_LENGTH; fn cometbft_light_block_validation_run(input: &Bytes, gas_limit: u64) -> PrecompileResult { + return cometbft_light_block_validation_run_inner(input, gas_limit, true); +} + +fn cometbft_light_block_validation_run_before_hertz( + input: &Bytes, + gas_limit: u64, +) -> PrecompileResult { + return cometbft_light_block_validation_run_inner(input, gas_limit, false); +} + +fn cometbft_light_block_validation_run_inner( + input: &Bytes, + gas_limit: u64, + is_hertz: bool, +) -> PrecompileResult { const COMETBFT_LIGHT_BLOCK_VALIDATION_BASE: u64 = 3_000; if COMETBFT_LIGHT_BLOCK_VALIDATION_BASE > gas_limit { @@ -62,10 +79,13 @@ fn cometbft_light_block_validation_run(input: &Bytes, gas_limit: u64) -> Precomp Err(e) => return Err(e), }; - let validator_set_changed = match consensus_state.apply_light_block(&light_block) { + let mut validator_set_changed = match consensus_state.apply_light_block(&light_block) { Ok(validator_set_changed) => validator_set_changed, Err(e) => return Err(e), }; + if !is_hertz { + validator_set_changed = false; + } let consensus_state_bytes = match consensus_state.encode() { Ok(cs) => cs, @@ -160,12 +180,7 @@ impl ConsensusState { next_validator_set_hash: Bytes, validators: ValidatorSet, ) -> Self { - Self { - chain_id, - height, - next_validator_set_hash, - validators, - } + Self { chain_id, height, next_validator_set_hash, validators } } fn apply_light_block(&mut self, light_block: &LightBlock) -> Result { @@ -231,12 +246,7 @@ impl ConsensusState { .as_bytes()); self.height = light_block.height().value(); self.next_validator_set_hash = Bytes::from( - light_block - .signed_header - .header() - .next_validators_hash - .as_bytes() - .to_vec(), + light_block.signed_header.header().next_validators_hash.as_bytes().to_vec(), ); self.validators = light_block.validators.clone(); @@ -304,7 +314,7 @@ impl ConsensusState { type DecodeConsensusStateResult = Result; /// input: /// | chainID | height | nextValidatorSetHash | [{validator pubkey, voting power, relayer address, relayer bls pubkey}] | -/// | 32 bytes | 8 bytes | 32 bytes | [{32 bytes, 8 bytes, 20 bytes, 48 bytes}] +/// | 32 bytes | 8 bytes | 32 bytes | [{32 bytes, 8 bytes, 20 bytes, 48 bytes}] fn decode_consensus_state(input: &Bytes) -> DecodeConsensusStateResult { let minimum_length = CHAIN_ID_LENGTH + HEIGHT_LENGTH + VALIDATOR_SET_HASH_LENGTH; let input_length = input.len() as u64; @@ -553,10 +563,7 @@ mod tests { cs.validators.validators()[0].relayer_address.as_bytes(), relayer_address.to_vec() ); - assert_eq!( - cs.validators.validators()[0].bls_key.as_bytes(), - bls_pub_key.to_vec() - ); + assert_eq!(cs.validators.validators()[0].bls_key.as_bytes(), bls_pub_key.to_vec()); } { let chain_id = "chain_9000-121".to_string(); @@ -577,9 +584,7 @@ mod tests { Bytes::from(hex!("d5e63aeee6e6fa122a6a23a6e0fca87701ba1541")).to_vec(), )); bls_pub_keys.push(Bytes::from(hex!("aa2d28cbcd1ea3a63479f6fb260a3d755853e6a78cfa6252584fee97b2ec84a9d572ee4a5d3bc1558bb98a4b370fb861"))); - relayer_addresses.push(Bytes::from(hex!( - "d5e63aeee6e6fa122a6a23a6e0fca87701ba1541" - ))); + relayer_addresses.push(Bytes::from(hex!("d5e63aeee6e6fa122a6a23a6e0fca87701ba1541"))); validators_info.push(Validator::new_with_bls_and_relayer( PublicKey::from_raw_ed25519(&hex!( "6b0b523ee91ad18a63d63f21e0c40a83ef15963f4260574ca5159fd90a1c5270" @@ -590,9 +595,7 @@ mod tests { Bytes::from(hex!("6fd1ceb5a48579f322605220d4325bd9ff90d5fa")).to_vec(), )); bls_pub_keys.push(Bytes::from(hex!("b31e74a881fc78681e3dfa440978d2b8be0708a1cbbca2c660866216975fdaf0e9038d9b7ccbf9731f43956dba7f2451"))); - relayer_addresses.push(Bytes::from(hex!( - "6fd1ceb5a48579f322605220d4325bd9ff90d5fa" - ))); + relayer_addresses.push(Bytes::from(hex!("6fd1ceb5a48579f322605220d4325bd9ff90d5fa"))); validators_info.push(Validator::new_with_bls_and_relayer( PublicKey::from_raw_ed25519(&hex!( "919606ae20bf5d248ee353821754bcdb456fd3950618fda3e32d3d0fb990eeda" @@ -603,9 +606,7 @@ mod tests { Bytes::from(hex!("97376a436bbf54e0f6949b57aa821a90a749920a")).to_vec(), )); bls_pub_keys.push(Bytes::from(hex!("b32979580ea04984a2be033599c20c7a0c9a8d121b57f94ee05f5eda5b36c38f6e354c89328b92cdd1de33b64d3a0867"))); - relayer_addresses.push(Bytes::from(hex!( - "97376a436bbf54e0f6949b57aa821a90a749920a" - ))); + relayer_addresses.push(Bytes::from(hex!("97376a436bbf54e0f6949b57aa821a90a749920a"))); let validator_set = ValidatorSet::without_proposer(validators_info); let cs_bytes = Bytes::from(hex!("636861696e5f393030302d3132310000000000000000000000000000000000000000000000000001a5f1af4874227f1cdbe5240259a365ad86484a4255bfd65e2a0222d733fcdbc320cc466ee9412ddd49e0fff04cdb41bade2b7622f08b6bdacac94d4de03bdb970000000000002710d5e63aeee6e6fa122a6a23a6e0fca87701ba1541aa2d28cbcd1ea3a63479f6fb260a3d755853e6a78cfa6252584fee97b2ec84a9d572ee4a5d3bc1558bb98a4b370fb8616b0b523ee91ad18a63d63f21e0c40a83ef15963f4260574ca5159fd90a1c527000000000000027106fd1ceb5a48579f322605220d4325bd9ff90d5fab31e74a881fc78681e3dfa440978d2b8be0708a1cbbca2c660866216975fdaf0e9038d9b7ccbf9731f43956dba7f2451919606ae20bf5d248ee353821754bcdb456fd3950618fda3e32d3d0fb990eeda000000000000271097376a436bbf54e0f6949b57aa821a90a749920ab32979580ea04984a2be033599c20c7a0c9a8d121b57f94ee05f5eda5b36c38f6e354c89328b92cdd1de33b64d3a0867")); let cs = match decode_consensus_state(&cs_bytes) { @@ -701,4 +702,22 @@ mod tests { } } } + + #[test] + fn test_cometbft_light_block_validate_before_hertz() { + let input = Bytes::from(hex!( + "000000000000000000000000000000000000000000000000000000000000018c677265656e6669656c645f393030302d3132310000000000000000000000000000000000000000013c350cd55b99dc6c2b7da9bef5410fbfb869fede858e7b95bf7ca294e228bb40e33f6e876d63791ebd05ff617a1b4f4ad1aa2ce65e3c3a9cdfb33e0ffa7e8423000000000098968015154514f68ce65a0d9eecc578c0ab12da0a2a28a0805521b5b7ae56eb3fb24555efbfe59e1622bfe9f7be8c9022e9b3f2442739c1ce870b9adee169afe60f674edd7c86451c5363d89052fde8351895eeea166ce5373c36e31b518ed191d0c599aa0f5b0000000000989680432f6c4908a9aa5f3444421f466b11645235c99b831b2a2de9e504d7ea299e52a202ce529808618eb3bfc0addf13d8c5f2df821d81e18f9bc61583510b322d067d46323b0a572635c06a049c0a2a929e3c8184a50cf6a8b95708c25834ade456f399015a0000000000989680864cb9828254d712f8e59b164fc6a9402dc4e6c59065e38cff24f5323c8c5da888a0f97e5ee4ba1e11b0674b0a0d06204c1dfa247c370cd4be3e799fc4f6f48d977ac7ca0aeb060adb030a02080b1213677265656e6669656c645f393030302d3132311802220c08b2d7f3a10610e8d2adb3032a480a20ec6ecb5db4ffb17fabe40c60ca7b8441e9c5d77585d0831186f3c37aa16e9c15122408011220a2ab9e1eb9ea52812f413526e424b326aff2f258a56e00d690db9f805b60fe7e32200f40aeff672e8309b7b0aefbb9a1ae3d4299b5c445b7d54e8ff398488467f0053a20e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b85542203c350cd55b99dc6c2b7da9bef5410fbfb869fede858e7b95bf7ca294e228bb404a203c350cd55b99dc6c2b7da9bef5410fbfb869fede858e7b95bf7ca294e228bb405220294d8fbd0b94b767a7eba9840f299a3586da7fe6b5dead3b7eecba193c400f935a20bc50557c12d7392b0d07d75df0b61232d48f86a74fdea6d1485d9be6317d268c6220e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b8556a20e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b85572146699336aa109d1beab3946198c8e59f3b2cbd92f7a4065e3cd89e315ca39d87dee92835b98f8b8ec0861d6d9bb2c60156df5d375b3ceb1fbe71af6a244907d62548a694165caa660fec7a9b4e7b9198191361c71be0b128a0308021a480a20726abd0fdbfb6f779b0483e6e4b4b6f12241f6ea2bf374233ab1a316692b6415122408011220159f10ff15a8b58fc67a92ffd7f33c8cd407d4ce81b04ca79177dfd00ca19a67226808021214050cff76cc632760ba9db796c046004c900967361a0c08b3d7f3a10610808cadba03224080713027ffb776a702d78fd0406205c629ba473e1f8d6af646190f6eb9262cd67d69be90d10e597b91e06d7298eb6fa4b8f1eb7752ebf352a1f51560294548042268080212146699336aa109d1beab3946198c8e59f3b2cbd92f1a0c08b3d7f3a10610b087c1c00322405e2ddb70acfe4904438be3d9f4206c0ace905ac4fc306a42cfc9e86268950a0fbfd6ec5f526d3e41a3ef52bf9f9f358e3cb4c3feac76c762fa3651c1244fe004226808021214c55765fd2d0570e869f6ac22e7f2916a35ea300d1a0c08b3d7f3a10610f0b3d492032240ca17898bd22232fc9374e1188636ee321a396444a5b1a79f7628e4a11f265734b2ab50caf21e8092c55d701248e82b2f011426cb35ba22043b497a6b4661930612a0050aa8010a14050cff76cc632760ba9db796c046004c9009673612220a20e33f6e876d63791ebd05ff617a1b4f4ad1aa2ce65e3c3a9cdfb33e0ffa7e84231880ade2042080a6bbf6ffffffffff012a30a0805521b5b7ae56eb3fb24555efbfe59e1622bfe9f7be8c9022e9b3f2442739c1ce870b9adee169afe60f674edd7c86321415154514f68ce65a0d9eecc578c0ab12da0a2a283a14ee7a2a6a44d427f6949eeb8f12ea9fbb2501da880aa2010a146699336aa109d1beab3946198c8e59f3b2cbd92f12220a20451c5363d89052fde8351895eeea166ce5373c36e31b518ed191d0c599aa0f5b1880ade2042080ade2042a30831b2a2de9e504d7ea299e52a202ce529808618eb3bfc0addf13d8c5f2df821d81e18f9bc61583510b322d067d46323b3214432f6c4908a9aa5f3444421f466b11645235c99b3a14a0a7769429468054e19059af4867da0a495567e50aa2010a14c55765fd2d0570e869f6ac22e7f2916a35ea300d12220a200a572635c06a049c0a2a929e3c8184a50cf6a8b95708c25834ade456f399015a1880ade2042080ade2042a309065e38cff24f5323c8c5da888a0f97e5ee4ba1e11b0674b0a0d06204c1dfa247c370cd4be3e799fc4f6f48d977ac7ca3214864cb9828254d712f8e59b164fc6a9402dc4e6c53a143139916d97df0c589312b89950b6ab9795f34d1a12a8010a14050cff76cc632760ba9db796c046004c9009673612220a20e33f6e876d63791ebd05ff617a1b4f4ad1aa2ce65e3c3a9cdfb33e0ffa7e84231880ade2042080a6bbf6ffffffffff012a30a0805521b5b7ae56eb3fb24555efbfe59e1622bfe9f7be8c9022e9b3f2442739c1ce870b9adee169afe60f674edd7c86321415154514f68ce65a0d9eecc578c0ab12da0a2a283a14ee7a2a6a44d427f6949eeb8f12ea9fbb2501da88" + )); + let except_output_after_hertz = Bytes::from(hex!( + "000000000000000000000000000000000000000000000000000000000000018c677265656e6669656c645f393030302d3132310000000000000000000000000000000000000000023c350cd55b99dc6c2b7da9bef5410fbfb869fede858e7b95bf7ca294e228bb40e33f6e876d63791ebd05ff617a1b4f4ad1aa2ce65e3c3a9cdfb33e0ffa7e8423000000000098968015154514f68ce65a0d9eecc578c0ab12da0a2a28a0805521b5b7ae56eb3fb24555efbfe59e1622bfe9f7be8c9022e9b3f2442739c1ce870b9adee169afe60f674edd7c86451c5363d89052fde8351895eeea166ce5373c36e31b518ed191d0c599aa0f5b0000000000989680432f6c4908a9aa5f3444421f466b11645235c99b831b2a2de9e504d7ea299e52a202ce529808618eb3bfc0addf13d8c5f2df821d81e18f9bc61583510b322d067d46323b0a572635c06a049c0a2a929e3c8184a50cf6a8b95708c25834ade456f399015a0000000000989680864cb9828254d712f8e59b164fc6a9402dc4e6c59065e38cff24f5323c8c5da888a0f97e5ee4ba1e11b0674b0a0d06204c1dfa247c370cd4be3e799fc4f6f48d977ac7ca" + )); + + let result = cometbft_light_block_validation_run_before_hertz(&input, 100_000); + let (gas_used, output) = match result { + Ok(result) => result, + Err(_) => panic!("cometbft_light_block_validation_run failed"), + }; + assert_eq!(gas_used, 3_000); + assert_eq!(output, except_output_after_hertz); + } } diff --git a/crates/precompile/src/double_sign.rs b/crates/precompile/src/double_sign.rs new file mode 100644 index 00000000..1500c861 --- /dev/null +++ b/crates/precompile/src/double_sign.rs @@ -0,0 +1,202 @@ +use crate::secp256k1; +use crate::{Bytes, Error, Precompile, PrecompileResult, PrecompileWithAddress}; +use alloy_primitives::{BlockNumber, ChainId, U256}; +use alloy_rlp::{Decodable, RlpDecodable, RlpEncodable}; +use core::cmp::Ordering; +use revm_primitives::alloy_primitives::B512; +use revm_primitives::{keccak256, PrecompileError, B256}; + +/// Double sign evidence validation precompile for BSC. +pub(crate) const DOUBLE_SIGN_EVIDENCE_VALIDATION: PrecompileWithAddress = PrecompileWithAddress( + crate::u64_to_address(104), + Precompile::Standard(crate::double_sign::double_sign_evidence_validation_run), +); + +const EXTRA_SEAL_LENGTH: usize = 65; + +/// Double sign evidence with two different headers. +#[derive(Debug, RlpDecodable, PartialEq)] +pub(crate) struct DoubleSignEvidence { + pub(crate) chain_id: ChainId, + pub(crate) header_bytes1: Bytes, + pub(crate) header_bytes2: Bytes, +} + +/// Header of a block. +#[derive(Debug, RlpDecodable, PartialEq)] +pub(crate) struct Header { + pub(crate) parent_hash: [u8; 32], + pub(crate) uncle_hash: [u8; 32], + pub(crate) coinbase: [u8; 20], + pub(crate) root: [u8; 32], + pub(crate) tx_hash: [u8; 32], + pub(crate) receipt_hash: [u8; 32], + pub(crate) bloom: [u8; 256], + pub(crate) difficulty: U256, + pub(crate) number: BlockNumber, + pub(crate) gas_limit: u64, + pub(crate) gas_used: u64, + pub(crate) time: u64, + pub(crate) extra: Bytes, + pub(crate) mix_digest: [u8; 32], + pub(crate) nonce: [u8; 8], +} + +/// The fields to generate the seal hash. +#[derive(Debug, RlpEncodable, RlpDecodable, PartialEq)] +pub(crate) struct SealContent { + pub(crate) chain_id: ChainId, + pub(crate) parent_hash: [u8; 32], + pub(crate) uncle_hash: [u8; 32], + pub(crate) coinbase: [u8; 20], + pub(crate) root: [u8; 32], + pub(crate) tx_hash: [u8; 32], + pub(crate) receipt_hash: [u8; 32], + pub(crate) bloom: [u8; 256], + pub(crate) difficulty: U256, + pub(crate) number: BlockNumber, + pub(crate) gas_limit: u64, + pub(crate) gas_used: u64, + pub(crate) time: u64, + pub(crate) extra: Bytes, + pub(crate) mix_digest: [u8; 32], + pub(crate) nonce: [u8; 8], +} + +/// Run the double sign evidence validation precompile. +/// +/// input: rlp encoded DoubleSignEvidence +/// +/// return: +/// +/// signer address| evidence height| +/// +/// 20 bytes | 32 bytes | +fn double_sign_evidence_validation_run(input: &Bytes, gas_limit: u64) -> PrecompileResult { + const DOUBLE_SIGN_EVIDENCE_VALIDATION_BASE: u64 = 10_000; + + if DOUBLE_SIGN_EVIDENCE_VALIDATION_BASE > gas_limit { + return Err(Error::OutOfGas); + } + + let evidence = match DoubleSignEvidence::decode(&mut input.iter().as_ref()) { + Ok(e) => e, + Err(_) => return Err(PrecompileError::Other(String::from("invalid evidence"))), + }; + + let header1 = match Header::decode(&mut evidence.header_bytes1.as_ref()) { + Ok(e) => e, + Err(_) => return Err(PrecompileError::Other(String::from("invalid evidence"))), + }; + let header2 = match Header::decode(&mut evidence.header_bytes2.as_ref()) { + Ok(e) => e, + Err(_) => return Err(PrecompileError::Other(String::from("invalid evidence"))), + }; + + // basic check + if header1.number.to_be_bytes().len() > 32 || header2.number.to_be_bytes().len() > 32 { + return Err(PrecompileError::Other(String::from("invalid evidence"))); + } + if header1.number != header2.number { + return Err(PrecompileError::Other(String::from("invalid evidence"))); + } + if header1.parent_hash.cmp(&header2.parent_hash) != Ordering::Equal { + return Err(PrecompileError::Other(String::from("invalid evidence"))); + } + + if header1.extra.len() < EXTRA_SEAL_LENGTH || header1.extra.len() < EXTRA_SEAL_LENGTH { + return Err(PrecompileError::Other(String::from("invalid evidence"))); + } + let sig1 = &header1.extra[header1.extra.len() - EXTRA_SEAL_LENGTH..]; + let sig2 = &header2.extra[header2.extra.len() - EXTRA_SEAL_LENGTH..]; + if sig1.eq(sig2) { + return Err(PrecompileError::Other(String::from("invalid evidence"))); + } + + // check signature + let msg_hash1 = seal_hash(&header1, evidence.chain_id); + let msg_hash2 = seal_hash(&header2, evidence.chain_id); + + if msg_hash1.eq(&msg_hash2) { + return Err(PrecompileError::Other(String::from("invalid evidence"))); + } + + let recid1 = sig1[64]; + let sig1 = <&B512>::try_from(&sig1[..64]).unwrap(); + let addr1 = match secp256k1::ecrecover(sig1, recid1, &msg_hash1) { + Ok(pk) => pk, + Err(_) => return Err(PrecompileError::Other(String::from("invalid evidence"))), + }; + + let recid2 = sig2[64]; + let sig2 = <&B512>::try_from(&sig2[..64]).unwrap(); + let addr2 = match secp256k1::ecrecover(sig2, recid2, &msg_hash2) { + Ok(pk) => pk, + Err(_) => return Err(PrecompileError::Other(String::from("invalid evidence"))), + }; + + if !addr1.eq(&addr2) { + return Err(PrecompileError::Other(String::from("invalid evidence"))); + } + + let mut res = [0; 52]; + let signer = &addr1[12..]; + res[..20].clone_from_slice(signer); + res[52 - header1.number.to_be_bytes().len()..].clone_from_slice(&header1.number.to_be_bytes()); + + Ok(( + DOUBLE_SIGN_EVIDENCE_VALIDATION_BASE, + Bytes::copy_from_slice(&res), + )) +} + +fn seal_hash(header: &Header, chain_id: ChainId) -> B256 { + let seal_content = SealContent { + chain_id, + parent_hash: header.parent_hash, + uncle_hash: header.uncle_hash, + coinbase: header.coinbase, + root: header.root, + tx_hash: header.tx_hash, + receipt_hash: header.receipt_hash, + bloom: header.bloom, + difficulty: header.difficulty, + number: header.number, + gas_limit: header.gas_limit, + gas_used: header.gas_used, + time: header.time, + extra: header.extra.slice(..header.extra.len() - EXTRA_SEAL_LENGTH), + mix_digest: header.mix_digest, + nonce: header.nonce, + }; + let encoded = alloy_rlp::encode(seal_content); + + keccak256(encoded) +} + +#[cfg(test)] +mod tests { + use super::*; + use revm_primitives::hex; + + #[test] + fn test_double_sign_evidence_validation_run() { + let input = hex::decode("f906278202cab9030ff9030ca01062d3d5015b9242bc193a9b0769f3d3780ecb55f97f40a752ae26d0b68cd0d8a0fae1a05fcb14bfd9b8a9f2b65007a9b6c2000de0627a73be644dd993d32342c494976ea74026e726554db657fa54763abd0c3a0aa9a0f385cc58ed297ff0d66eb5580b02853d3478ba418b1819ac659ee05df49b9794a0bf88464af369ed6b8cf02db00f0b9556ffa8d49cd491b00952a7f83431446638a00a6d0870e586a76278fbfdcedf76ef6679af18fc1f9137cfad495f434974ea81b901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001820cdf830f4240830f4240846555fa64b90111d983010301846765746888676f312e32302e378664617277696e00007abd731ef8ae07b86091cb8836d58f5444b883422a18825d899035d3e6ea39ad1a50069bf0b86da8b5573dde1cb4a0a34f19ce94e0ef78ff7518c80265b8a3ca56e3c60167523590d4e8dcc324900559465fc0fa403774096614e135de280949b58a45cc96f2ba9e17f848820d41a08429d0d8b33ee72a84f750fefea846cbca54e487129c7961c680bb72309ca888820d42a08c9db14d938b19f9e2261bbeca2679945462be2b58103dfff73665d0d150fb8a804ae755e0fe64b59753f4db6308a1f679747bce186aa2c62b95fa6eeff3fbd08f3b0667e45428a54ade15bad19f49641c499b431b36f65803ea71b379e6b61de501a0232c9ba2d41b40d36ed794c306747bcbc49bf61a0f37409c18bfe2b5bef26a2d880000000000000000b9030ff9030ca01062d3d5015b9242bc193a9b0769f3d3780ecb55f97f40a752ae26d0b68cd0d8a0b2789a5357827ed838335283e15c4dcc42b9bebcbf2919a18613246787e2f96094976ea74026e726554db657fa54763abd0c3a0aa9a071ce4c09ee275206013f0063761bc19c93c13990582f918cc57333634c94ce89a00e095703e5c9b149f253fe89697230029e32484a410b4b1f2c61442d73c3095aa0d317ae19ede7c8a2d3ac9ef98735b049bcb7278d12f48c42b924538b60a25e12b901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001820cdf830f4240830f4240846555fa64b90111d983010301846765746888676f312e32302e378664617277696e00007abd731ef8ae07b86091cb8836d58f5444b883422a18825d899035d3e6ea39ad1a50069bf0b86da8b5573dde1cb4a0a34f19ce94e0ef78ff7518c80265b8a3ca56e3c60167523590d4e8dcc324900559465fc0fa403774096614e135de280949b58a45cc96f2ba9e17f848820d41a08429d0d8b33ee72a84f750fefea846cbca54e487129c7961c680bb72309ca888820d42a08c9db14d938b19f9e2261bbeca2679945462be2b58103dfff73665d0d150fb8a80c0b17bfe88534296ff064cb7156548f6deba2d6310d5044ed6485f087dc6ef232e051c28e1909c2b50a3b4f29345d66681c319bef653e52e5d746480d5a3983b00a0b56228685be711834d0f154292d07826dea42a0fad3e4f56c31470b7fbfbea26880000000000000000").unwrap(); + + let res = double_sign_evidence_validation_run(&Bytes::from(input), 10_000).unwrap(); + + let gas = res.0; + assert_eq!(gas, 10_000u64); + + let res = hex::encode(res.1); + assert_eq!(res, "15d34aaf54267db7d7c367839aaf71a00a2c6a650000000000000000000000000000000000000000000000000000000000000cdf") + } + + #[test] + fn test_double_sign_evidence_validation_run_invalid_evidence() { + let input = hex::decode("f9066b38b90332f9032fa01062d3d5015b9242bc193a9b0769f3d3780ecb55f97f40a752ae26d0b68cd0d8a0fae1a05fcb14bfd9b8a9f2b65007a9b6c2000de0627a73be644dd993d32342c494df87f0e2b8519ea2dd4abd8b639cdd628497ed25a0f385cc58ed297ff0d66eb5580b02853d3478ba418b1819ac659ee05df49b9794a0bf88464af369ed6b8cf02db00f0b9556ffa8d49cd491b00952a7f83431446638a00a6d0870e586a76278fbfdcedf76ef6679af18fc1f9137cfad495f434974ea81b901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001a1010000000000000000000000000000000000000000000000000000000000000000830f4240830f42408465bc6996b90115d983010306846765746889676f312e32302e3131856c696e7578000053474aa9f8b25fb860b0844a5082bfaa2299d2a23f076e2f6b17b15f839cc3e7d5a875656f6733fd4b87ba3401f906d15f3dea263cd9a6076107c7db620a4630dd3832c4a4b57eb8f497e28a3d69e5c03b30205c4b45675747d513e1accd66329770f3c35b18c9d023f84c84023a5ad6a086a28d985d9a6c8e7f9a4feadd5ace0adba9818e1e1727edca755fcc0bd8344684023a5ad7a0bc3492196b2e68b8e6ceea87cfa7588b4d590089eb885c4f2c1e9d9fb450f7b980988e1b9d0beb91dab063e04879a24c43d33baae3759dee41fd62ffa83c77fd202bea27a829b49e8025bdd198393526dd12b223ab16052fd26a43f3aabf63e76901a0232c9ba2d41b40d36ed794c306747bcbc49bf61a0f37409c18bfe2b5bef26a2d880000000000000000b90332f9032fa01062d3d5015b9242bc193a9b0769f3d3780ecb55f97f40a752ae26d0b68cd0d8a0b2789a5357827ed838335283e15c4dcc42b9bebcbf2919a18613246787e2f96094df87f0e2b8519ea2dd4abd8b639cdd628497ed25a071ce4c09ee275206013f0063761bc19c93c13990582f918cc57333634c94ce89a00e095703e5c9b149f253fe89697230029e32484a410b4b1f2c61442d73c3095aa0d317ae19ede7c8a2d3ac9ef98735b049bcb7278d12f48c42b924538b60a25e12b901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001a1010000000000000000000000000000000000000000000000000000000000000000830f4240830f42408465bc6996b90115d983010306846765746889676f312e32302e3131856c696e7578000053474aa9f8b25fb860b0844a5082bfaa2299d2a23f076e2f6b17b15f839cc3e7d5a875656f6733fd4b87ba3401f906d15f3dea263cd9a6076107c7db620a4630dd3832c4a4b57eb8f497e28a3d69e5c03b30205c4b45675747d513e1accd66329770f3c35b18c9d023f84c84023a5ad6a086a28d985d9a6c8e7f9a4feadd5ace0adba9818e1e1727edca755fcc0bd8344684023a5ad7a0bc3492196b2e68b8e6ceea87cfa7588b4d590089eb885c4f2c1e9d9fb450f7b9804c71ed015dd0c5c2d7393b68c2927f83f0a5da4c66f761f09e2f950cc610832c7876144599368404096ddef0eadacfde57717e2c7d23982b927285b797d41bfa00a0b56228685be711834d0f154292d07826dea42a0fad3e4f56c31470b7fbfbea26880000000000000000").unwrap(); + + let res = double_sign_evidence_validation_run(&Bytes::from(input), 10_000); + assert_eq!(res.err(), Some(PrecompileError::Other(String::from("invalid evidence")))); + } +} diff --git a/crates/precompile/src/iavl.rs b/crates/precompile/src/iavl.rs new file mode 100644 index 00000000..99891817 --- /dev/null +++ b/crates/precompile/src/iavl.rs @@ -0,0 +1,208 @@ +use crate::{Bytes, Error, Precompile, PrecompileError, PrecompileResult, PrecompileWithAddress}; +use parity_bytes::BytesRef; +use tendermint::lite::iavl_proof; + +/// Iavl proof validation precompile for BSC. +pub(crate) const IAVL_PROOF_VALIDATION: PrecompileWithAddress = PrecompileWithAddress( + crate::u64_to_address(101), + Precompile::Standard(crate::iavl::iavl_proof_validation_run), +); + +/// Iavl proof validation precompile for BSC after Nano hardfork. +pub(crate) const IAVL_PROOF_VALIDATION_NANO: PrecompileWithAddress = PrecompileWithAddress( + crate::u64_to_address(101), + Precompile::Standard(crate::iavl::iavl_proof_validation_run_nano), +); + +/// Iavl proof validation precompile for BSC after Moran hardfork. +pub(crate) const IAVL_PROOF_VALIDATION_MORAN: PrecompileWithAddress = PrecompileWithAddress( + crate::u64_to_address(101), + Precompile::Standard(crate::iavl::iavl_proof_validation_run_moran), +); + +/// Iavl proof validation precompile for BSC after Planck hardfork. +pub(crate) const IAVL_PROOF_VALIDATION_PLANCK: PrecompileWithAddress = PrecompileWithAddress( + crate::u64_to_address(101), + Precompile::Standard(crate::iavl::iavl_proof_validation_run_planck), +); + +/// Iavl proof validation precompile for BSC after Plato hardfork. +pub(crate) const IAVL_PROOF_VALIDATION_PLATO: PrecompileWithAddress = PrecompileWithAddress( + crate::u64_to_address(101), + Precompile::Standard(crate::iavl::iavl_proof_validation_run_plato), +); + +/// Run Iavl proof validation. +fn iavl_proof_validation_run(input: &Bytes, gas_limit: u64) -> PrecompileResult { + return iavl_proof_validation_run_inner(input, gas_limit, false, false, false); +} + + +/// Run Iavl proof validation with Nano hardfork. +fn iavl_proof_validation_run_nano(_input: &Bytes, _gas_limit: u64) -> PrecompileResult { + return Err(PrecompileError::other("suspended")); +} + + +/// Run Iavl proof validation with Moran hardfork. +fn iavl_proof_validation_run_moran(input: &Bytes, gas_limit: u64) -> PrecompileResult { + return iavl_proof_validation_run_inner(input, gas_limit, true, false, false); +} + +/// Run Iavl proof validation with Planck hardfork. +fn iavl_proof_validation_run_planck(input: &Bytes, gas_limit: u64) -> PrecompileResult { + return iavl_proof_validation_run_inner(input, gas_limit, false, true, false); +} + +/// Run Iavl proof validation with Plato hardfork. +fn iavl_proof_validation_run_plato(input: &Bytes, gas_limit: u64) -> PrecompileResult { + return iavl_proof_validation_run_inner(input, gas_limit, false, false, true); +} + +/// Run Iavl proof validation with given hardfork toggles. +fn iavl_proof_validation_run_inner( + input: &Bytes, + gas_limit: u64, + is_moran: bool, + is_planck: bool, + is_plato: bool, +) -> PrecompileResult { + const IAVL_PROOF_VALIDATION_BASE: u64 = 3_000; + + if IAVL_PROOF_VALIDATION_BASE > gas_limit { + return Err(Error::OutOfGas); + } + + let mut output = [0u8; 32]; + let mut bytes = BytesRef::Fixed(&mut output); + let res = iavl_proof::execute(input.as_ref(), &mut bytes, is_moran, is_planck, is_plato); + match res { + Ok(()) => Ok(( + IAVL_PROOF_VALIDATION_BASE, + Bytes::copy_from_slice(&output[..]), + )), + Err(str) => Err(PrecompileError::Other(String::from(str))), + } +} + +#[cfg(test)] +mod tests { + use super::*; + use revm_primitives::hex; + + #[test] + fn test_iavl_proof_validation_run() { + let input = hex::decode("00000000000000000000000000000000000000000000000000000000000007306163630000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001c6163636f756e743a8a4e2eb018bdf98a8f53ec755740ffc728637a1d000000000000000000000000000000000000000000000000000000000000007b4bdc4c270a750a148a4e2eb018bdf98a8f53ec755740ffc728637a1d12110a0941544348412d3733301080f69bf321120b0a03424e4210e8baeb8d44120f0a075050432d303041108094ebdc031a26eb5ae98721031c199c92e5b0080967da99be27cf2da53317441b4a663e6d9c6caf02be1fdbdc20d7962b28152c69c314b4de5c8035253c8bc0771d9ca17b1b23a57c0c6d068b57579791cae20add070a066961766c3a76121c6163636f756e743a8a4e2eb018bdf98a8f53ec755740ffc728637a1d1ab407b2070aaf070a2d081810cdfd2b188096a82222209f223f804e2d94ac51c4321b0687397012e6d95eb9783b03bc790da631004c7c0a2d081710adb31a18f395a8222a20d2a38865de82383ccce0140513b65cec1bf2ae6cd7dfeb22eb6faadb4e26b26f0a2d081510b2990b18f395a82222208a02bbd5a695dfc772627ac8744aa9cf30ae26575bdce8c96a9a0d0999175b430a2d081410e6ff0418f395a8222a20d39619c779be909e67f23499fb74eb2c19afd7f21523401d4ccf7e917db5cd600a2d081210e3fe0118f395a8222a20a10cc73843f889d9e03a463eb135e928bb980e19734344cba0fbf4e8a4c5258b0a2c081010dd6518f395a8222a2007fd15843a2fd3f58d021b0e072a6c70742d7a3d993a922445e3491e1c14ee8e0a2c080f10cc2a18eda6a7222a20088942d7b30abd021d8e9505cc41313fad87c8c10a799f3b51018b7b2cfe4ad90a2c080d10b70d18eda6a7222a2091a37bc44d0c61e3752ddc59eb390355ab65e8a9fb453be4f0acec537f1ca14f0a2c080c10890818eda6a72222201cfc317855a06667c45812fe36efe33af05671dfe0d9b56b02662011af2e79e30a2c080b10ac0318c4b0ee212220aeb454a4b3243b6269a2fd8841dca9a951c53b30f1e27da91063dae7224402c70a2c080910e40118c4b0ee212a20441340a4de6498f861b97b3f3ad9603af055e5af51a0d96fff2ae28e3c5c6c9a0a2c0808108d0118c4b0ee212220ae32ea4b9ab7b53571da320e2815fd8b2c278124961cca4a1849a799842424450a2b0807104d18c4b0ee212220e2804c9b7f045ec0b4ab20920a937b82fda8b7a9ddd12b21637335b915cfda550a2b0806102418a5f4c7192a20ec85f22addedfc82c771af5b4c77544b7c1d7c5bbac33f2712dfba1045ebdbd00a2b0805101118a5f4c7192a2071ade34dcc447a0ba8adc603080633d15c06f3525830c86ebce35eca0a4921fc0a2b0804100c18a5f4c7192a205190bce93993e65b266a3417ed511df8897a812cb4b62569e5afcfbec10b69cd0a2b0803100618a5f4c7192220b76c6884f1d412ac10bfb3987fb7d26f0330b2a85539509ebc5c6bdec2f95d520a2b0802100418a5f4c71922206a285b4a4f9d1c687bbafa1f3649b6a6e32b1a85dd0402421210683e846cf0020a2b0801100218a5f4c7192220033b3f7c6dcb258b6e55545e7a4f51539447cd595eb8a2e373ba0015502da1051a450a1c6163636f756e743a8a4e2eb018bdf98a8f53ec755740ffc728637a1d12201a272295e94cf1d8090bdb019dde48e9dab026ad2c3e43aaa7e61cc954a9245d18a5f4c7190ab6040a0a6d756c746973746f726512036163631aa204a0040a9d040a300a0364657812290a27088496a822122038fc49f49648fec62acc434151a51eaa378c1b20a730a749548e36f1529422500a300a03676f7612290a27088496a8221220a78ce489bdf08b9ee869c184876e1623dc38b3e64a5cf1a0005f97976c64deac0a380a0b61746f6d69635f7377617012290a27088496a8221220544c2fa38f61e10a39ec00b3e724d5834761268bb455cdbf5843bcf1531f8fbc0a300a0376616c12290a27088496a82212201f71082c9f6f45fb456b2c00b41e50d2f662f2dfec3cb6965f19d214bf02f3980a0f0a046d61696e12070a05088496a8220a320a057374616b6512290a27088496a82212200dd467343c718f240e50b4feac42970fc8c1c69a018be955f9c27913ac1f8b3c0a300a0361636312290a27088496a8221220270c19ccc9c40c5176b3dfbd8af734c97a307e0dbd8df9e286dcd5d709f973ed0a330a06746f6b656e7312290a27088496a8221220c4f96eedf50c83964de9df013afec2e545012d92528b643a5166c828774187b60a320a05706169727312290a27088496a8221220351c55cfda84596ecd22ebc77013662aba97f81f19d9ef3d150213bb07c823060a360a0974696d655f6c6f636b12290a27088496a8221220e7adf5bd30ce022decf0e9341bf05c464ed70cdbc97423bd2bab8f3571e5179b0a330a06706172616d7312290a27088496a822122042a9dfc356ca435db131eb41fb1975c8482f2434537918665e530b0b4633b5f9").unwrap(); + let res = iavl_proof_validation_run(&Bytes::from(input), 3_000u64).unwrap(); + + let gas = res.0; + assert_eq!(gas, 3_000u64); + + let res = hex::encode(res.1); + assert_eq!( + res, + "0000000000000000000000000000000000000000000000000000000000000001" + ) + } + + #[test] + fn test_iavl_proof_validation_run_moran() { + let input = hex::decode("00000000000000000000000000000000000000000000000000000000000007306163630000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001c6163636f756e743a8a4e2eb018bdf98a8f53ec755740ffc728637a1d000000000000000000000000000000000000000000000000000000000000007b4bdc4c270a750a148a4e2eb018bdf98a8f53ec755740ffc728637a1d12110a0941544348412d3733301080f69bf321120b0a03424e4210e8baeb8d44120f0a075050432d303041108094ebdc031a26eb5ae98721031c199c92e5b0080967da99be27cf2da53317441b4a663e6d9c6caf02be1fdbdc20d7962b28152c69c314b4de5c8035253c8bc0771d9ca17b1b23a57c0c6d068b57579791cae20add070a066961766c3a76121c6163636f756e743a8a4e2eb018bdf98a8f53ec755740ffc728637a1d1ab407b2070aaf070a2d081810cdfd2b188096a82222209f223f804e2d94ac51c4321b0687397012e6d95eb9783b03bc790da631004c7c0a2d081710adb31a18f395a8222a20d2a38865de82383ccce0140513b65cec1bf2ae6cd7dfeb22eb6faadb4e26b26f0a2d081510b2990b18f395a82222208a02bbd5a695dfc772627ac8744aa9cf30ae26575bdce8c96a9a0d0999175b430a2d081410e6ff0418f395a8222a20d39619c779be909e67f23499fb74eb2c19afd7f21523401d4ccf7e917db5cd600a2d081210e3fe0118f395a8222a20a10cc73843f889d9e03a463eb135e928bb980e19734344cba0fbf4e8a4c5258b0a2c081010dd6518f395a8222a2007fd15843a2fd3f58d021b0e072a6c70742d7a3d993a922445e3491e1c14ee8e0a2c080f10cc2a18eda6a7222a20088942d7b30abd021d8e9505cc41313fad87c8c10a799f3b51018b7b2cfe4ad90a2c080d10b70d18eda6a7222a2091a37bc44d0c61e3752ddc59eb390355ab65e8a9fb453be4f0acec537f1ca14f0a2c080c10890818eda6a72222201cfc317855a06667c45812fe36efe33af05671dfe0d9b56b02662011af2e79e30a2c080b10ac0318c4b0ee212220aeb454a4b3243b6269a2fd8841dca9a951c53b30f1e27da91063dae7224402c70a2c080910e40118c4b0ee212a20441340a4de6498f861b97b3f3ad9603af055e5af51a0d96fff2ae28e3c5c6c9a0a2c0808108d0118c4b0ee212220ae32ea4b9ab7b53571da320e2815fd8b2c278124961cca4a1849a799842424450a2b0807104d18c4b0ee212220e2804c9b7f045ec0b4ab20920a937b82fda8b7a9ddd12b21637335b915cfda550a2b0806102418a5f4c7192a20ec85f22addedfc82c771af5b4c77544b7c1d7c5bbac33f2712dfba1045ebdbd00a2b0805101118a5f4c7192a2071ade34dcc447a0ba8adc603080633d15c06f3525830c86ebce35eca0a4921fc0a2b0804100c18a5f4c7192a205190bce93993e65b266a3417ed511df8897a812cb4b62569e5afcfbec10b69cd0a2b0803100618a5f4c7192220b76c6884f1d412ac10bfb3987fb7d26f0330b2a85539509ebc5c6bdec2f95d520a2b0802100418a5f4c71922206a285b4a4f9d1c687bbafa1f3649b6a6e32b1a85dd0402421210683e846cf0020a2b0801100218a5f4c7192220033b3f7c6dcb258b6e55545e7a4f51539447cd595eb8a2e373ba0015502da1051a450a1c6163636f756e743a8a4e2eb018bdf98a8f53ec755740ffc728637a1d12201a272295e94cf1d8090bdb019dde48e9dab026ad2c3e43aaa7e61cc954a9245d18a5f4c7190ab6040a0a6d756c746973746f726512036163631aa204a0040a9d040a300a0364657812290a27088496a822122038fc49f49648fec62acc434151a51eaa378c1b20a730a749548e36f1529422500a300a03676f7612290a27088496a8221220a78ce489bdf08b9ee869c184876e1623dc38b3e64a5cf1a0005f97976c64deac0a380a0b61746f6d69635f7377617012290a27088496a8221220544c2fa38f61e10a39ec00b3e724d5834761268bb455cdbf5843bcf1531f8fbc0a300a0376616c12290a27088496a82212201f71082c9f6f45fb456b2c00b41e50d2f662f2dfec3cb6965f19d214bf02f3980a0f0a046d61696e12070a05088496a8220a320a057374616b6512290a27088496a82212200dd467343c718f240e50b4feac42970fc8c1c69a018be955f9c27913ac1f8b3c0a300a0361636312290a27088496a8221220270c19ccc9c40c5176b3dfbd8af734c97a307e0dbd8df9e286dcd5d709f973ed0a330a06746f6b656e7312290a27088496a8221220c4f96eedf50c83964de9df013afec2e545012d92528b643a5166c828774187b60a320a05706169727312290a27088496a8221220351c55cfda84596ecd22ebc77013662aba97f81f19d9ef3d150213bb07c823060a360a0974696d655f6c6f636b12290a27088496a8221220e7adf5bd30ce022decf0e9341bf05c464ed70cdbc97423bd2bab8f3571e5179b0a330a06706172616d7312290a27088496a822122042a9dfc356ca435db131eb41fb1975c8482f2434537918665e530b0b4633b5f9").unwrap(); + let res = iavl_proof_validation_run_moran(&Bytes::from(input), 3_000u64).unwrap(); + + let gas = res.0; + assert_eq!(gas, 3_000u64); + + let res = hex::encode(res.1); + assert_eq!( + res, + "0000000000000000000000000000000000000000000000000000000000000001" + ) + } + + #[test] + fn test_iavl_proof_validation_run_absence_proof_moran() { + let input = hex::decode("00000000000000000000000000000000000000000000000000000000000007306163630000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001c6163636f756e743a8a4e2eb018bdf98a8f53ec755740ffc728637a1d000000000000000000000000000000000000000000000000000000000000007b4bdc4c270a750a148a4e2eb018bdf98a8f53ec755740ffc728637a1d12110a0941544348412d3733301080f69bf321120b0a03424e4210e8baeb8d44120f0a075050432d303041108094ebdc031a26eb5ae98721031c199c92e5b0080967da99be27cf2da53317441b4a663e6d9c6caf02be1fdbdc20d7962b28152c69c314b4de5c8035253c8bc0771d9ca17b1b23a57c0c6d068b57579791cae20add070a066961766c3a61121c6163636f756e743a8a4e2eb018bdf98a8f53ec755740ffc728637a1d1ab407b2070aaf070a2d081810cdfd2b188096a82222209f223f804e2d94ac51c4321b0687397012e6d95eb9783b03bc790da631004c7c0a2d081710adb31a18f395a8222a20d2a38865de82383ccce0140513b65cec1bf2ae6cd7dfeb22eb6faadb4e26b26f0a2d081510b2990b18f395a82222208a02bbd5a695dfc772627ac8744aa9cf30ae26575bdce8c96a9a0d0999175b430a2d081410e6ff0418f395a8222a20d39619c779be909e67f23499fb74eb2c19afd7f21523401d4ccf7e917db5cd600a2d081210e3fe0118f395a8222a20a10cc73843f889d9e03a463eb135e928bb980e19734344cba0fbf4e8a4c5258b0a2c081010dd6518f395a8222a2007fd15843a2fd3f58d021b0e072a6c70742d7a3d993a922445e3491e1c14ee8e0a2c080f10cc2a18eda6a7222a20088942d7b30abd021d8e9505cc41313fad87c8c10a799f3b51018b7b2cfe4ad90a2c080d10b70d18eda6a7222a2091a37bc44d0c61e3752ddc59eb390355ab65e8a9fb453be4f0acec537f1ca14f0a2c080c10890818eda6a72222201cfc317855a06667c45812fe36efe33af05671dfe0d9b56b02662011af2e79e30a2c080b10ac0318c4b0ee212220aeb454a4b3243b6269a2fd8841dca9a951c53b30f1e27da91063dae7224402c70a2c080910e40118c4b0ee212a20441340a4de6498f861b97b3f3ad9603af055e5af51a0d96fff2ae28e3c5c6c9a0a2c0808108d0118c4b0ee212220ae32ea4b9ab7b53571da320e2815fd8b2c278124961cca4a1849a799842424450a2b0807104d18c4b0ee212220e2804c9b7f045ec0b4ab20920a937b82fda8b7a9ddd12b21637335b915cfda550a2b0806102418a5f4c7192a20ec85f22addedfc82c771af5b4c77544b7c1d7c5bbac33f2712dfba1045ebdbd00a2b0805101118a5f4c7192a2071ade34dcc447a0ba8adc603080633d15c06f3525830c86ebce35eca0a4921fc0a2b0804100c18a5f4c7192a205190bce93993e65b266a3417ed511df8897a812cb4b62569e5afcfbec10b69cd0a2b0803100618a5f4c7192220b76c6884f1d412ac10bfb3987fb7d26f0330b2a85539509ebc5c6bdec2f95d520a2b0802100418a5f4c71922206a285b4a4f9d1c687bbafa1f3649b6a6e32b1a85dd0402421210683e846cf0020a2b0801100218a5f4c7192220033b3f7c6dcb258b6e55545e7a4f51539447cd595eb8a2e373ba0015502da1051a450a1c6163636f756e743a8a4e2eb018bdf98a8f53ec755740ffc728637a1d12201a272295e94cf1d8090bdb019dde48e9dab026ad2c3e43aaa7e61cc954a9245d18a5f4c7190ab6040a0a6d756c746973746f726512036163631aa204a0040a9d040a300a0364657812290a27088496a822122038fc49f49648fec62acc434151a51eaa378c1b20a730a749548e36f1529422500a300a03676f7612290a27088496a8221220a78ce489bdf08b9ee869c184876e1623dc38b3e64a5cf1a0005f97976c64deac0a380a0b61746f6d69635f7377617012290a27088496a8221220544c2fa38f61e10a39ec00b3e724d5834761268bb455cdbf5843bcf1531f8fbc0a300a0376616c12290a27088496a82212201f71082c9f6f45fb456b2c00b41e50d2f662f2dfec3cb6965f19d214bf02f3980a0f0a046d61696e12070a05088496a8220a320a057374616b6512290a27088496a82212200dd467343c718f240e50b4feac42970fc8c1c69a018be955f9c27913ac1f8b3c0a300a0361636312290a27088496a8221220270c19ccc9c40c5176b3dfbd8af734c97a307e0dbd8df9e286dcd5d709f973ed0a330a06746f6b656e7312290a27088496a8221220c4f96eedf50c83964de9df013afec2e545012d92528b643a5166c828774187b60a320a05706169727312290a27088496a8221220351c55cfda84596ecd22ebc77013662aba97f81f19d9ef3d150213bb07c823060a360a0974696d655f6c6f636b12290a27088496a8221220e7adf5bd30ce022decf0e9341bf05c464ed70cdbc97423bd2bab8f3571e5179b0a330a06706172616d7312290a27088496a822122042a9dfc356ca435db131eb41fb1975c8482f2434537918665e530b0b4633b5f9").unwrap(); + let res = iavl_proof_validation_run_moran(&Bytes::from(input), 3_000u64); + + assert_eq!( + res.err(), + Some(PrecompileError::Other(String::from("invalid merkle proof"))) + ); + } + + #[test] + fn test_iavl_proof_validation_run_before_after_moran() { + // Bytest1 is the inputs of exploit tx 0x05356fd06ce56a9ec5b4eaf9c075abd740cae4c21eab1676440ab5cd2fe5c57a + let bytest1 = hex::decode("00000000000000000000000000000000000000000000000000000000000005086962630000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e00000100380200000000010dd9ac0000000000000000000000000000000000000000000000000000000000000093000000000000000000000000000000000000000000000000000000000000000000f870a0424e4200000000000000000000000000000000000000000000000000000000009400000000000000000000000000000000000000008ad3c21bcecceda100000094489a8756c18c0b8b24ec2a2b9ff3d4d447f79bec94489a8756c18c0b8b24ec2a2b9ff3d4d447f79bec846553f10072cda827a83531ca0fd7ac917a6b65649719aab0836722caafe0603147a523180a8d020a066961766c3a76120e00000100380200000000010dd9ac1af201f0010aed010a2b0802100318b091c73422200c10f902d266c238a4ca9e26fa9bc36483cd3ebee4e263012f5e7f40c22ee4d20a4d0801100218b091c7342220e4fd47bffd1c06e67edad92b2bf9ca63631978676288a2aa99f95c459436ef632a20121a1f9c4eca726c725796c5375fc4158986ced08e498dc8268ef94d8ed1891612001a370a0e0000010038020000000000000002122011056c6919f02d966991c10721684a8d1542e44003f9ffb47032c18995d4ac7f18b091c7341a340a0e00000100380200000000010dd9ac12202c3a561458f8527b002b5ec3cab2d308662798d6245d4588a4e6a80ebdfe30ac18010ad4050a0a6d756c746973746f726512036962631ac005be050abb050a110a066f7261636c6512070a0508b891c7340a0f0a046d61696e12070a0508b891c7340a350a08736c617368696e6712290a2708b891c7341220c8ccf341e6e695e7e1cb0ce4bf347eea0cc16947d8b4e934ec400b57c59d6f860a380a0b61746f6d69635f7377617012290a2708b891c734122042d4ecc9468f71a70288a95d46564bfcaf2c9f811051dcc5593dbef152976b010a110a0662726964676512070a0508b891c7340a300a0364657812290a2708b891c73412201773be443c27f61075cecdc050ce22eb4990c54679089e90afdc4e0e88182a230a2f0a02736312290a2708b891c7341220df7a0484b7244f76861b1642cfb7a61d923794bd2e076c8dbd05fc4ee29f3a670a330a06746f6b656e7312290a2708b891c734122064958c2f76fec1fa5d1828296e51264c259fa264f499724795a740f48fc4731b0a320a057374616b6512290a2708b891c734122015d2c302143bdf029d58fe381cc3b54cedf77ecb8834dfc5dc3e1555d68f19ab0a330a06706172616d7312290a2708b891c734122050abddcb7c115123a5a4247613ab39e6ba935a3d4f4b9123c4fedfa0895c040a0a300a0361636312290a2708b891c734122079fb5aecc4a9b87e56231103affa5e515a1bdf3d0366490a73e087980b7f1f260a0e0a0376616c12070a0508b891c7340a300a0369626312290a2708b891c7341220e09159530585455058cf1785f411ea44230f39334e6e0f6a3c54dbf069df2b620a300a03676f7612290a2708b891c7341220db85ddd37470983b14186e975a175dfb0bf301b43de685ced0aef18d28b4e0420a320a05706169727312290a2708b891c7341220a78b556bc9e73d86b4c63ceaf146db71b12ac80e4c10dd0ce6eb09c99b0c7cfe0a360a0974696d655f6c6f636b12290a2708b891c73412204775dbe01d41cab018c21ba5c2af94720e4d7119baf693670e70a40ba2a52143").unwrap(); + // Bytest1 is the inputs of exploit tx 0xebf83628ba893d35b496121fb8201666b8e09f3cbadf0e269162baa72efe3b8b + let bytest2 = hex::decode("00000000000000000000000000000000000000000000000000000000000005086962630000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e00000100380200000000010dd85c0000000000000000000000000000000000000000000000000000000000000093000000000000000000000000000000000000000000000000000000000000000000f870a0424e4200000000000000000000000000000000000000000000000000000000009400000000000000000000000000000000000000008ad3c21bcecceda100000094489a8756c18c0b8b24ec2a2b9ff3d4d447f79bec94489a8756c18c0b8b24ec2a2b9ff3d4d447f79bec846553f10072cda827a83531ca0fd7ac917a6b65649719aab0836722caafe0603147a523180a8d020a066961766c3a76120e00000100380200000000010dd85c1af201f0010aed010a2b0802100318b091c73422200c10f902d266c238a4ca9e26fa9bc36483cd3ebee4e263012f5e7f40c22ee4d20a4d0801100218b091c7342220e4fd47bffd1c06e67edad92b2bf9ca63631978676288a2aa99f95c459436ef632a20da657c1ffb86c684eb3e265361ef0fa4f9dfa670b45f9f91c5eb6ad84b21a4d112001a370a0e0000010038020000000000000002122011056c6919f02d966991c10721684a8d1542e44003f9ffb47032c18995d4ac7f18b091c7341a340a0e00000100380200000000010dd85c12202c3a561458f8527b002b5ec3cab2d308662798d6245d4588a4e6a80ebdfe30ac18010ad4050a0a6d756c746973746f726512036962631ac005be050abb050a110a066f7261636c6512070a0508b891c7340a0f0a046d61696e12070a0508b891c7340a350a08736c617368696e6712290a2708b891c7341220c8ccf341e6e695e7e1cb0ce4bf347eea0cc16947d8b4e934ec400b57c59d6f860a380a0b61746f6d69635f7377617012290a2708b891c734122042d4ecc9468f71a70288a95d46564bfcaf2c9f811051dcc5593dbef152976b010a110a0662726964676512070a0508b891c7340a300a0364657812290a2708b891c73412201773be443c27f61075cecdc050ce22eb4990c54679089e90afdc4e0e88182a230a2f0a02736312290a2708b891c7341220df7a0484b7244f76861b1642cfb7a61d923794bd2e076c8dbd05fc4ee29f3a670a330a06746f6b656e7312290a2708b891c734122064958c2f76fec1fa5d1828296e51264c259fa264f499724795a740f48fc4731b0a320a057374616b6512290a2708b891c734122015d2c302143bdf029d58fe381cc3b54cedf77ecb8834dfc5dc3e1555d68f19ab0a330a06706172616d7312290a2708b891c734122050abddcb7c115123a5a4247613ab39e6ba935a3d4f4b9123c4fedfa0895c040a0a300a0361636312290a2708b891c734122079fb5aecc4a9b87e56231103affa5e515a1bdf3d0366490a73e087980b7f1f260a0e0a0376616c12070a0508b891c7340a300a0369626312290a2708b891c7341220e09159530585455058cf1785f411ea44230f39334e6e0f6a3c54dbf069df2b620a300a03676f7612290a2708b891c7341220db85ddd37470983b14186e975a175dfb0bf301b43de685ced0aef18d28b4e0420a320a05706169727312290a2708b891c7341220a78b556bc9e73d86b4c63ceaf146db71b12ac80e4c10dd0ce6eb09c99b0c7cfe0a360a0974696d655f6c6f636b12290a2708b891c73412204775dbe01d41cab018c21ba5c2af94720e4d7119baf693670e70a40ba2a52143").unwrap(); + + let testcases = vec![bytest1, bytest2]; + + testcases.into_iter().for_each(|t| { + let res = iavl_proof_validation_run(&Bytes::from(t.clone()), 3_000u64); + assert_eq!(res.err(), None); + + let res = iavl_proof_validation_run_moran(&Bytes::from(t.clone()), 3_000u64); + + assert_eq!( + res.err(), + Some(PrecompileError::Other(String::from("invalid merkle proof"))) + ); + }); + + let input = hex::decode("00000000000000000000000000000000000000000000000000000000000007306163630000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001c6163636f756e743a8a4e2eb018bdf98a8f53ec755740ffc728637a1d000000000000000000000000000000000000000000000000000000000000007b4bdc4c270a750a148a4e2eb018bdf98a8f53ec755740ffc728637a1d12110a0941544348412d3733301080f69bf321120b0a03424e4210e8baeb8d44120f0a075050432d303041108094ebdc031a26eb5ae98721031c199c92e5b0080967da99be27cf2da53317441b4a663e6d9c6caf02be1fdbdc20d7962b28152c69c314b4de5c8035253c8bc0771d9ca17b1b23a57c0c6d068b57579791cae20add070a066961766c3a61121c6163636f756e743a8a4e2eb018bdf98a8f53ec755740ffc728637a1d1ab407b2070aaf070a2d081810cdfd2b188096a82222209f223f804e2d94ac51c4321b0687397012e6d95eb9783b03bc790da631004c7c0a2d081710adb31a18f395a8222a20d2a38865de82383ccce0140513b65cec1bf2ae6cd7dfeb22eb6faadb4e26b26f0a2d081510b2990b18f395a82222208a02bbd5a695dfc772627ac8744aa9cf30ae26575bdce8c96a9a0d0999175b430a2d081410e6ff0418f395a8222a20d39619c779be909e67f23499fb74eb2c19afd7f21523401d4ccf7e917db5cd600a2d081210e3fe0118f395a8222a20a10cc73843f889d9e03a463eb135e928bb980e19734344cba0fbf4e8a4c5258b0a2c081010dd6518f395a8222a2007fd15843a2fd3f58d021b0e072a6c70742d7a3d993a922445e3491e1c14ee8e0a2c080f10cc2a18eda6a7222a20088942d7b30abd021d8e9505cc41313fad87c8c10a799f3b51018b7b2cfe4ad90a2c080d10b70d18eda6a7222a2091a37bc44d0c61e3752ddc59eb390355ab65e8a9fb453be4f0acec537f1ca14f0a2c080c10890818eda6a72222201cfc317855a06667c45812fe36efe33af05671dfe0d9b56b02662011af2e79e30a2c080b10ac0318c4b0ee212220aeb454a4b3243b6269a2fd8841dca9a951c53b30f1e27da91063dae7224402c70a2c080910e40118c4b0ee212a20441340a4de6498f861b97b3f3ad9603af055e5af51a0d96fff2ae28e3c5c6c9a0a2c0808108d0118c4b0ee212220ae32ea4b9ab7b53571da320e2815fd8b2c278124961cca4a1849a799842424450a2b0807104d18c4b0ee212220e2804c9b7f045ec0b4ab20920a937b82fda8b7a9ddd12b21637335b915cfda550a2b0806102418a5f4c7192a20ec85f22addedfc82c771af5b4c77544b7c1d7c5bbac33f2712dfba1045ebdbd00a2b0805101118a5f4c7192a2071ade34dcc447a0ba8adc603080633d15c06f3525830c86ebce35eca0a4921fc0a2b0804100c18a5f4c7192a205190bce93993e65b266a3417ed511df8897a812cb4b62569e5afcfbec10b69cd0a2b0803100618a5f4c7192220b76c6884f1d412ac10bfb3987fb7d26f0330b2a85539509ebc5c6bdec2f95d520a2b0802100418a5f4c71922206a285b4a4f9d1c687bbafa1f3649b6a6e32b1a85dd0402421210683e846cf0020a2b0801100218a5f4c7192220033b3f7c6dcb258b6e55545e7a4f51539447cd595eb8a2e373ba0015502da1051a450a1c6163636f756e743a8a4e2eb018bdf98a8f53ec755740ffc728637a1d12201a272295e94cf1d8090bdb019dde48e9dab026ad2c3e43aaa7e61cc954a9245d18a5f4c7190ab6040a0a6d756c746973746f726512036163631aa204a0040a9d040a300a0364657812290a27088496a822122038fc49f49648fec62acc434151a51eaa378c1b20a730a749548e36f1529422500a300a03676f7612290a27088496a8221220a78ce489bdf08b9ee869c184876e1623dc38b3e64a5cf1a0005f97976c64deac0a380a0b61746f6d69635f7377617012290a27088496a8221220544c2fa38f61e10a39ec00b3e724d5834761268bb455cdbf5843bcf1531f8fbc0a300a0376616c12290a27088496a82212201f71082c9f6f45fb456b2c00b41e50d2f662f2dfec3cb6965f19d214bf02f3980a0f0a046d61696e12070a05088496a8220a320a057374616b6512290a27088496a82212200dd467343c718f240e50b4feac42970fc8c1c69a018be955f9c27913ac1f8b3c0a300a0361636312290a27088496a8221220270c19ccc9c40c5176b3dfbd8af734c97a307e0dbd8df9e286dcd5d709f973ed0a330a06746f6b656e7312290a27088496a8221220c4f96eedf50c83964de9df013afec2e545012d92528b643a5166c828774187b60a320a05706169727312290a27088496a8221220351c55cfda84596ecd22ebc77013662aba97f81f19d9ef3d150213bb07c823060a360a0974696d655f6c6f636b12290a27088496a8221220e7adf5bd30ce022decf0e9341bf05c464ed70cdbc97423bd2bab8f3571e5179b0a330a06706172616d7312290a27088496a822122042a9dfc356ca435db131eb41fb1975c8482f2434537918665e530b0b4633b5f9").unwrap(); + let res = iavl_proof_validation_run_moran(&Bytes::from(input), 3_000u64); + + assert_eq!( + res.err(), + Some(PrecompileError::Other(String::from("invalid merkle proof"))) + ); + } + + #[test] + fn test_iavl_proof_validation_run_valid_proof_moran() { + let input = hex::decode("00000000000000000000000000000000000000000000000000000000000005086962630000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e00000100380200000000010dd9ac0000000000000000000000000000000000000000000000000000000000000093000000000000000000000000000000000000000000000000000000000000000000f870a0424e4200000000000000000000000000000000000000000000000000000000009400000000000000000000000000000000000000008ad3c21bcecceda100000094489a8756c18c0b8b24ec2a2b9ff3d4d447f79bec94489a8756c18c0b8b24ec2a2b9ff3d4d447f79bec846553f10072cda827a83531ca0fd7ac917a6b65649719aab0836722caafe0603147a523180a8d020a066961766c3a76120e00000100380200000000010dd9ac1af201f0010aed010a2b0802100318b091c73422200c10f902d266c238a4ca9e26fa9bc36483cd3ebee4e263012f5e7f40c22ee4d20a4d0801100218b091c7342220e4fd47bffd1c06e67edad92b2bf9ca63631978676288a2aa99f95c459436ef632a20121a1f9c4eca726c725796c5375fc4158986ced08e498dc8268ef94d8ed1891612001a370a0e0000010038020000000000000002122011056c6919f02d966991c10721684a8d1542e44003f9ffb47032c18995d4ac7f18b091c7341a340a0e00000100380200000000010dd9ac12202c3a561458f8527b002b5ec3cab2d308662798d6245d4588a4e6a80ebdfe30ac18010ad4050a0a6d756c746973746f726512036962631ac005be050abb050a110a066f7261636c6512070a0508b891c7340a0f0a046d61696e12070a0508b891c7340a350a08736c617368696e6712290a2708b891c7341220c8ccf341e6e695e7e1cb0ce4bf347eea0cc16947d8b4e934ec400b57c59d6f860a380a0b61746f6d69635f7377617012290a2708b891c734122042d4ecc9468f71a70288a95d46564bfcaf2c9f811051dcc5593dbef152976b010a110a0662726964676512070a0508b891c7340a300a0364657812290a2708b891c73412201773be443c27f61075cecdc050ce22eb4990c54679089e90afdc4e0e88182a230a2f0a02736312290a2708b891c7341220df7a0484b7244f76861b1642cfb7a61d923794bd2e076c8dbd05fc4ee29f3a670a330a06746f6b656e7312290a2708b891c734122064958c2f76fec1fa5d1828296e51264c259fa264f499724795a740f48fc4731b0a320a057374616b6512290a2708b891c734122015d2c302143bdf029d58fe381cc3b54cedf77ecb8834dfc5dc3e1555d68f19ab0a330a06706172616d7312290a2708b891c734122050abddcb7c115123a5a4247613ab39e6ba935a3d4f4b9123c4fedfa0895c040a0a300a0361636312290a2708b891c734122079fb5aecc4a9b87e56231103affa5e515a1bdf3d0366490a73e087980b7f1f260a0e0a0376616c12070a0508b891c7340a300a0369626312290a2708b891c7341220e09159530585455058cf1785f411ea44230f39334e6e0f6a3c54dbf069df2b620a300a03676f7612290a2708b891c7341220db85ddd37470983b14186e975a175dfb0bf301b43de685ced0aef18d28b4e0420a320a05706169727312290a2708b891c7341220a78b556bc9e73d86b4c63ceaf146db71b12ac80e4c10dd0ce6eb09c99b0c7cfe0a360a0974696d655f6c6f636b12290a2708b891c73412204775dbe01d41cab018c21ba5c2af94720e4d7119baf693670e70a40ba2a52143").unwrap(); + let res = iavl_proof_validation_run(&Bytes::from(input), 3_000u64).unwrap(); + + let gas = res.0; + assert_eq!(gas, 3_000u64); + + let res = hex::encode(res.1); + assert_eq!( + res, + "0000000000000000000000000000000000000000000000000000000000000001" + ) + } + + #[test] + fn test_iavl_proof_validation_run_valid_proof_plank() { + let input = hex::decode("000000000000000000000000000000000000000000000000000000000000015b6962630000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000477696e640000000000000000000000000000000000000000000000000000000000000005626c6f7773ae6d1123fc362b3297bfb19c9f9fabbcbd1e2555b923dead261905b8a2ff6db60a300a0a69637332333a6961766c120477696e641a1c0a1a0a0477696e641205626c6f77731a0b0801180120012a030002040a9d010a0c69637332333a73696d706c6512036962631a87010a84010a036962631220141acb8632cfb808f293f2649cb9aabaca74fc18640900ffd0d48e2994b2a1521a090801180120012a0100222708011201011a205f0ba08283de309300409486e978a3ea59d82bccc838b07c7d39bd87c16a5034222708011201011a20455b81ef5591150bd24d3e57a769f65518b16de93487f0fab02271b3d69e2852").unwrap(); + let res = iavl_proof_validation_run_planck(&Bytes::from(input), 3_000u64).unwrap(); + + let gas = res.0; + assert_eq!(gas, 3_000u64); + + let res = hex::encode(res.1); + assert_eq!( + res, + "0000000000000000000000000000000000000000000000000000000000000001" + ) + } + + #[test] + fn test_iavl_proof_validation_run_valid_proof_plato() { + let input = hex::decode("000000000000000000000000000000000000000000000000000000000000015b6962630000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000477696e640000000000000000000000000000000000000000000000000000000000000005626c6f7773ae6d1123fc362b3297bfb19c9f9fabbcbd1e2555b923dead261905b8a2ff6db60a300a0a69637332333a6961766c120477696e641a1c0a1a0a0477696e641205626c6f77731a0b0801180120012a030002040a9d010a0c69637332333a73696d706c6512036962631a87010a84010a036962631220141acb8632cfb808f293f2649cb9aabaca74fc18640900ffd0d48e2994b2a1521a090801180120012a0100222708011201011a205f0ba08283de309300409486e978a3ea59d82bccc838b07c7d39bd87c16a5034222708011201011a20455b81ef5591150bd24d3e57a769f65518b16de93487f0fab02271b3d69e2852").unwrap(); + let res = iavl_proof_validation_run_plato(&Bytes::from(input), 3_000u64).unwrap(); + + let gas = res.0; + assert_eq!(gas, 3_000u64); + + let res = hex::encode(res.1); + assert_eq!( + res, + "0000000000000000000000000000000000000000000000000000000000000001" + ) + } +} diff --git a/crates/precompile/src/lib.rs b/crates/precompile/src/lib.rs index 347d3a62..f64fa465 100644 --- a/crates/precompile/src/lib.rs +++ b/crates/precompile/src/lib.rs @@ -14,7 +14,9 @@ mod bls; pub mod bls12_381; pub mod bn128; mod cometbft; +mod double_sign; pub mod hash; +mod iavl; pub mod identity; #[cfg(feature = "c-kzg")] pub mod kzg_point_evaluation; @@ -22,6 +24,8 @@ pub mod modexp; pub mod secp256k1; #[cfg(feature = "secp256r1")] pub mod secp256r1; +mod tendermint; +mod tm_secp256k1; pub mod utilities; use core::hash::Hash; @@ -54,6 +58,7 @@ impl PrecompileOutput { } } } + #[derive(Clone, Default, Debug)] pub struct Precompiles { /// Precompiles. @@ -69,6 +74,13 @@ impl Precompiles { PrecompileSpecId::ISTANBUL => Self::istanbul(), PrecompileSpecId::BERLIN => Self::berlin(), PrecompileSpecId::FERMAT => Self::fermat(), + PrecompileSpecId::NANO => Self::nano(), + PrecompileSpecId::MORAN => Self::moran(), + PrecompileSpecId::PLANCK => Self::planck(), + PrecompileSpecId::LUBAN => Self::luban(), + PrecompileSpecId::PLATO => Self::plato(), + PrecompileSpecId::HERTZ => Self::hertz(), + PrecompileSpecId::FEYNMAN => Self::feynman(), PrecompileSpecId::CANCUN => Self::cancun(), PrecompileSpecId::PRAGUE => Self::prague(), PrecompileSpecId::LATEST => Self::latest(), @@ -121,6 +133,13 @@ impl Precompiles { bn128::mul::ISTANBUL, bn128::pair::ISTANBUL, ]); + + #[cfg(feature = "bsc")] + precompiles.extend([ + tendermint::TENDERMINT_HEADER_VALIDATION, + iavl::IAVL_PROOF_VALIDATION, + ]); + Box::new(precompiles) }) } @@ -158,6 +177,126 @@ impl Precompiles { }) } + /// Returns precompiles for Nano sepc. + pub fn nano() -> &'static Self { + static INSTANCE: OnceBox = OnceBox::new(); + INSTANCE.get_or_init(|| { + let precompiles = Self::berlin().clone(); + let precompiles = { + let mut precompiles = precompiles; + precompiles.extend([ + tendermint::TENDERMINT_HEADER_VALIDATION_NANO, + iavl::IAVL_PROOF_VALIDATION_NANO, + ]); + precompiles + }; + + Box::new(precompiles) + }) + } + + /// Returns precompiles for Moran sepc. + pub fn moran() -> &'static Self { + static INSTANCE: OnceBox = OnceBox::new(); + INSTANCE.get_or_init(|| { + let precompiles = Self::berlin().clone(); + let precompiles = { + let mut precompiles = precompiles; + precompiles.extend([ + tendermint::TENDERMINT_HEADER_VALIDATION, + iavl::IAVL_PROOF_VALIDATION_MORAN, + ]); + precompiles + }; + + Box::new(precompiles) + }) + } + + /// Returns precompiles for Planck sepc. + pub fn planck() -> &'static Self { + static INSTANCE: OnceBox = OnceBox::new(); + INSTANCE.get_or_init(|| { + let precompiles = Self::berlin().clone(); + let precompiles = { + let mut precompiles = precompiles; + precompiles.extend([ + tendermint::TENDERMINT_HEADER_VALIDATION, + iavl::IAVL_PROOF_VALIDATION_PLANCK, + ]); + precompiles + }; + + Box::new(precompiles) + }) + } + + /// Returns precompiles for Luban sepc. + pub fn luban() -> &'static Self { + static INSTANCE: OnceBox = OnceBox::new(); + INSTANCE.get_or_init(|| { + let precompiles = Self::planck().clone(); + let precompiles = { + let mut precompiles = precompiles; + precompiles.extend([ + bls::BLS_SIGNATURE_VALIDATION, + cometbft::COMETBFT_LIGHT_BLOCK_VALIDATION_BEFORE_HERTZ, + ]); + precompiles + }; + + Box::new(precompiles) + }) + } + + /// Returns precompiles for Plato sepc. + pub fn plato() -> &'static Self { + static INSTANCE: OnceBox = OnceBox::new(); + INSTANCE.get_or_init(|| { + let precompiles = Self::luban().clone(); + let precompiles = { + let mut precompiles = precompiles; + precompiles.extend([iavl::IAVL_PROOF_VALIDATION_PLATO]); + precompiles + }; + + Box::new(precompiles) + }) + } + + /// Returns precompiles for Hertz sepc. + pub fn hertz() -> &'static Self { + static INSTANCE: OnceBox = OnceBox::new(); + INSTANCE.get_or_init(|| { + let precompiles = Self::plato().clone(); + let precompiles = { + let mut precompiles = precompiles; + precompiles.extend([cometbft::COMETBFT_LIGHT_BLOCK_VALIDATION]); + precompiles + }; + + Box::new(precompiles) + }) + } + + /// Returns precompiles for Feynman sepc. + pub fn feynman() -> &'static Self { + static INSTANCE: OnceBox = OnceBox::new(); + INSTANCE.get_or_init(|| { + let precompiles = Self::hertz().clone(); + let precompiles = { + let mut precompiles = precompiles; + precompiles.extend([ + tm_secp256k1::TM_SECP256K1_SIGNATURE_RECOVER, + double_sign::DOUBLE_SIGN_EVIDENCE_VALIDATION, + ]); + precompiles + }; + + Box::new(precompiles) + }) + } + /// Returns precompiles for Cancun spec. /// /// If the `c-kzg` feature is not enabled KZG Point Evaluation precompile will not be included, @@ -279,6 +418,15 @@ pub enum PrecompileSpecId { ISTANBUL, BERLIN, FERMAT, + + NANO, // BSC NANO HARDFORK + MORAN, // BSC MORAN HARDFORK + PLANCK, // BSC PLANCK HARDFORK + LUBAN, // BSC LUBAN HARDFORK + PLATO, // BSC PLATO HARDFORK + HERTZ, // BSC HERTZ HARDFORK + FEYNMAN, // BSC FEYNMAN HARDFORK + CANCUN, PRAGUE, LATEST, @@ -294,7 +442,23 @@ impl PrecompileSpecId { } BYZANTIUM | CONSTANTINOPLE | PETERSBURG => Self::BYZANTIUM, ISTANBUL | MUIR_GLACIER => Self::ISTANBUL, + #[cfg(feature = "bsc")] + RAMANUJAN | NIELS | MIRROR_SYNC | BRUNO | EULER => Self::ISTANBUL, + #[cfg(feature = "bsc")] + NANO => Self::NANO, + #[cfg(feature = "bsc")] + MORAN | GIBBS => Self::MORAN, + #[cfg(feature = "bsc")] + PLANCK => Self::PLANCK, + #[cfg(feature = "bsc")] + LUBAN => Self::LUBAN, + #[cfg(feature = "bsc")] + PLATO => Self::PLATO, BERLIN | LONDON | ARROW_GLACIER | GRAY_GLACIER | MERGE | SHANGHAI => Self::BERLIN, + #[cfg(feature = "bsc")] + HERTZ | HERTZ_FIX | KEPLER => Self::HERTZ, + #[cfg(feature = "bsc")] + FEYNMAN | FEYNMAN_FIX | HABER => Self::FEYNMAN, CANCUN => Self::CANCUN, PRAGUE => Self::PRAGUE, LATEST => Self::LATEST, @@ -306,6 +470,8 @@ impl PrecompileSpecId { FERMAT => Self::FERMAT, #[cfg(feature = "opbnb")] HABER => Self::CANCUN, + #[cfg(feature = "opbnb")] + FERMAT => Self::FERMAT, } } } diff --git a/crates/precompile/src/tendermint.rs b/crates/precompile/src/tendermint.rs new file mode 100644 index 00000000..d02b6c4a --- /dev/null +++ b/crates/precompile/src/tendermint.rs @@ -0,0 +1,55 @@ +use crate::{Bytes, Error, Precompile, PrecompileError, PrecompileResult, PrecompileWithAddress}; +use parity_bytes::BytesRef; +use tendermint::lite::light_client; + +/// Tendermint precompile for BSC. +pub(crate) const TENDERMINT_HEADER_VALIDATION: PrecompileWithAddress = PrecompileWithAddress( + crate::u64_to_address(100), + Precompile::Standard(crate::tendermint::tendermint_header_validation_run), +); + +/// Tendermint precompile for BSC after Nano hardfork. +pub(crate) const TENDERMINT_HEADER_VALIDATION_NANO: PrecompileWithAddress = PrecompileWithAddress( + crate::u64_to_address(100), + Precompile::Standard(crate::tendermint::tendermint_header_validation_run_nano), +); + +/// Run the Tendermint header validation precompile after Nano hardfork. +fn tendermint_header_validation_run_nano(_input: &Bytes, _gas_limit: u64) -> PrecompileResult { + return Err(PrecompileError::other("suspended")); +} + +/// Run the Tendermint header validation precompile. +fn tendermint_header_validation_run(input: &Bytes, gas_limit: u64) -> PrecompileResult { + const TENDERMINT_HEADER_VALIDATION_BASE: u64 = 3_000; + + if TENDERMINT_HEADER_VALIDATION_BASE > gas_limit { + return Err(Error::OutOfGas); + } + + let mut output = vec![0u8, 0, 0]; + let mut bytes = BytesRef::Flexible(&mut output); + let res = light_client::TmHeaderVerifier::execute(input.as_ref(), &mut bytes); + match res { + Ok(()) => Ok((TENDERMINT_HEADER_VALIDATION_BASE, Bytes::from(output))), + Err(str) => Err(PrecompileError::Other(String::from(str))), + } +} + +#[cfg(test)] +mod tests { + use super::*; + use revm_primitives::hex; + + #[test] + fn test_tendermint_header_validation_run() { + let input = hex::decode("0000000000000000000000000000000000000000000000000000000000001325000000000000000000000000000000000000000000000000000000000000022042696e616e63652d436861696e2d4e696c6500000000000000000000000000000000000003fc05e2b7029751d2a6581efc2f79712ec44d8b4981850325a7feadaa58ef4ddaa18a9380d9ab0fc10d18ca0e0832d5f4c063c5489ec1443dfb738252d038a82131b27ae17cbe9c20cdcfdf876b3b12978d3264a007fcaaa71c4cdb701d9ebc0323f44f000000174876e800184e7b103d34c41003f9b864d5f8c1adda9bd0436b253bb3c844bc739c1e77c9000000174876e8004d420aea843e92a0cfe69d89696dff6827769f9cb52a249af537ce89bf2a4b74000000174876e800bd03de9f8ab29e2800094e153fac6f696cfa512536c9c2f804dcb2c2c4e4aed6000000174876e8008f4a74a07351895ddf373057b98fae6dfaf2cd21f37a063e19601078fe470d53000000174876e8004a5d4753eb79f92e80efe22df7aca4f666a4f44bf81c536c4a09d4b9c5b654b5000000174876e800c80e9abef7ff439c10c68fe8f1303deddfc527718c3b37d8ba6807446e3c827a000000174876e8009142afcc691b7cc05d26c7b0be0c8b46418294171730e079f384fde2fa50bafc000000174876e80049b288e4ebbb3a281c2d546fc30253d5baf08993b6e5d295fb787a5b314a298e000000174876e80004224339688f012e649de48e241880092eaa8f6aa0f4f14bfcf9e0c76917c0b6000000174876e8004034b37ceda8a0bf13b1abaeee7a8f9383542099a554d219b93d0ce69e3970e8000000174876e800e3210a92130abb020a02080a121242696e616e63652d436861696e2d4e696c6518e38bf01f220c08e191aef20510f5f4e4c70230dae0c7173a480a20102b54820dd8fb5bc2c4e875ee573fa294d9b7b7ceb362aa8fd21b33dee41b1c12240801122082f341511f3e6b89d6177fd31f8a106013ba09d6e12ef40a7dec885d81b687634220b1b77e6977e0cd0177e3102a78833c9e152aa646ed4fb5a77e8af58c9867eec0522080d9ab0fc10d18ca0e0832d5f4c063c5489ec1443dfb738252d038a82131b27a5a2080d9ab0fc10d18ca0e0832d5f4c063c5489ec1443dfb738252d038a82131b27a6220294d8fbd0b94b767a7eba9840f299a3586da7fe6b5dead3b7eecba193c400f936a20a3e248bc209955054d880e4d89ff3c0419c0cd77681f4b4c6649ead5545054b982011462633d9db7ed78e951f79913fdc8231aa77ec12b12d1100a480a207eaabf7df1081377e06e08efe7ad17974049380bdd65a9b053c099ef80ff6e6f122408011220d153cc308d9cb96ca43ffeceaae1ee85794c83d17408ff76cfee92f5e91d0be212b601080210e38bf01f22480a207eaabf7df1081377e06e08efe7ad17974049380bdd65a9b053c099ef80ff6e6f122408011220d153cc308d9cb96ca43ffeceaae1ee85794c83d17408ff76cfee92f5e91d0be22a0b08e291aef20510cebfe23e321406fd60078eb4c2356137dd50036597db267cf61642409276f20ad4b152f91c344bd63ac691bad66e04e228a8b58dca293ff0bd10f8aef6dfbcecae49e32b09d89e10b771a6c01628628596a95e126b04763560c66c0f12b801080210e38bf01f22480a207eaabf7df1081377e06e08efe7ad17974049380bdd65a9b053c099ef80ff6e6f122408011220d153cc308d9cb96ca43ffeceaae1ee85794c83d17408ff76cfee92f5e91d0be22a0b08e291aef20510a4caa532321418e69cc672973992bb5f76d049a5b2c5ddf77436380142409ed2b74fa835296d552e68c439dd4ee3fa94fb197282edcc1cc815c863ca42a2c9a73475ff6be9064371a61655a3c31d2f0acc89c3a4489ad4c2671aef52360512b801080210e38bf01f22480a207eaabf7df1081377e06e08efe7ad17974049380bdd65a9b053c099ef80ff6e6f122408011220d153cc308d9cb96ca43ffeceaae1ee85794c83d17408ff76cfee92f5e91d0be22a0b08e291aef20510a69eca2f3214344c39bb8f4512d6cab1f6aafac1811ef9d8afdf38024240de2768ead90011bcbb1914abc1572749ab7b81382eb81cff3b41c56edc12470a7b8a4d61f8b4ca7b2cb7e24706edd219455796b4db74cd36965859f91dc8910312b801080210e38bf01f22480a207eaabf7df1081377e06e08efe7ad17974049380bdd65a9b053c099ef80ff6e6f122408011220d153cc308d9cb96ca43ffeceaae1ee85794c83d17408ff76cfee92f5e91d0be22a0b08e291aef20510dcdd833b321437ef19af29679b368d2b9e9de3f8769b357866763803424072ddfe0aeb13616b3f17eb60b19a923ec51fcc726625094aa069255c829c8cdd9e242080a1e559b0030fe9a0db19fd34e392bd78df12a9caff9f2b811bc1ac0a12b801080210e38bf01f22480a207eaabf7df1081377e06e08efe7ad17974049380bdd65a9b053c099ef80ff6e6f122408011220d153cc308d9cb96ca43ffeceaae1ee85794c83d17408ff76cfee92f5e91d0be22a0b08e291aef20510e9f2f859321462633d9db7ed78e951f79913fdc8231aa77ec12b38044240f5f61c640ab2402b44936de0d24e7b439df78bc3ef15467ecb29b92ece4aa0550790d5ce80761f2ac4b0e3283969725c42343749d9b44b179b2d4fced66c5d0412b801080210e38bf01f22480a207eaabf7df1081377e06e08efe7ad17974049380bdd65a9b053c099ef80ff6e6f122408011220d153cc308d9cb96ca43ffeceaae1ee85794c83d17408ff76cfee92f5e91d0be22a0b08e291aef20510ff90f55532147b343e041ca130000a8bc00c35152bd7e774003738054240df6e298b3efd42eb536e68a0210bc921e8b5dc145fe965f63f4d3490064f239f2a54a6db16c96086e4ae52280c04ad8b32b44f5ff3d41f0c364949ccb628c50312b801080210e38bf01f22480a207eaabf7df1081377e06e08efe7ad17974049380bdd65a9b053c099ef80ff6e6f122408011220d153cc308d9cb96ca43ffeceaae1ee85794c83d17408ff76cfee92f5e91d0be22a0b08e291aef20510cad7c931321491844d296bd8e591448efc65fd6ad51a888d58fa3806424030298627da1afd28229aac150f553724b594989e59136d6a175d84e45a4dee344ff9e0eeb69fdf29abb6d833adc3e1ccdc87b2a65019ef5fb627c44d9d132c0012b801080210e38bf01f22480a207eaabf7df1081377e06e08efe7ad17974049380bdd65a9b053c099ef80ff6e6f122408011220d153cc308d9cb96ca43ffeceaae1ee85794c83d17408ff76cfee92f5e91d0be22a0b08e291aef20510c8c296323214b3727172ce6473bc780298a2d66c12f1a14f5b2a38074240918491100730b4523f0c85409f6d1cca9ebc4b8ca6df8d55fe3d85158fa43286608693c50332953e1d3b93e3e78b24e158d6a2275ce8c6c7c07a7a646a19200312b801080210e38bf01f22480a207eaabf7df1081377e06e08efe7ad17974049380bdd65a9b053c099ef80ff6e6f122408011220d153cc308d9cb96ca43ffeceaae1ee85794c83d17408ff76cfee92f5e91d0be22a0b08e291aef2051086f1a2403214b6f20c7faa2b2f6f24518fa02b71cb5f4a09fba338084240ca59c9fc7f6ab660e9970fc03e5ed588ccb8be43fe5a3e8450287b726f29d039e53fe888438f178ac63c3d2ca969cd8c2fbc8606f067634339b6a94a7382960212b801080210e38bf01f22480a207eaabf7df1081377e06e08efe7ad17974049380bdd65a9b053c099ef80ff6e6f122408011220d153cc308d9cb96ca43ffeceaae1ee85794c83d17408ff76cfee92f5e91d0be22a0b08e291aef2051080efbb543214e0dd72609cc106210d1aa13936cb67b93a0aee2138094240e787a21f5cb7052624160759a9d379dd9db144f2b498bca026375c9ce8ecdc2a0936af1c309b3a0f686c92bf5578b595a4ca99036a19c9fc50d3718fd454b30012b801080210e38bf01f22480a207eaabf7df1081377e06e08efe7ad17974049380bdd65a9b053c099ef80ff6e6f122408011220d153cc308d9cb96ca43ffeceaae1ee85794c83d17408ff76cfee92f5e91d0be22a0b08e291aef20510ddf8d85a3214fc3108dc3814888f4187452182bc1baf83b71bc9380a4240d51ea31f6449eed71de22339722af1edbb0b21401037d85882b32a2ed8ae9127f2df4d1da2092729e582812856227ed6cdf98a3f60203d1ff80bd635fb03bb0912a4070a4f0a1406fd60078eb4c2356137dd50036597db267cf61612251624de6420e17cbe9c20cdcfdf876b3b12978d3264a007fcaaa71c4cdb701d9ebc0323f44f1880d0dbc3f4022080e0ebdaf2e2ffffff010a4b0a1418e69cc672973992bb5f76d049a5b2c5ddf7743612251624de6420184e7b103d34c41003f9b864d5f8c1adda9bd0436b253bb3c844bc739c1e77c91880d0dbc3f4022080d0dbc3f4020a4b0a14344c39bb8f4512d6cab1f6aafac1811ef9d8afdf12251624de64204d420aea843e92a0cfe69d89696dff6827769f9cb52a249af537ce89bf2a4b741880d0dbc3f4022080d0dbc3f4020a4b0a1437ef19af29679b368d2b9e9de3f8769b3578667612251624de6420bd03de9f8ab29e2800094e153fac6f696cfa512536c9c2f804dcb2c2c4e4aed61880d0dbc3f4022080d0dbc3f4020a4b0a1462633d9db7ed78e951f79913fdc8231aa77ec12b12251624de64208f4a74a07351895ddf373057b98fae6dfaf2cd21f37a063e19601078fe470d531880d0dbc3f4022080d0dbc3f4020a4b0a147b343e041ca130000a8bc00c35152bd7e774003712251624de64204a5d4753eb79f92e80efe22df7aca4f666a4f44bf81c536c4a09d4b9c5b654b51880d0dbc3f4022080d0dbc3f4020a4b0a1491844d296bd8e591448efc65fd6ad51a888d58fa12251624de6420c80e9abef7ff439c10c68fe8f1303deddfc527718c3b37d8ba6807446e3c827a1880d0dbc3f4022080d0dbc3f4020a4b0a14b3727172ce6473bc780298a2d66c12f1a14f5b2a12251624de64209142afcc691b7cc05d26c7b0be0c8b46418294171730e079f384fde2fa50bafc1880d0dbc3f4022080d0dbc3f4020a4b0a14b6f20c7faa2b2f6f24518fa02b71cb5f4a09fba312251624de642049b288e4ebbb3a281c2d546fc30253d5baf08993b6e5d295fb787a5b314a298e1880d0dbc3f4022080d0dbc3f4020a4b0a14e0dd72609cc106210d1aa13936cb67b93a0aee2112251624de642004224339688f012e649de48e241880092eaa8f6aa0f4f14bfcf9e0c76917c0b61880d0dbc3f4022080d0dbc3f4020a4b0a14fc3108dc3814888f4187452182bc1baf83b71bc912251624de64204034b37ceda8a0bf13b1abaeee7a8f9383542099a554d219b93d0ce69e3970e81880d0dbc3f4022080d0dbc3f402124f0a1406fd60078eb4c2356137dd50036597db267cf61612251624de6420e17cbe9c20cdcfdf876b3b12978d3264a007fcaaa71c4cdb701d9ebc0323f44f1880d0dbc3f4022080e0ebdaf2e2ffffff011aa4070a4f0a1406fd60078eb4c2356137dd50036597db267cf61612251624de6420e17cbe9c20cdcfdf876b3b12978d3264a007fcaaa71c4cdb701d9ebc0323f44f1880d0dbc3f4022080e0ebdaf2e2ffffff010a4b0a1418e69cc672973992bb5f76d049a5b2c5ddf7743612251624de6420184e7b103d34c41003f9b864d5f8c1adda9bd0436b253bb3c844bc739c1e77c91880d0dbc3f4022080d0dbc3f4020a4b0a14344c39bb8f4512d6cab1f6aafac1811ef9d8afdf12251624de64204d420aea843e92a0cfe69d89696dff6827769f9cb52a249af537ce89bf2a4b741880d0dbc3f4022080d0dbc3f4020a4b0a1437ef19af29679b368d2b9e9de3f8769b3578667612251624de6420bd03de9f8ab29e2800094e153fac6f696cfa512536c9c2f804dcb2c2c4e4aed61880d0dbc3f4022080d0dbc3f4020a4b0a1462633d9db7ed78e951f79913fdc8231aa77ec12b12251624de64208f4a74a07351895ddf373057b98fae6dfaf2cd21f37a063e19601078fe470d531880d0dbc3f4022080d0dbc3f4020a4b0a147b343e041ca130000a8bc00c35152bd7e774003712251624de64204a5d4753eb79f92e80efe22df7aca4f666a4f44bf81c536c4a09d4b9c5b654b51880d0dbc3f4022080d0dbc3f4020a4b0a1491844d296bd8e591448efc65fd6ad51a888d58fa12251624de6420c80e9abef7ff439c10c68fe8f1303deddfc527718c3b37d8ba6807446e3c827a1880d0dbc3f4022080d0dbc3f4020a4b0a14b3727172ce6473bc780298a2d66c12f1a14f5b2a12251624de64209142afcc691b7cc05d26c7b0be0c8b46418294171730e079f384fde2fa50bafc1880d0dbc3f4022080d0dbc3f4020a4b0a14b6f20c7faa2b2f6f24518fa02b71cb5f4a09fba312251624de642049b288e4ebbb3a281c2d546fc30253d5baf08993b6e5d295fb787a5b314a298e1880d0dbc3f4022080d0dbc3f4020a4b0a14e0dd72609cc106210d1aa13936cb67b93a0aee2112251624de642004224339688f012e649de48e241880092eaa8f6aa0f4f14bfcf9e0c76917c0b61880d0dbc3f4022080d0dbc3f4020a4b0a14fc3108dc3814888f4187452182bc1baf83b71bc912251624de64204034b37ceda8a0bf13b1abaeee7a8f9383542099a554d219b93d0ce69e3970e81880d0dbc3f4022080d0dbc3f402124f0a1406fd60078eb4c2356137dd50036597db267cf61612251624de6420e17cbe9c20cdcfdf876b3b12978d3264a007fcaaa71c4cdb701d9ebc0323f44f1880d0dbc3f4022080e0ebdaf2e2ffffff01").unwrap(); + let res = tendermint_header_validation_run(&Bytes::from(input), 3_000u64).unwrap(); + + let gas = res.0; + assert_eq!(gas, 3_000u64); + + let output = hex::encode(res.1); + assert_eq!(output, "000000000000000000000000000000000000000000000000000000000000022042696e616e63652d436861696e2d4e696c6500000000000000000000000000000000000003fc05e3a3e248bc209955054d880e4d89ff3c0419c0cd77681f4b4c6649ead5545054b980d9ab0fc10d18ca0e0832d5f4c063c5489ec1443dfb738252d038a82131b27ae17cbe9c20cdcfdf876b3b12978d3264a007fcaaa71c4cdb701d9ebc0323f44f000000174876e800184e7b103d34c41003f9b864d5f8c1adda9bd0436b253bb3c844bc739c1e77c9000000174876e8004d420aea843e92a0cfe69d89696dff6827769f9cb52a249af537ce89bf2a4b74000000174876e800bd03de9f8ab29e2800094e153fac6f696cfa512536c9c2f804dcb2c2c4e4aed6000000174876e8008f4a74a07351895ddf373057b98fae6dfaf2cd21f37a063e19601078fe470d53000000174876e8004a5d4753eb79f92e80efe22df7aca4f666a4f44bf81c536c4a09d4b9c5b654b5000000174876e800c80e9abef7ff439c10c68fe8f1303deddfc527718c3b37d8ba6807446e3c827a000000174876e8009142afcc691b7cc05d26c7b0be0c8b46418294171730e079f384fde2fa50bafc000000174876e80049b288e4ebbb3a281c2d546fc30253d5baf08993b6e5d295fb787a5b314a298e000000174876e80004224339688f012e649de48e241880092eaa8f6aa0f4f14bfcf9e0c76917c0b6000000174876e8004034b37ceda8a0bf13b1abaeee7a8f9383542099a554d219b93d0ce69e3970e8000000174876e800"); + } +} diff --git a/crates/precompile/src/tm_secp256k1.rs b/crates/precompile/src/tm_secp256k1.rs new file mode 100644 index 00000000..69d6d446 --- /dev/null +++ b/crates/precompile/src/tm_secp256k1.rs @@ -0,0 +1,130 @@ +use crate::{Bytes, Error, Precompile, PrecompileError, PrecompileResult, PrecompileWithAddress}; +use secp256k1::{ecdsa, Message, PublicKey}; +use tendermint::{account, public_key}; + +/// Tendermint SECP256K1 signature recover precompile for BSC. +pub(crate) const TM_SECP256K1_SIGNATURE_RECOVER: PrecompileWithAddress = PrecompileWithAddress( + crate::u64_to_address(105), + Precompile::Standard(crate::tm_secp256k1::tm_secp256k1_signature_recover_run), +); + +const SECP256K1_PUBKEY_LENGTH: usize = 33; +const SECP256K1_SIGNATURE_LENGTH: usize = 64; +const SECP256K1_SIGNATURE_MSGHASH_LENGTH: usize = 32; + +/// Runs the Tendermint SECP256K1 signature recover precompile. +/// +/// input: +/// +/// | PubKey | Signature | SignatureMsgHash | +/// +/// | 33 bytes | 64 bytes | 32 bytes | +fn tm_secp256k1_signature_recover_run(input: &Bytes, gas_limit: u64) -> PrecompileResult { + const TM_SECP256K1_SIGNATURE_RECOVER_BASE: u64 = 3_000; + + if TM_SECP256K1_SIGNATURE_RECOVER_BASE > gas_limit { + return Err(Error::OutOfGas); + } + + let input_length = input.len(); + if input_length + != SECP256K1_PUBKEY_LENGTH + SECP256K1_SIGNATURE_LENGTH + SECP256K1_SIGNATURE_MSGHASH_LENGTH + { + return Err(PrecompileError::Other(String::from("invalid input"))); + } + + let public_key = match PublicKey::from_slice(&input[..SECP256K1_PUBKEY_LENGTH]) { + Ok(pk) => pk, + Err(_) => return Err(PrecompileError::Other(String::from("invalid pubkey"))), + }; + + let message = Message::from_digest( + input[SECP256K1_PUBKEY_LENGTH + SECP256K1_SIGNATURE_LENGTH..] + .try_into() + .unwrap(), + ); + + let sig = match ecdsa::Signature::from_compact( + &input[SECP256K1_PUBKEY_LENGTH..SECP256K1_PUBKEY_LENGTH + SECP256K1_SIGNATURE_LENGTH], + ) { + Ok(s) => s, + Err(_) => return Err(PrecompileError::Other(String::from("invalid signature"))), + }; + + let res = sig.verify(&message, &public_key).is_ok(); + + if !res { + return Err(PrecompileError::Other(String::from("invalid signature"))); + } + + let tm_pub_key = + match public_key::PublicKey::from_raw_secp256k1(&input[..SECP256K1_PUBKEY_LENGTH]) { + Some(pk) => pk, + None => return Err(PrecompileError::Other(String::from("invalid pubkey"))), + }; + + return Ok(( + TM_SECP256K1_SIGNATURE_RECOVER_BASE, + Bytes::copy_from_slice(account::Id::from(tm_pub_key).as_bytes()), + )); +} + +#[cfg(test)] +mod tests { + use super::*; + use revm_primitives::hex; + + #[test] + fn test_tm_secp256k1_signature_recover_run_local_key() { + let pub_key = + hex::decode("0278caa4d6321aa856d6341dd3e8bcdfe0b55901548871c63c3f5cec43c2ae88a9") + .unwrap(); + let sig = hex::decode("0cb78be0d8eaeab991907b06c61240c04f4ca83f54b7799ce77cf029b837988038c4b3b7f5df231695b0d14499b716e1fd6504860eb3c9244ecb4e569d44c062").unwrap(); + let msg_hash = + hex::decode("b6ac827edff4bbbf23579720782dbef40b65780af292cc66849e7e5944f1230f") + .unwrap(); + + let expect_address = hex::decode("fa3B227adFf8EA1706098928715076D76959Ae6c").unwrap(); + + let mut input = vec![]; + input.extend(pub_key); + input.extend(sig); + input.extend(msg_hash); + + let input = revm_primitives::Bytes::copy_from_slice(&input); + let res = tm_secp256k1_signature_recover_run(&input, 3_000u64).unwrap(); + + let gas = res.0; + assert_eq!(gas, 3_000u64); + + let res = res.1; + assert_eq!(res, Bytes::from(expect_address)); + } + + #[test] + fn test_tm_secp256k1_signature_recover_run_ledger_key() { + let pub_key = + hex::decode("02d63ee39adb1779353b4393dd5ea9d6d2b6df63b71d168571803cc7b9a0a20e98") + .unwrap(); + let sig = hex::decode("66bdb5d381b2773c0f569858c7ee143959522d7c1f46dc656c325cb7353ec40c28ec22dff3650b34c096c5b12e702d7237d409f1ebaaa6dd1128a8f2d401fd5b").unwrap(); + let msg_hash = + hex::decode("c45e8f0dc7c054c31912beeffd6f10f1c585606d61e252e97968cd66661c2571") + .unwrap(); + + let expect_address = hex::decode("65a284146b84210a01add088954bb52d88b230af").unwrap(); + + let mut input = vec![]; + input.extend(pub_key); + input.extend(sig); + input.extend(msg_hash); + + let input = revm_primitives::Bytes::copy_from_slice(&input); + let res = tm_secp256k1_signature_recover_run(&input, 3_000u64).unwrap(); + + let gas = res.0; + assert_eq!(gas, 3_000u64); + + let res = res.1; + assert_eq!(res, Bytes::from(expect_address)); + } +} diff --git a/crates/primitives/Cargo.toml b/crates/primitives/Cargo.toml index ee77dd34..bb6b57c1 100644 --- a/crates/primitives/Cargo.toml +++ b/crates/primitives/Cargo.toml @@ -72,6 +72,7 @@ arbitrary = ["std", "alloy-primitives/arbitrary", "bitflags/arbitrary"] asm-keccak = ["alloy-primitives/asm-keccak"] portable = ["c-kzg?/portable"] +bsc = [] optimism = [] # Optimism default handler enabled Optimism handler register by default in EvmBuilder. optimism-default-handler = ["optimism"] diff --git a/crates/primitives/src/env.rs b/crates/primitives/src/env.rs index 44b07369..19d0fc50 100644 --- a/crates/primitives/src/env.rs +++ b/crates/primitives/src/env.rs @@ -553,6 +553,10 @@ pub struct TxEnv { #[cfg(feature = "optimism")] /// Optimism fields. pub optimism: OptimismFields, + + #[cfg_attr(feature = "serde", serde(flatten))] + #[cfg(feature = "bsc")] + pub bsc: BscFields, } pub enum TxType { @@ -595,6 +599,8 @@ impl Default for TxEnv { max_fee_per_blob_gas: None, #[cfg(feature = "optimism")] optimism: OptimismFields::default(), + #[cfg(feature = "bsc")] + bsc: BscFields::default(), } } } @@ -658,6 +664,15 @@ pub struct OptimismFields { pub enveloped_tx: Option, } +/// Additional [TxEnv] fields for bsc. +#[cfg(feature = "bsc")] +#[derive(Clone, Debug, Default, PartialEq, Eq, Hash)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct BscFields { + /// Whether the transaction is a system transaction. + pub is_system_transaction: Option, +} + /// Transaction destination. #[derive(Clone, Debug, PartialEq, Eq, Hash)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] diff --git a/crates/primitives/src/env/handler_cfg.rs b/crates/primitives/src/env/handler_cfg.rs index f57a3e8c..ed166e15 100644 --- a/crates/primitives/src/env/handler_cfg.rs +++ b/crates/primitives/src/env/handler_cfg.rs @@ -12,6 +12,9 @@ pub struct HandlerCfg { /// Optimism related field, it will append the Optimism handle register to the EVM. #[cfg(feature = "optimism")] pub is_optimism: bool, + /// Bsc related field, it will append the Bsc handle register to the EVM. + #[cfg(feature = "bsc")] + pub is_bsc: bool, } impl Default for HandlerCfg { @@ -35,6 +38,8 @@ impl HandlerCfg { spec_id, #[cfg(feature = "optimism")] is_optimism, + #[cfg(feature = "bsc")] + is_bsc: true, } } @@ -47,6 +52,12 @@ impl HandlerCfg { } } + /// Creates new `HandlerCfg` instance with the bsc feature. + #[cfg(feature = "bsc")] + pub fn new_with_bsc(spec_id: SpecId, is_bsc: bool) -> Self { + Self { spec_id, is_bsc } + } + /// Returns `true` if the optimism feature is enabled and flag is set to `true`. pub fn is_optimism(&self) -> bool { cfg_if::cfg_if! { @@ -57,6 +68,17 @@ impl HandlerCfg { } } } + + /// Returns `true` if the bsc feature is enabled and flag is set to `true`. + pub fn is_bsc(&self) -> bool { + cfg_if::cfg_if! { + if #[cfg(feature = "bsc")] { + self.is_bsc + } else { + false + } + } + } } /// Configuration environment with the chain spec id. @@ -89,6 +111,12 @@ impl CfgEnvWithHandlerCfg { pub fn enable_optimism(&mut self) { self.handler_cfg.is_optimism = true; } + + /// Enables the bsc feature. + #[cfg(feature = "bsc")] + pub fn enable_bsc(&mut self) { + self.handler_cfg.is_bsc = true; + } } impl DerefMut for CfgEnvWithHandlerCfg { @@ -142,6 +170,12 @@ impl EnvWithHandlerCfg { pub fn enable_optimism(&mut self) { self.handler_cfg.is_optimism = true; } + + /// Enables the bsc handle register. + #[cfg(feature = "bsc")] + pub fn enable_bsc(&mut self) { + self.handler_cfg.is_bsc = true; + } } impl DerefMut for EnvWithHandlerCfg { diff --git a/crates/primitives/src/specification.rs b/crates/primitives/src/specification.rs index fce209ef..5bc6033d 100644 --- a/crates/primitives/src/specification.rs +++ b/crates/primitives/src/specification.rs @@ -5,7 +5,7 @@ pub use SpecId::*; /// Specification IDs and their activation block. /// /// Information was obtained from the [Ethereum Execution Specifications](https://github.com/ethereum/execution-specs) -#[cfg(not(feature = "optimism"))] +#[cfg(all(not(feature = "optimism"), not(feature = "bsc")))] #[repr(u8)] #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash, enumn::N)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] @@ -71,6 +71,56 @@ pub enum SpecId { LATEST = u8::MAX, } +/// Specification IDs and their activation block of BSC. +#[cfg(feature = "bsc")] +#[repr(u8)] +#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash, enumn::N)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub enum SpecId { + FRONTIER = 0, + FRONTIER_THAWING = 1, + HOMESTEAD = 2, // Homestead 0 + TANGERINE = 3, // Tangerine Whistle(EIP150) 0 + SPURIOUS_DRAGON = 4, // Spurious Dragon(EIP155, EIP158) 0 + BYZANTIUM = 5, // Byzantium 0 + CONSTANTINOPLE = 6, // Constantinople 0 + PETERSBURG = 7, // Petersburg 0 + ISTANBUL = 8, // Istanbul 0 + MUIR_GLACIER = 9, // Muir Glacier 0 + RAMANUJAN = 10, // Ramanujan 0 + NIELS = 11, // Niels 0 + MIRROR_SYNC = 12, // Mirror Sync 5184000 + BRUNO = 13, // Bruno 13082000 + EULER = 14, // Euler 18907621 + NANO = 15, // Nano 21962149 + MORAN = 16, // Moran 22107423 + GIBBS = 17, // Gibbs 23846001 + PLANCK = 18, // Planck 27281024 + LUBAN = 19, // Luban 29020050 + PLATO = 20, // Plato 30720096 + BERLIN = 21, // Berlin 31302048 + LONDON = 22, // London 31302048 + HERTZ = 23, // Hertz 31302048 + HERTZ_FIX = 24, // HertzFix 34140700 + SHANGHAI = 25, // Shanghai timestamp(1705996800) 2024-01-23 08:00:00 AM UTC + KEPLER = 26, // Kepler timestamp(1705996800) 2024-01-23 08:00:00 AM UTC + FEYNMAN = 27, // Feynman timestamp(1713419340) 2024-04-18 05:49:00 AM UTC + FEYNMAN_FIX = 28, // FeynmanFix timestamp(1713419340) 2024-04-18 05:49:00 AM UTC + CANCUN = 29, // Cancun timestamp(1718863500) 2024-06-20 06:05:00 AM UTC + HABER = 30, // Haber TBD + + // TODO: or u8::MAX - n? + /// Not enabled in bsc + DAO_FORK = 31, + ARROW_GLACIER = 32, + GRAY_GLACIER = 33, + MERGE = 34, + PRAGUE = 35, + + #[default] + LATEST = u8::MAX, +} + impl SpecId { /// Returns the `SpecId` for the given `u8`. #[inline] @@ -92,6 +142,7 @@ impl SpecId { } impl From<&str> for SpecId { + #[cfg(not(feature = "bsc"))] fn from(name: &str) -> Self { match name { "Frontier" => Self::FRONTIER, @@ -121,7 +172,44 @@ impl From<&str> for SpecId { "Ecotone" => SpecId::ECOTONE, #[cfg(feature = "optimism")] "Fjord" => SpecId::FJORD, - #[cfg(feature = "opbnb")] + #[cfg(any(feature = "opbnb"))] + "Haber" => SpecId::HABER, + _ => Self::LATEST, + } + } + + #[cfg(feature = "bsc")] + fn from(name: &str) -> Self { + match name { + "Frontier" => Self::FRONTIER, + "Homestead" => Self::HOMESTEAD, + "Tangerine" => Self::TANGERINE, + "Spurious" => Self::SPURIOUS_DRAGON, + "Byzantium" => Self::BYZANTIUM, + "Constantinople" => Self::CONSTANTINOPLE, + "Petersburg" => Self::PETERSBURG, + "Istanbul" => Self::ISTANBUL, + "MuirGlacier" => Self::MUIR_GLACIER, + "Berlin" => Self::BERLIN, + "London" => Self::LONDON, + "Shanghai" => Self::SHANGHAI, + "Cancun" => Self::CANCUN, + "Ramanujan" => SpecId::RAMANUJAN, + "Niels" => SpecId::NIELS, + "MirrorSync" => SpecId::MIRROR_SYNC, + "Bruno" => SpecId::BRUNO, + "Euler" => SpecId::EULER, + "Nano" => SpecId::NANO, + "Moran" => SpecId::MORAN, + "Gibbs" => SpecId::GIBBS, + "Planck" => SpecId::PLANCK, + "Luban" => SpecId::LUBAN, + "Plato" => SpecId::PLATO, + "Hertz" => SpecId::HERTZ, + "HertzFix" => SpecId::HERTZ_FIX, + "Kepler" => SpecId::KEPLER, + "Feynman" => SpecId::FEYNMAN, + "FeynmanFix" => SpecId::FEYNMAN_FIX, "Haber" => SpecId::HABER, _ => Self::LATEST, } @@ -129,6 +217,7 @@ impl From<&str> for SpecId { } impl From for &'static str { + #[cfg(not(feature = "bsc"))] fn from(spec_id: SpecId) -> Self { match spec_id { SpecId::FRONTIER => "Frontier", @@ -156,15 +245,54 @@ impl From for &'static str { SpecId::REGOLITH => "Regolith", #[cfg(feature = "opbnb")] SpecId::FERMAT => "Fermat", - #[cfg(feature = "opbnb")] - SpecId::HABER => "Haber", #[cfg(feature = "optimism")] SpecId::CANYON => "Canyon", #[cfg(feature = "optimism")] SpecId::ECOTONE => "Ecotone", #[cfg(feature = "optimism")] SpecId::FJORD => "Fjord", + #[cfg(feature = "opbnb")] + SpecId::HABER => "Haber", + SpecId::LATEST => "Latest", + } + } + + #[cfg(feature = "bsc")] + fn from(spec_id: SpecId) -> Self { + match spec_id { + SpecId::FRONTIER => "Frontier", + SpecId::FRONTIER_THAWING => "Frontier Thawing", + SpecId::HOMESTEAD => "Homestead", + SpecId::TANGERINE => "Tangerine", + SpecId::SPURIOUS_DRAGON => "Spurious", + SpecId::BYZANTIUM => "Byzantium", + SpecId::CONSTANTINOPLE => "Constantinople", + SpecId::PETERSBURG => "Petersburg", + SpecId::ISTANBUL => "Istanbul", + SpecId::MUIR_GLACIER => "MuirGlacier", + SpecId::BERLIN => "Berlin", + SpecId::LONDON => "London", + SpecId::SHANGHAI => "Shanghai", + SpecId::CANCUN => "Cancun", + SpecId::RAMANUJAN => "Ramanujan", + SpecId::NIELS => "Niels", + SpecId::MIRROR_SYNC => "MirrorSync", + SpecId::BRUNO => "Bruno", + SpecId::EULER => "Euler", + SpecId::NANO => "Nano", + SpecId::MORAN => "Moran", + SpecId::GIBBS => "Gibbs", + SpecId::PLANCK => "Planck", + SpecId::LUBAN => "Luban", + SpecId::PLATO => "Plato", + SpecId::HERTZ => "Hertz", + SpecId::HERTZ_FIX => "HertzFix", + SpecId::KEPLER => "Kepler", + SpecId::FEYNMAN => "Feynman", + SpecId::FEYNMAN_FIX => "FeynmanFix", + SpecId::HABER => "Haber", SpecId::LATEST => "Latest", + _ => "Unknown", } } } @@ -213,6 +341,43 @@ spec!(PRAGUE, PragueSpec); spec!(LATEST, LatestSpec); +// BSC Hardforks +// TODO: some of these hardforks may have no EVM spec change +#[cfg(feature = "bsc")] +spec!(RAMANUJAN, RamanujanSpec); +#[cfg(feature = "bsc")] +spec!(NIELS, NielsSpec); +#[cfg(feature = "bsc")] +spec!(MIRROR_SYNC, MirrorSyncSpec); +#[cfg(feature = "bsc")] +spec!(BRUNO, BrunoSpec); +#[cfg(feature = "bsc")] +spec!(EULER, EulerSpec); +#[cfg(feature = "bsc")] +spec!(NANO, NanoSpec); +#[cfg(feature = "bsc")] +spec!(MORAN, MoranSpec); +#[cfg(feature = "bsc")] +spec!(GIBBS, GibbsSpec); +#[cfg(feature = "bsc")] +spec!(PLANCK, PlanckSpec); +#[cfg(feature = "bsc")] +spec!(LUBAN, LubanSpec); +#[cfg(feature = "bsc")] +spec!(PLATO, PlatoSpec); +#[cfg(feature = "bsc")] +spec!(HERTZ, HertzSpec); +#[cfg(feature = "bsc")] +spec!(HERTZ_FIX, HertzFixSpec); +#[cfg(feature = "bsc")] +spec!(KEPLER, KeplerSpec); +#[cfg(feature = "bsc")] +spec!(FEYNMAN, FeynmanSpec); +#[cfg(feature = "bsc")] +spec!(FEYNMAN_FIX, FeynmanFixSpec); +#[cfg(any(feature = "bsc", feature = "opbnb"))] +spec!(HABER, HaberSpec); + // Optimism Hardforks #[cfg(feature = "optimism")] spec!(BEDROCK, BedrockSpec); @@ -226,10 +391,8 @@ spec!(ECOTONE, EcotoneSpec); spec!(FJORD, FjordSpec); #[cfg(feature = "opbnb")] spec!(FERMAT, FermatSpec); -#[cfg(feature = "opbnb")] -spec!(HABER, HaberSpec); -#[cfg(not(feature = "optimism"))] +#[cfg(all(not(feature = "optimism"), not(feature = "bsc")))] #[macro_export] macro_rules! spec_to_generic { ($spec_id:expr, $e:expr) => {{ @@ -266,9 +429,9 @@ macro_rules! spec_to_generic { use $crate::BerlinSpec as SPEC; $e } - $crate::SpecId::LONDON - | $crate::SpecId::ARROW_GLACIER - | $crate::SpecId::GRAY_GLACIER => { + $crate::SpecId::LONDON | + $crate::SpecId::ARROW_GLACIER | + $crate::SpecId::GRAY_GLACIER => { use $crate::LondonSpec as SPEC; $e } @@ -333,9 +496,9 @@ macro_rules! spec_to_generic { use $crate::BerlinSpec as SPEC; $e } - $crate::SpecId::LONDON - | $crate::SpecId::ARROW_GLACIER - | $crate::SpecId::GRAY_GLACIER => { + $crate::SpecId::LONDON | + $crate::SpecId::ARROW_GLACIER | + $crate::SpecId::GRAY_GLACIER => { use $crate::LondonSpec as SPEC; $e } @@ -393,6 +556,141 @@ macro_rules! spec_to_generic { }}; } +#[cfg(feature = "bsc")] +#[macro_export] +macro_rules! spec_to_generic { + ($spec_id:expr, $e:expr) => {{ + match $spec_id { + $crate::SpecId::FRONTIER | SpecId::FRONTIER_THAWING => { + use $crate::FrontierSpec as SPEC; + $e + } + $crate::SpecId::HOMESTEAD | SpecId::DAO_FORK => { + use $crate::HomesteadSpec as SPEC; + $e + } + $crate::SpecId::TANGERINE => { + use $crate::TangerineSpec as SPEC; + $e + } + $crate::SpecId::SPURIOUS_DRAGON => { + use $crate::SpuriousDragonSpec as SPEC; + $e + } + $crate::SpecId::BYZANTIUM => { + use $crate::ByzantiumSpec as SPEC; + $e + } + $crate::SpecId::PETERSBURG | $crate::SpecId::CONSTANTINOPLE => { + use $crate::PetersburgSpec as SPEC; + $e + } + $crate::SpecId::ISTANBUL | $crate::SpecId::MUIR_GLACIER => { + use $crate::IstanbulSpec as SPEC; + $e + } + $crate::SpecId::BERLIN => { + use $crate::BerlinSpec as SPEC; + $e + } + $crate::SpecId::LONDON | + $crate::SpecId::ARROW_GLACIER | + $crate::SpecId::GRAY_GLACIER => { + use $crate::LondonSpec as SPEC; + $e + } + $crate::SpecId::MERGE => { + use $crate::MergeSpec as SPEC; + $e + } + $crate::SpecId::SHANGHAI => { + use $crate::ShanghaiSpec as SPEC; + $e + } + $crate::SpecId::CANCUN => { + use $crate::CancunSpec as SPEC; + $e + } + $crate::SpecId::LATEST => { + use $crate::LatestSpec as SPEC; + $e + } + $crate::SpecId::PRAGUE => { + use $crate::PragueSpec as SPEC; + $e + } + $crate::SpecId::RAMANUJAN => { + use $crate::RamanujanSpec as SPEC; + $e + } + $crate::SpecId::NIELS => { + use $crate::NielsSpec as SPEC; + $e + } + $crate::SpecId::MIRROR_SYNC => { + use $crate::MirrorSyncSpec as SPEC; + $e + } + $crate::SpecId::BRUNO => { + use $crate::BrunoSpec as SPEC; + $e + } + $crate::SpecId::EULER => { + use $crate::EulerSpec as SPEC; + $e + } + $crate::SpecId::NANO => { + use $crate::NanoSpec as SPEC; + $e + } + $crate::SpecId::MORAN => { + use $crate::MoranSpec as SPEC; + $e + } + $crate::SpecId::GIBBS => { + use $crate::GibbsSpec as SPEC; + $e + } + $crate::SpecId::PLANCK => { + use $crate::PlanckSpec as SPEC; + $e + } + $crate::SpecId::LUBAN => { + use $crate::LubanSpec as SPEC; + $e + } + $crate::SpecId::PLATO => { + use $crate::PlatoSpec as SPEC; + $e + } + $crate::SpecId::HERTZ => { + use $crate::HertzSpec as SPEC; + $e + } + $crate::SpecId::HERTZ_FIX => { + use $crate::HertzFixSpec as SPEC; + $e + } + $crate::SpecId::KEPLER => { + use $crate::KeplerSpec as SPEC; + $e + } + $crate::SpecId::FEYNMAN => { + use $crate::FeynmanSpec as SPEC; + $e + } + $crate::SpecId::FEYNMAN_FIX => { + use $crate::FeynmanFixSpec as SPEC; + $e + } + $crate::SpecId::HABER => { + use $crate::HaberSpec as SPEC; + $e + } + } + }}; +} + #[cfg(test)] mod tests { use super::*; @@ -404,6 +702,7 @@ mod tests { spec_to_generic!(FRONTIER, assert_eq!(SPEC::SPEC_ID, FRONTIER)); spec_to_generic!(FRONTIER_THAWING, assert_eq!(SPEC::SPEC_ID, FRONTIER)); spec_to_generic!(HOMESTEAD, assert_eq!(SPEC::SPEC_ID, HOMESTEAD)); + #[cfg(not(feature = "bsc"))] spec_to_generic!(DAO_FORK, assert_eq!(SPEC::SPEC_ID, HOMESTEAD)); spec_to_generic!(TANGERINE, assert_eq!(SPEC::SPEC_ID, TANGERINE)); spec_to_generic!(SPURIOUS_DRAGON, assert_eq!(SPEC::SPEC_ID, SPURIOUS_DRAGON)); @@ -414,23 +713,66 @@ mod tests { spec_to_generic!(MUIR_GLACIER, assert_eq!(SPEC::SPEC_ID, ISTANBUL)); spec_to_generic!(BERLIN, assert_eq!(SPEC::SPEC_ID, BERLIN)); spec_to_generic!(LONDON, assert_eq!(SPEC::SPEC_ID, LONDON)); + #[cfg(not(feature = "bsc"))] spec_to_generic!(ARROW_GLACIER, assert_eq!(SPEC::SPEC_ID, LONDON)); + #[cfg(not(feature = "bsc"))] spec_to_generic!(GRAY_GLACIER, assert_eq!(SPEC::SPEC_ID, LONDON)); + #[cfg(not(feature = "bsc"))] spec_to_generic!(MERGE, assert_eq!(SPEC::SPEC_ID, MERGE)); #[cfg(feature = "optimism")] spec_to_generic!(BEDROCK, assert_eq!(SPEC::SPEC_ID, BEDROCK)); #[cfg(feature = "optimism")] spec_to_generic!(REGOLITH, assert_eq!(SPEC::SPEC_ID, REGOLITH)); + #[cfg(feature = "opbnb")] + spec_to_generic!(FERMAT, assert_eq!(SPEC::SPEC_ID, FERMAT)); spec_to_generic!(SHANGHAI, assert_eq!(SPEC::SPEC_ID, SHANGHAI)); #[cfg(feature = "optimism")] spec_to_generic!(CANYON, assert_eq!(SPEC::SPEC_ID, CANYON)); + #[cfg(feature = "optimism")] + spec_to_generic!(ECOTONE, assert_eq!(SPEC::SPEC_ID, ECOTONE)); spec_to_generic!(CANCUN, assert_eq!(SPEC::SPEC_ID, CANCUN)); #[cfg(feature = "optimism")] spec_to_generic!(ECOTONE, assert_eq!(SPEC::SPEC_ID, ECOTONE)); #[cfg(feature = "optimism")] spec_to_generic!(FJORD, assert_eq!(SPEC::SPEC_ID, FJORD)); + #[cfg(not(feature = "bsc"))] spec_to_generic!(PRAGUE, assert_eq!(SPEC::SPEC_ID, PRAGUE)); + #[cfg(any(feature = "bsc", feature = "opbnb"))] + spec_to_generic!(HABER, assert_eq!(SPEC::SPEC_ID, HABER)); spec_to_generic!(LATEST, assert_eq!(SPEC::SPEC_ID, LATEST)); + + #[cfg(feature = "bsc")] + spec_to_generic!(RAMANUJAN, assert_eq!(SPEC::SPEC_ID, RAMANUJAN)); + #[cfg(feature = "bsc")] + spec_to_generic!(NIELS, assert_eq!(SPEC::SPEC_ID, NIELS)); + #[cfg(feature = "bsc")] + spec_to_generic!(MIRROR_SYNC, assert_eq!(SPEC::SPEC_ID, MIRROR_SYNC)); + #[cfg(feature = "bsc")] + spec_to_generic!(BRUNO, assert_eq!(SPEC::SPEC_ID, BRUNO)); + #[cfg(feature = "bsc")] + spec_to_generic!(EULER, assert_eq!(SPEC::SPEC_ID, EULER)); + #[cfg(feature = "bsc")] + spec_to_generic!(NANO, assert_eq!(SPEC::SPEC_ID, NANO)); + #[cfg(feature = "bsc")] + spec_to_generic!(MORAN, assert_eq!(SPEC::SPEC_ID, MORAN)); + #[cfg(feature = "bsc")] + spec_to_generic!(GIBBS, assert_eq!(SPEC::SPEC_ID, GIBBS)); + #[cfg(feature = "bsc")] + spec_to_generic!(PLANCK, assert_eq!(SPEC::SPEC_ID, PLANCK)); + #[cfg(feature = "bsc")] + spec_to_generic!(LUBAN, assert_eq!(SPEC::SPEC_ID, LUBAN)); + #[cfg(feature = "bsc")] + spec_to_generic!(PLATO, assert_eq!(SPEC::SPEC_ID, PLATO)); + #[cfg(feature = "bsc")] + spec_to_generic!(HERTZ, assert_eq!(SPEC::SPEC_ID, HERTZ)); + #[cfg(feature = "bsc")] + spec_to_generic!(HERTZ_FIX, assert_eq!(SPEC::SPEC_ID, HERTZ_FIX)); + #[cfg(feature = "bsc")] + spec_to_generic!(KEPLER, assert_eq!(SPEC::SPEC_ID, KEPLER)); + #[cfg(feature = "bsc")] + spec_to_generic!(FEYNMAN, assert_eq!(SPEC::SPEC_ID, FEYNMAN)); + #[cfg(feature = "bsc")] + spec_to_generic!(FEYNMAN_FIX, assert_eq!(SPEC::SPEC_ID, FEYNMAN_FIX)); } } diff --git a/crates/revm/Cargo.toml b/crates/revm/Cargo.toml index aaddcb58..55a048a3 100644 --- a/crates/revm/Cargo.toml +++ b/crates/revm/Cargo.toml @@ -88,6 +88,7 @@ portable = ["revm-precompile/portable", "revm-interpreter/portable"] test-utils = [] +bsc = ["revm-interpreter/bsc", "revm-precompile/bsc"] optimism = ["revm-interpreter/optimism", "revm-precompile/optimism"] # Optimism default handler enabled Optimism handler register by default in EvmBuilder. optimism-default-handler = [ diff --git a/crates/revm/src/bsc.rs b/crates/revm/src/bsc.rs new file mode 100644 index 00000000..980d2e85 --- /dev/null +++ b/crates/revm/src/bsc.rs @@ -0,0 +1,7 @@ +//! Optimism-specific constants, types, and helpers. + +mod handler_register; + +pub use handler_register::{ + bsc_handle_register, collect_system_reward, output, validate_initial_tx_gas, SYSTEM_ADDRESS, +}; diff --git a/crates/revm/src/bsc/handler_register.rs b/crates/revm/src/bsc/handler_register.rs new file mode 100644 index 00000000..788d3334 --- /dev/null +++ b/crates/revm/src/bsc/handler_register.rs @@ -0,0 +1,115 @@ +//! Handler related to BNB-Smart-chain + +use crate::{ + handler::register::EvmHandler, + interpreter::Gas, + primitives::{ + address, db::Database, spec_to_generic, Address, EVMError, Env, ExecutionResult, + InvalidTransaction, ResultAndState, Spec, SpecId, U256, + }, + Context, FrameResult, +}; +use revm_interpreter::{gas, SuccessOrHalt}; +use std::sync::Arc; + +pub const SYSTEM_ADDRESS: Address = address!("fffffffffffffffffffffffffffffffffffffffe"); + +pub fn bsc_handle_register(handler: &mut EvmHandler<'_, EXT, DB>) { + spec_to_generic!(handler.cfg.spec_id, { + handler.validation.initial_tx_gas = Arc::new(validate_initial_tx_gas::); + handler.post_execution.reward_beneficiary = + Arc::new(collect_system_reward::); + handler.post_execution.output = Arc::new(output::); + }); +} + +/// Validate initial transaction gas. +pub fn validate_initial_tx_gas( + env: &Env, +) -> Result> { + // no initial gas for system transactions + if env.tx.bsc.is_system_transaction.unwrap_or(false) { + return Ok(0); + } + + let input = &env.tx.data; + let is_create = env.tx.transact_to.is_create(); + let access_list = &env.tx.access_list; + + let initial_gas_spend = gas::validate_initial_tx_gas(SPEC::SPEC_ID, input, is_create, access_list); + + // Additional check to see if limit is big enough to cover initial gas. + if initial_gas_spend > env.tx.gas_limit { + return Err(InvalidTransaction::CallGasCostMoreThanGasLimit.into()); + } + Ok(initial_gas_spend) +} + +/// Collect gas fee to system account. +#[inline] +pub fn collect_system_reward( + context: &mut Context, + gas: &Gas, +) -> Result<(), EVMError> { + let effective_gas_price = context.evm.env.effective_gas_price(); + + let (system_account, _) = context + .evm + .inner + .journaled_state + .load_account(SYSTEM_ADDRESS, &mut context.evm.inner.db)?; + + system_account.mark_touch(); + system_account.info.balance = system_account + .info + .balance + .saturating_add(effective_gas_price * U256::from(gas.spent() - gas.refunded() as u64)); + + Ok(()) +} + +/// Main return handle, returns the output of the transaction. +#[inline] +pub fn output( + context: &mut Context, + result: FrameResult, +) -> Result> { + core::mem::replace(&mut context.evm.error, Ok(()))?; + // used gas with refund calculated. + let gas_refunded = if context.evm.env.tx.bsc.is_system_transaction.unwrap_or(false) { + 0 + } else { + result.gas().refunded() as u64 + }; + let final_gas_used = result.gas().spent() - gas_refunded; + let output = result.output(); + let instruction_result = result.into_interpreter_result(); + + // reset journal and return present state. + let (state, logs) = context.evm.journaled_state.finalize(); + + let result = match instruction_result.result.into() { + SuccessOrHalt::Success(reason) => ExecutionResult::Success { + reason, + gas_used: final_gas_used, + gas_refunded, + logs, + output, + }, + SuccessOrHalt::Revert => { + ExecutionResult::Revert { gas_used: final_gas_used, output: output.into_data() } + } + SuccessOrHalt::Halt(reason) => ExecutionResult::Halt { reason, gas_used: final_gas_used }, + // Only two internal return flags. + flag @ (SuccessOrHalt::FatalExternalError | + SuccessOrHalt::InternalContinue | + SuccessOrHalt::InternalCallOrCreate) => { + panic!( + "Encountered unexpected internal return flag: {:?} with instruction result: {:?}", + flag, instruction_result + ) + } + }; + + Ok(ResultAndState { result, state }) +} diff --git a/crates/revm/src/builder.rs b/crates/revm/src/builder.rs index 4b2a81ec..d15ed12c 100644 --- a/crates/revm/src/builder.rs +++ b/crates/revm/src/builder.rs @@ -168,6 +168,17 @@ impl<'a, EXT, DB: Database> EvmBuilder<'a, SetGenericStage, EXT, DB> { } } + /// Sets the Bsc handler with latest spec. + #[cfg(feature = "bsc")] + pub fn bsc(mut self) -> EvmBuilder<'a, HandlerStage, EXT, DB> { + self.handler = Handler::bsc_with_spec(self.handler.cfg.spec_id); + EvmBuilder { + context: self.context, + handler: self.handler, + phantom: PhantomData, + } + } + /// Sets the mainnet handler with latest spec. /// /// Enabled only with `optimism-default-handler` feature. diff --git a/crates/revm/src/handler.rs b/crates/revm/src/handler.rs index fab20b12..66f2561b 100644 --- a/crates/revm/src/handler.rs +++ b/crates/revm/src/handler.rs @@ -43,6 +43,7 @@ impl<'a, EXT, DB: Database> EvmHandler<'a, EXT, DB> { /// /// Internally it calls `mainnet_with_spec` with the given spec id. /// Or `optimism_with_spec` if the optimism feature is enabled and `cfg.is_optimism` is set. + /// Or `bsc_with_spec` if the bsc feature is enabled and `cfg.is_bsc` is set. pub fn new(cfg: HandlerCfg) -> Self { cfg_if::cfg_if! { if #[cfg(feature = "optimism")] { @@ -51,6 +52,8 @@ impl<'a, EXT, DB: Database> EvmHandler<'a, EXT, DB> { } else { Handler::mainnet_with_spec(cfg.spec_id) } + } else if #[cfg(feature = "bsc")] { + Handler::bsc_with_spec(cfg.spec_id) } else { Handler::mainnet_with_spec(cfg.spec_id) } @@ -70,6 +73,12 @@ impl<'a, EXT, DB: Database> EvmHandler<'a, EXT, DB> { } } + /// Creates handler with variable spec id, inside it will call `mainnet::` for + /// appropriate spec. + pub fn mainnet_with_spec(spec_id: SpecId) -> Self { + spec_to_generic!(spec_id, Self::mainnet::()) + } + /// Returns `true` if the optimism feature is enabled and flag is set to `true`. pub fn is_optimism(&self) -> bool { self.cfg.is_optimism() @@ -92,10 +101,26 @@ impl<'a, EXT, DB: Database> EvmHandler<'a, EXT, DB> { spec_to_generic!(spec_id, Self::optimism::()) } - /// Creates handler with variable spec id, inside it will call `mainnet::` for - /// appropriate spec. - pub fn mainnet_with_spec(spec_id: SpecId) -> Self { - spec_to_generic!(spec_id, Self::mainnet::()) + /// Returns `true` if the bsc feature is enabled and flag is set to `true`. + pub fn is_bsc(&self) -> bool { + self.cfg.is_bsc() + } + + /// Handler for bsc + #[cfg(feature = "bsc")] + pub fn bsc() -> Self { + let mut handler = Self::mainnet::(); + handler.cfg.is_bsc = true; + handler.append_handler_register(HandleRegisters::Plain( + crate::bsc::bsc_handle_register::, + )); + handler + } + + /// Bsc with spec. Similar to [`Self::mainnet_with_spec`]. + #[cfg(feature = "bsc")] + pub fn bsc_with_spec(spec_id: SpecId) -> Self { + spec_to_generic!(spec_id, Self::bsc::()) } /// Specification ID. diff --git a/crates/revm/src/lib.rs b/crates/revm/src/lib.rs index 6b69b5bd..5f981677 100644 --- a/crates/revm/src/lib.rs +++ b/crates/revm/src/lib.rs @@ -22,6 +22,8 @@ mod inspector; mod journaled_state; #[cfg(feature = "optimism")] pub mod optimism; +#[cfg(feature = "bsc")] +pub mod bsc; // Export items. From b4e356231e816df260c920d7b030384b771a5c58 Mon Sep 17 00:00:00 2001 From: Roshan Date: Thu, 6 Jun 2024 22:51:55 +0800 Subject: [PATCH 02/18] fix precompile contracts error --- crates/precompile/src/lib.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/crates/precompile/src/lib.rs b/crates/precompile/src/lib.rs index f64fa465..91d71c8f 100644 --- a/crates/precompile/src/lib.rs +++ b/crates/precompile/src/lib.rs @@ -181,7 +181,7 @@ impl Precompiles { pub fn nano() -> &'static Self { static INSTANCE: OnceBox = OnceBox::new(); INSTANCE.get_or_init(|| { - let precompiles = Self::berlin().clone(); + let precompiles = Self::istanbul().clone(); let precompiles = { let mut precompiles = precompiles; precompiles.extend([ @@ -199,7 +199,7 @@ impl Precompiles { pub fn moran() -> &'static Self { static INSTANCE: OnceBox = OnceBox::new(); INSTANCE.get_or_init(|| { - let precompiles = Self::berlin().clone(); + let precompiles = Self::istanbul().clone(); let precompiles = { let mut precompiles = precompiles; precompiles.extend([ @@ -217,7 +217,7 @@ impl Precompiles { pub fn planck() -> &'static Self { static INSTANCE: OnceBox = OnceBox::new(); INSTANCE.get_or_init(|| { - let precompiles = Self::berlin().clone(); + let precompiles = Self::istanbul().clone(); let precompiles = { let mut precompiles = precompiles; precompiles.extend([ From 655764e9558e1b6aa9b98b5589d77c0b2a7772df Mon Sep 17 00:00:00 2001 From: Roshan Date: Fri, 7 Jun 2024 02:31:50 +0800 Subject: [PATCH 03/18] optimize `specification` setting --- crates/precompile/src/lib.rs | 4 +- crates/primitives/src/specification.rs | 204 +++++++++---------------- 2 files changed, 73 insertions(+), 135 deletions(-) diff --git a/crates/precompile/src/lib.rs b/crates/precompile/src/lib.rs index 91d71c8f..e02fc3e9 100644 --- a/crates/precompile/src/lib.rs +++ b/crates/precompile/src/lib.rs @@ -461,7 +461,6 @@ impl PrecompileSpecId { FEYNMAN | FEYNMAN_FIX | HABER => Self::FEYNMAN, CANCUN => Self::CANCUN, PRAGUE => Self::PRAGUE, - LATEST => Self::LATEST, #[cfg(feature = "optimism")] BEDROCK | REGOLITH | CANYON => Self::BERLIN, #[cfg(feature = "optimism")] @@ -470,8 +469,7 @@ impl PrecompileSpecId { FERMAT => Self::FERMAT, #[cfg(feature = "opbnb")] HABER => Self::CANCUN, - #[cfg(feature = "opbnb")] - FERMAT => Self::FERMAT, + LATEST => Self::LATEST, } } } diff --git a/crates/primitives/src/specification.rs b/crates/primitives/src/specification.rs index 5bc6033d..3858581b 100644 --- a/crates/primitives/src/specification.rs +++ b/crates/primitives/src/specification.rs @@ -1,5 +1,8 @@ #![allow(non_camel_case_types)] +#[cfg(all(feature = "optimism", feature = "bsc"))] +compile_error!("Features 'optimism' and 'bsc' cannot be enabled together."); + pub use SpecId::*; /// Specification IDs and their activation block. @@ -142,7 +145,6 @@ impl SpecId { } impl From<&str> for SpecId { - #[cfg(not(feature = "bsc"))] fn from(name: &str) -> Self { match name { "Frontier" => Self::FRONTIER, @@ -172,44 +174,39 @@ impl From<&str> for SpecId { "Ecotone" => SpecId::ECOTONE, #[cfg(feature = "optimism")] "Fjord" => SpecId::FJORD, - #[cfg(any(feature = "opbnb"))] - "Haber" => SpecId::HABER, - _ => Self::LATEST, - } - } - - #[cfg(feature = "bsc")] - fn from(name: &str) -> Self { - match name { - "Frontier" => Self::FRONTIER, - "Homestead" => Self::HOMESTEAD, - "Tangerine" => Self::TANGERINE, - "Spurious" => Self::SPURIOUS_DRAGON, - "Byzantium" => Self::BYZANTIUM, - "Constantinople" => Self::CONSTANTINOPLE, - "Petersburg" => Self::PETERSBURG, - "Istanbul" => Self::ISTANBUL, - "MuirGlacier" => Self::MUIR_GLACIER, - "Berlin" => Self::BERLIN, - "London" => Self::LONDON, - "Shanghai" => Self::SHANGHAI, - "Cancun" => Self::CANCUN, + #[cfg(feature = "bsc")] "Ramanujan" => SpecId::RAMANUJAN, + #[cfg(feature = "bsc")] "Niels" => SpecId::NIELS, + #[cfg(feature = "bsc")] "MirrorSync" => SpecId::MIRROR_SYNC, + #[cfg(feature = "bsc")] "Bruno" => SpecId::BRUNO, + #[cfg(feature = "bsc")] "Euler" => SpecId::EULER, + #[cfg(feature = "bsc")] "Nano" => SpecId::NANO, + #[cfg(feature = "bsc")] "Moran" => SpecId::MORAN, + #[cfg(feature = "bsc")] "Gibbs" => SpecId::GIBBS, + #[cfg(feature = "bsc")] "Planck" => SpecId::PLANCK, + #[cfg(feature = "bsc")] "Luban" => SpecId::LUBAN, + #[cfg(feature = "bsc")] "Plato" => SpecId::PLATO, + #[cfg(feature = "bsc")] "Hertz" => SpecId::HERTZ, + #[cfg(feature = "bsc")] "HertzFix" => SpecId::HERTZ_FIX, + #[cfg(feature = "bsc")] "Kepler" => SpecId::KEPLER, + #[cfg(feature = "bsc")] "Feynman" => SpecId::FEYNMAN, + #[cfg(feature = "bsc")] "FeynmanFix" => SpecId::FEYNMAN_FIX, + #[cfg(any(feature = "opbnb", feature = "bsc"))] "Haber" => SpecId::HABER, _ => Self::LATEST, } @@ -217,7 +214,6 @@ impl From<&str> for SpecId { } impl From for &'static str { - #[cfg(not(feature = "bsc"))] fn from(spec_id: SpecId) -> Self { match spec_id { SpecId::FRONTIER => "Frontier", @@ -251,48 +247,41 @@ impl From for &'static str { SpecId::ECOTONE => "Ecotone", #[cfg(feature = "optimism")] SpecId::FJORD => "Fjord", - #[cfg(feature = "opbnb")] - SpecId::HABER => "Haber", - SpecId::LATEST => "Latest", - } - } - - #[cfg(feature = "bsc")] - fn from(spec_id: SpecId) -> Self { - match spec_id { - SpecId::FRONTIER => "Frontier", - SpecId::FRONTIER_THAWING => "Frontier Thawing", - SpecId::HOMESTEAD => "Homestead", - SpecId::TANGERINE => "Tangerine", - SpecId::SPURIOUS_DRAGON => "Spurious", - SpecId::BYZANTIUM => "Byzantium", - SpecId::CONSTANTINOPLE => "Constantinople", - SpecId::PETERSBURG => "Petersburg", - SpecId::ISTANBUL => "Istanbul", - SpecId::MUIR_GLACIER => "MuirGlacier", - SpecId::BERLIN => "Berlin", - SpecId::LONDON => "London", - SpecId::SHANGHAI => "Shanghai", - SpecId::CANCUN => "Cancun", + #[cfg(feature = "bsc")] SpecId::RAMANUJAN => "Ramanujan", + #[cfg(feature = "bsc")] SpecId::NIELS => "Niels", + #[cfg(feature = "bsc")] SpecId::MIRROR_SYNC => "MirrorSync", + #[cfg(feature = "bsc")] SpecId::BRUNO => "Bruno", + #[cfg(feature = "bsc")] SpecId::EULER => "Euler", + #[cfg(feature = "bsc")] SpecId::NANO => "Nano", + #[cfg(feature = "bsc")] SpecId::MORAN => "Moran", + #[cfg(feature = "bsc")] SpecId::GIBBS => "Gibbs", + #[cfg(feature = "bsc")] SpecId::PLANCK => "Planck", + #[cfg(feature = "bsc")] SpecId::LUBAN => "Luban", + #[cfg(feature = "bsc")] SpecId::PLATO => "Plato", + #[cfg(feature = "bsc")] SpecId::HERTZ => "Hertz", + #[cfg(feature = "bsc")] SpecId::HERTZ_FIX => "HertzFix", + #[cfg(feature = "bsc")] SpecId::KEPLER => "Kepler", + #[cfg(feature = "bsc")] SpecId::FEYNMAN => "Feynman", + #[cfg(feature = "bsc")] SpecId::FEYNMAN_FIX => "FeynmanFix", + #[cfg(any(feature = "opbnb", feature = "bsc"))] SpecId::HABER => "Haber", SpecId::LATEST => "Latest", - _ => "Unknown", } } } @@ -342,24 +331,11 @@ spec!(PRAGUE, PragueSpec); spec!(LATEST, LatestSpec); // BSC Hardforks -// TODO: some of these hardforks may have no EVM spec change -#[cfg(feature = "bsc")] -spec!(RAMANUJAN, RamanujanSpec); -#[cfg(feature = "bsc")] -spec!(NIELS, NielsSpec); -#[cfg(feature = "bsc")] -spec!(MIRROR_SYNC, MirrorSyncSpec); -#[cfg(feature = "bsc")] -spec!(BRUNO, BrunoSpec); -#[cfg(feature = "bsc")] -spec!(EULER, EulerSpec); #[cfg(feature = "bsc")] spec!(NANO, NanoSpec); #[cfg(feature = "bsc")] spec!(MORAN, MoranSpec); #[cfg(feature = "bsc")] -spec!(GIBBS, GibbsSpec); -#[cfg(feature = "bsc")] spec!(PLANCK, PlanckSpec); #[cfg(feature = "bsc")] spec!(LUBAN, LubanSpec); @@ -368,13 +344,7 @@ spec!(PLATO, PlatoSpec); #[cfg(feature = "bsc")] spec!(HERTZ, HertzSpec); #[cfg(feature = "bsc")] -spec!(HERTZ_FIX, HertzFixSpec); -#[cfg(feature = "bsc")] -spec!(KEPLER, KeplerSpec); -#[cfg(feature = "bsc")] spec!(FEYNMAN, FeynmanSpec); -#[cfg(feature = "bsc")] -spec!(FEYNMAN_FIX, FeynmanFixSpec); #[cfg(any(feature = "bsc", feature = "opbnb"))] spec!(HABER, HaberSpec); @@ -585,72 +555,24 @@ macro_rules! spec_to_generic { use $crate::PetersburgSpec as SPEC; $e } - $crate::SpecId::ISTANBUL | $crate::SpecId::MUIR_GLACIER => { - use $crate::IstanbulSpec as SPEC; - $e - } - $crate::SpecId::BERLIN => { - use $crate::BerlinSpec as SPEC; - $e - } - $crate::SpecId::LONDON | - $crate::SpecId::ARROW_GLACIER | - $crate::SpecId::GRAY_GLACIER => { - use $crate::LondonSpec as SPEC; - $e - } - $crate::SpecId::MERGE => { - use $crate::MergeSpec as SPEC; - $e - } - $crate::SpecId::SHANGHAI => { - use $crate::ShanghaiSpec as SPEC; - $e - } - $crate::SpecId::CANCUN => { - use $crate::CancunSpec as SPEC; - $e - } - $crate::SpecId::LATEST => { - use $crate::LatestSpec as SPEC; - $e - } - $crate::SpecId::PRAGUE => { - use $crate::PragueSpec as SPEC; - $e - } - $crate::SpecId::RAMANUJAN => { - use $crate::RamanujanSpec as SPEC; - $e - } - $crate::SpecId::NIELS => { - use $crate::NielsSpec as SPEC; - $e - } - $crate::SpecId::MIRROR_SYNC => { - use $crate::MirrorSyncSpec as SPEC; - $e - } - $crate::SpecId::BRUNO => { - use $crate::BrunoSpec as SPEC; - $e - } + $crate::SpecId::ISTANBUL | + $crate::SpecId::MUIR_GLACIER | + $crate::SpecId::RAMANUJAN | + $crate::SpecId::NIELS | + $crate::SpecId::MIRROR_SYNC | + $crate::SpecId::BRUNO | $crate::SpecId::EULER => { - use $crate::EulerSpec as SPEC; + use $crate::IstanbulSpec as SPEC; $e } $crate::SpecId::NANO => { use $crate::NanoSpec as SPEC; $e } - $crate::SpecId::MORAN => { + $crate::SpecId::MORAN | $crate::SpecId::GIBBS => { use $crate::MoranSpec as SPEC; $e } - $crate::SpecId::GIBBS => { - use $crate::GibbsSpec as SPEC; - $e - } $crate::SpecId::PLANCK => { use $crate::PlanckSpec as SPEC; $e @@ -663,30 +585,48 @@ macro_rules! spec_to_generic { use $crate::PlatoSpec as SPEC; $e } - $crate::SpecId::HERTZ => { - use $crate::HertzSpec as SPEC; + $crate::SpecId::BERLIN => { + use $crate::BerlinSpec as SPEC; + $e + } + $crate::SpecId::LONDON | + $crate::SpecId::ARROW_GLACIER | + $crate::SpecId::GRAY_GLACIER => { + use $crate::LondonSpec as SPEC; + $e + } + $crate::SpecId::MERGE => { + use $crate::MergeSpec as SPEC; $e } - $crate::SpecId::HERTZ_FIX => { - use $crate::HertzFixSpec as SPEC; + $crate::SpecId::SHANGHAI => { + use $crate::ShanghaiSpec as SPEC; $e } - $crate::SpecId::KEPLER => { - use $crate::KeplerSpec as SPEC; + $crate::SpecId::HERTZ | $crate::SpecId::HERTZ_FIX | $crate::SpecId::KEPLER => { + use $crate::HertzSpec as SPEC; $e } - $crate::SpecId::FEYNMAN => { + $crate::SpecId::FEYNMAN | $crate::SpecId::FEYNMAN_FIX => { use $crate::FeynmanSpec as SPEC; $e } - $crate::SpecId::FEYNMAN_FIX => { - use $crate::FeynmanFixSpec as SPEC; + $crate::SpecId::CANCUN => { + use $crate::CancunSpec as SPEC; + $e + } + $crate::SpecId::PRAGUE => { + use $crate::PragueSpec as SPEC; $e } $crate::SpecId::HABER => { use $crate::HaberSpec as SPEC; $e } + $crate::SpecId::LATEST => { + use $crate::LatestSpec as SPEC; + $e + } } }}; } From b80ac2486a0a823226c1acc1f613aa7e1f7e5014 Mon Sep 17 00:00:00 2001 From: Roshan Date: Fri, 7 Jun 2024 02:42:32 +0800 Subject: [PATCH 04/18] fix lint issues --- crates/precompile/src/cometbft.rs | 31 +++++++-- crates/precompile/src/double_sign.rs | 5 +- crates/precompile/src/iavl.rs | 2 - crates/primitives/src/specification.rs | 90 ++++++++++++------------- crates/revm/src/bsc/handler_register.rs | 30 ++++++--- crates/revm/src/lib.rs | 4 +- 6 files changed, 97 insertions(+), 65 deletions(-) diff --git a/crates/precompile/src/cometbft.rs b/crates/precompile/src/cometbft.rs index a4410d07..65b7f3b3 100644 --- a/crates/precompile/src/cometbft.rs +++ b/crates/precompile/src/cometbft.rs @@ -180,7 +180,12 @@ impl ConsensusState { next_validator_set_hash: Bytes, validators: ValidatorSet, ) -> Self { - Self { chain_id, height, next_validator_set_hash, validators } + Self { + chain_id, + height, + next_validator_set_hash, + validators, + } } fn apply_light_block(&mut self, light_block: &LightBlock) -> Result { @@ -246,7 +251,12 @@ impl ConsensusState { .as_bytes()); self.height = light_block.height().value(); self.next_validator_set_hash = Bytes::from( - light_block.signed_header.header().next_validators_hash.as_bytes().to_vec(), + light_block + .signed_header + .header() + .next_validators_hash + .as_bytes() + .to_vec(), ); self.validators = light_block.validators.clone(); @@ -563,7 +573,10 @@ mod tests { cs.validators.validators()[0].relayer_address.as_bytes(), relayer_address.to_vec() ); - assert_eq!(cs.validators.validators()[0].bls_key.as_bytes(), bls_pub_key.to_vec()); + assert_eq!( + cs.validators.validators()[0].bls_key.as_bytes(), + bls_pub_key.to_vec() + ); } { let chain_id = "chain_9000-121".to_string(); @@ -584,7 +597,9 @@ mod tests { Bytes::from(hex!("d5e63aeee6e6fa122a6a23a6e0fca87701ba1541")).to_vec(), )); bls_pub_keys.push(Bytes::from(hex!("aa2d28cbcd1ea3a63479f6fb260a3d755853e6a78cfa6252584fee97b2ec84a9d572ee4a5d3bc1558bb98a4b370fb861"))); - relayer_addresses.push(Bytes::from(hex!("d5e63aeee6e6fa122a6a23a6e0fca87701ba1541"))); + relayer_addresses.push(Bytes::from(hex!( + "d5e63aeee6e6fa122a6a23a6e0fca87701ba1541" + ))); validators_info.push(Validator::new_with_bls_and_relayer( PublicKey::from_raw_ed25519(&hex!( "6b0b523ee91ad18a63d63f21e0c40a83ef15963f4260574ca5159fd90a1c5270" @@ -595,7 +610,9 @@ mod tests { Bytes::from(hex!("6fd1ceb5a48579f322605220d4325bd9ff90d5fa")).to_vec(), )); bls_pub_keys.push(Bytes::from(hex!("b31e74a881fc78681e3dfa440978d2b8be0708a1cbbca2c660866216975fdaf0e9038d9b7ccbf9731f43956dba7f2451"))); - relayer_addresses.push(Bytes::from(hex!("6fd1ceb5a48579f322605220d4325bd9ff90d5fa"))); + relayer_addresses.push(Bytes::from(hex!( + "6fd1ceb5a48579f322605220d4325bd9ff90d5fa" + ))); validators_info.push(Validator::new_with_bls_and_relayer( PublicKey::from_raw_ed25519(&hex!( "919606ae20bf5d248ee353821754bcdb456fd3950618fda3e32d3d0fb990eeda" @@ -606,7 +623,9 @@ mod tests { Bytes::from(hex!("97376a436bbf54e0f6949b57aa821a90a749920a")).to_vec(), )); bls_pub_keys.push(Bytes::from(hex!("b32979580ea04984a2be033599c20c7a0c9a8d121b57f94ee05f5eda5b36c38f6e354c89328b92cdd1de33b64d3a0867"))); - relayer_addresses.push(Bytes::from(hex!("97376a436bbf54e0f6949b57aa821a90a749920a"))); + relayer_addresses.push(Bytes::from(hex!( + "97376a436bbf54e0f6949b57aa821a90a749920a" + ))); let validator_set = ValidatorSet::without_proposer(validators_info); let cs_bytes = Bytes::from(hex!("636861696e5f393030302d3132310000000000000000000000000000000000000000000000000001a5f1af4874227f1cdbe5240259a365ad86484a4255bfd65e2a0222d733fcdbc320cc466ee9412ddd49e0fff04cdb41bade2b7622f08b6bdacac94d4de03bdb970000000000002710d5e63aeee6e6fa122a6a23a6e0fca87701ba1541aa2d28cbcd1ea3a63479f6fb260a3d755853e6a78cfa6252584fee97b2ec84a9d572ee4a5d3bc1558bb98a4b370fb8616b0b523ee91ad18a63d63f21e0c40a83ef15963f4260574ca5159fd90a1c527000000000000027106fd1ceb5a48579f322605220d4325bd9ff90d5fab31e74a881fc78681e3dfa440978d2b8be0708a1cbbca2c660866216975fdaf0e9038d9b7ccbf9731f43956dba7f2451919606ae20bf5d248ee353821754bcdb456fd3950618fda3e32d3d0fb990eeda000000000000271097376a436bbf54e0f6949b57aa821a90a749920ab32979580ea04984a2be033599c20c7a0c9a8d121b57f94ee05f5eda5b36c38f6e354c89328b92cdd1de33b64d3a0867")); let cs = match decode_consensus_state(&cs_bytes) { diff --git a/crates/precompile/src/double_sign.rs b/crates/precompile/src/double_sign.rs index 1500c861..69745ad9 100644 --- a/crates/precompile/src/double_sign.rs +++ b/crates/precompile/src/double_sign.rs @@ -197,6 +197,9 @@ mod tests { let input = hex::decode("f9066b38b90332f9032fa01062d3d5015b9242bc193a9b0769f3d3780ecb55f97f40a752ae26d0b68cd0d8a0fae1a05fcb14bfd9b8a9f2b65007a9b6c2000de0627a73be644dd993d32342c494df87f0e2b8519ea2dd4abd8b639cdd628497ed25a0f385cc58ed297ff0d66eb5580b02853d3478ba418b1819ac659ee05df49b9794a0bf88464af369ed6b8cf02db00f0b9556ffa8d49cd491b00952a7f83431446638a00a6d0870e586a76278fbfdcedf76ef6679af18fc1f9137cfad495f434974ea81b901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001a1010000000000000000000000000000000000000000000000000000000000000000830f4240830f42408465bc6996b90115d983010306846765746889676f312e32302e3131856c696e7578000053474aa9f8b25fb860b0844a5082bfaa2299d2a23f076e2f6b17b15f839cc3e7d5a875656f6733fd4b87ba3401f906d15f3dea263cd9a6076107c7db620a4630dd3832c4a4b57eb8f497e28a3d69e5c03b30205c4b45675747d513e1accd66329770f3c35b18c9d023f84c84023a5ad6a086a28d985d9a6c8e7f9a4feadd5ace0adba9818e1e1727edca755fcc0bd8344684023a5ad7a0bc3492196b2e68b8e6ceea87cfa7588b4d590089eb885c4f2c1e9d9fb450f7b980988e1b9d0beb91dab063e04879a24c43d33baae3759dee41fd62ffa83c77fd202bea27a829b49e8025bdd198393526dd12b223ab16052fd26a43f3aabf63e76901a0232c9ba2d41b40d36ed794c306747bcbc49bf61a0f37409c18bfe2b5bef26a2d880000000000000000b90332f9032fa01062d3d5015b9242bc193a9b0769f3d3780ecb55f97f40a752ae26d0b68cd0d8a0b2789a5357827ed838335283e15c4dcc42b9bebcbf2919a18613246787e2f96094df87f0e2b8519ea2dd4abd8b639cdd628497ed25a071ce4c09ee275206013f0063761bc19c93c13990582f918cc57333634c94ce89a00e095703e5c9b149f253fe89697230029e32484a410b4b1f2c61442d73c3095aa0d317ae19ede7c8a2d3ac9ef98735b049bcb7278d12f48c42b924538b60a25e12b901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001a1010000000000000000000000000000000000000000000000000000000000000000830f4240830f42408465bc6996b90115d983010306846765746889676f312e32302e3131856c696e7578000053474aa9f8b25fb860b0844a5082bfaa2299d2a23f076e2f6b17b15f839cc3e7d5a875656f6733fd4b87ba3401f906d15f3dea263cd9a6076107c7db620a4630dd3832c4a4b57eb8f497e28a3d69e5c03b30205c4b45675747d513e1accd66329770f3c35b18c9d023f84c84023a5ad6a086a28d985d9a6c8e7f9a4feadd5ace0adba9818e1e1727edca755fcc0bd8344684023a5ad7a0bc3492196b2e68b8e6ceea87cfa7588b4d590089eb885c4f2c1e9d9fb450f7b9804c71ed015dd0c5c2d7393b68c2927f83f0a5da4c66f761f09e2f950cc610832c7876144599368404096ddef0eadacfde57717e2c7d23982b927285b797d41bfa00a0b56228685be711834d0f154292d07826dea42a0fad3e4f56c31470b7fbfbea26880000000000000000").unwrap(); let res = double_sign_evidence_validation_run(&Bytes::from(input), 10_000); - assert_eq!(res.err(), Some(PrecompileError::Other(String::from("invalid evidence")))); + assert_eq!( + res.err(), + Some(PrecompileError::Other(String::from("invalid evidence"))) + ); } } diff --git a/crates/precompile/src/iavl.rs b/crates/precompile/src/iavl.rs index 99891817..66b61152 100644 --- a/crates/precompile/src/iavl.rs +++ b/crates/precompile/src/iavl.rs @@ -37,13 +37,11 @@ fn iavl_proof_validation_run(input: &Bytes, gas_limit: u64) -> PrecompileResult return iavl_proof_validation_run_inner(input, gas_limit, false, false, false); } - /// Run Iavl proof validation with Nano hardfork. fn iavl_proof_validation_run_nano(_input: &Bytes, _gas_limit: u64) -> PrecompileResult { return Err(PrecompileError::other("suspended")); } - /// Run Iavl proof validation with Moran hardfork. fn iavl_proof_validation_run_moran(input: &Bytes, gas_limit: u64) -> PrecompileResult { return iavl_proof_validation_run_inner(input, gas_limit, true, false, false); diff --git a/crates/primitives/src/specification.rs b/crates/primitives/src/specification.rs index 3858581b..32b5ac1c 100644 --- a/crates/primitives/src/specification.rs +++ b/crates/primitives/src/specification.rs @@ -82,35 +82,35 @@ pub enum SpecId { pub enum SpecId { FRONTIER = 0, FRONTIER_THAWING = 1, - HOMESTEAD = 2, // Homestead 0 - TANGERINE = 3, // Tangerine Whistle(EIP150) 0 - SPURIOUS_DRAGON = 4, // Spurious Dragon(EIP155, EIP158) 0 - BYZANTIUM = 5, // Byzantium 0 - CONSTANTINOPLE = 6, // Constantinople 0 - PETERSBURG = 7, // Petersburg 0 - ISTANBUL = 8, // Istanbul 0 - MUIR_GLACIER = 9, // Muir Glacier 0 - RAMANUJAN = 10, // Ramanujan 0 - NIELS = 11, // Niels 0 - MIRROR_SYNC = 12, // Mirror Sync 5184000 - BRUNO = 13, // Bruno 13082000 - EULER = 14, // Euler 18907621 - NANO = 15, // Nano 21962149 - MORAN = 16, // Moran 22107423 - GIBBS = 17, // Gibbs 23846001 - PLANCK = 18, // Planck 27281024 - LUBAN = 19, // Luban 29020050 - PLATO = 20, // Plato 30720096 - BERLIN = 21, // Berlin 31302048 - LONDON = 22, // London 31302048 - HERTZ = 23, // Hertz 31302048 - HERTZ_FIX = 24, // HertzFix 34140700 - SHANGHAI = 25, // Shanghai timestamp(1705996800) 2024-01-23 08:00:00 AM UTC - KEPLER = 26, // Kepler timestamp(1705996800) 2024-01-23 08:00:00 AM UTC - FEYNMAN = 27, // Feynman timestamp(1713419340) 2024-04-18 05:49:00 AM UTC - FEYNMAN_FIX = 28, // FeynmanFix timestamp(1713419340) 2024-04-18 05:49:00 AM UTC - CANCUN = 29, // Cancun timestamp(1718863500) 2024-06-20 06:05:00 AM UTC - HABER = 30, // Haber TBD + HOMESTEAD = 2, // Homestead 0 + TANGERINE = 3, // Tangerine Whistle(EIP150) 0 + SPURIOUS_DRAGON = 4, // Spurious Dragon(EIP155, EIP158) 0 + BYZANTIUM = 5, // Byzantium 0 + CONSTANTINOPLE = 6, // Constantinople 0 + PETERSBURG = 7, // Petersburg 0 + ISTANBUL = 8, // Istanbul 0 + MUIR_GLACIER = 9, // Muir Glacier 0 + RAMANUJAN = 10, // Ramanujan 0 + NIELS = 11, // Niels 0 + MIRROR_SYNC = 12, // Mirror Sync 5184000 + BRUNO = 13, // Bruno 13082000 + EULER = 14, // Euler 18907621 + NANO = 15, // Nano 21962149 + MORAN = 16, // Moran 22107423 + GIBBS = 17, // Gibbs 23846001 + PLANCK = 18, // Planck 27281024 + LUBAN = 19, // Luban 29020050 + PLATO = 20, // Plato 30720096 + BERLIN = 21, // Berlin 31302048 + LONDON = 22, // London 31302048 + HERTZ = 23, // Hertz 31302048 + HERTZ_FIX = 24, // HertzFix 34140700 + SHANGHAI = 25, // Shanghai timestamp(1705996800) 2024-01-23 08:00:00 AM UTC + KEPLER = 26, // Kepler timestamp(1705996800) 2024-01-23 08:00:00 AM UTC + FEYNMAN = 27, // Feynman timestamp(1713419340) 2024-04-18 05:49:00 AM UTC + FEYNMAN_FIX = 28, // FeynmanFix timestamp(1713419340) 2024-04-18 05:49:00 AM UTC + CANCUN = 29, // Cancun timestamp(1718863500) 2024-06-20 06:05:00 AM UTC + HABER = 30, // Haber TBD // TODO: or u8::MAX - n? /// Not enabled in bsc @@ -399,9 +399,9 @@ macro_rules! spec_to_generic { use $crate::BerlinSpec as SPEC; $e } - $crate::SpecId::LONDON | - $crate::SpecId::ARROW_GLACIER | - $crate::SpecId::GRAY_GLACIER => { + $crate::SpecId::LONDON + | $crate::SpecId::ARROW_GLACIER + | $crate::SpecId::GRAY_GLACIER => { use $crate::LondonSpec as SPEC; $e } @@ -466,9 +466,9 @@ macro_rules! spec_to_generic { use $crate::BerlinSpec as SPEC; $e } - $crate::SpecId::LONDON | - $crate::SpecId::ARROW_GLACIER | - $crate::SpecId::GRAY_GLACIER => { + $crate::SpecId::LONDON + | $crate::SpecId::ARROW_GLACIER + | $crate::SpecId::GRAY_GLACIER => { use $crate::LondonSpec as SPEC; $e } @@ -555,13 +555,13 @@ macro_rules! spec_to_generic { use $crate::PetersburgSpec as SPEC; $e } - $crate::SpecId::ISTANBUL | - $crate::SpecId::MUIR_GLACIER | - $crate::SpecId::RAMANUJAN | - $crate::SpecId::NIELS | - $crate::SpecId::MIRROR_SYNC | - $crate::SpecId::BRUNO | - $crate::SpecId::EULER => { + $crate::SpecId::ISTANBUL + | $crate::SpecId::MUIR_GLACIER + | $crate::SpecId::RAMANUJAN + | $crate::SpecId::NIELS + | $crate::SpecId::MIRROR_SYNC + | $crate::SpecId::BRUNO + | $crate::SpecId::EULER => { use $crate::IstanbulSpec as SPEC; $e } @@ -589,9 +589,9 @@ macro_rules! spec_to_generic { use $crate::BerlinSpec as SPEC; $e } - $crate::SpecId::LONDON | - $crate::SpecId::ARROW_GLACIER | - $crate::SpecId::GRAY_GLACIER => { + $crate::SpecId::LONDON + | $crate::SpecId::ARROW_GLACIER + | $crate::SpecId::GRAY_GLACIER => { use $crate::LondonSpec as SPEC; $e } diff --git a/crates/revm/src/bsc/handler_register.rs b/crates/revm/src/bsc/handler_register.rs index 788d3334..d87429ed 100644 --- a/crates/revm/src/bsc/handler_register.rs +++ b/crates/revm/src/bsc/handler_register.rs @@ -36,7 +36,8 @@ pub fn validate_initial_tx_gas( let is_create = env.tx.transact_to.is_create(); let access_list = &env.tx.access_list; - let initial_gas_spend = gas::validate_initial_tx_gas(SPEC::SPEC_ID, input, is_create, access_list); + let initial_gas_spend = + gas::validate_initial_tx_gas(SPEC::SPEC_ID, input, is_create, access_list); // Additional check to see if limit is big enough to cover initial gas. if initial_gas_spend > env.tx.gas_limit { @@ -76,7 +77,14 @@ pub fn output( ) -> Result> { core::mem::replace(&mut context.evm.error, Ok(()))?; // used gas with refund calculated. - let gas_refunded = if context.evm.env.tx.bsc.is_system_transaction.unwrap_or(false) { + let gas_refunded = if context + .evm + .env + .tx + .bsc + .is_system_transaction + .unwrap_or(false) + { 0 } else { result.gas().refunded() as u64 @@ -96,14 +104,18 @@ pub fn output( logs, output, }, - SuccessOrHalt::Revert => { - ExecutionResult::Revert { gas_used: final_gas_used, output: output.into_data() } - } - SuccessOrHalt::Halt(reason) => ExecutionResult::Halt { reason, gas_used: final_gas_used }, + SuccessOrHalt::Revert => ExecutionResult::Revert { + gas_used: final_gas_used, + output: output.into_data(), + }, + SuccessOrHalt::Halt(reason) => ExecutionResult::Halt { + reason, + gas_used: final_gas_used, + }, // Only two internal return flags. - flag @ (SuccessOrHalt::FatalExternalError | - SuccessOrHalt::InternalContinue | - SuccessOrHalt::InternalCallOrCreate) => { + flag @ (SuccessOrHalt::FatalExternalError + | SuccessOrHalt::InternalContinue + | SuccessOrHalt::InternalCallOrCreate) => { panic!( "Encountered unexpected internal return flag: {:?} with instruction result: {:?}", flag, instruction_result diff --git a/crates/revm/src/lib.rs b/crates/revm/src/lib.rs index 5f981677..b63c311f 100644 --- a/crates/revm/src/lib.rs +++ b/crates/revm/src/lib.rs @@ -14,6 +14,8 @@ mod context; #[cfg(any(test, feature = "test-utils"))] pub mod test_utils; +#[cfg(feature = "bsc")] +pub mod bsc; pub mod db; mod evm; mod frame; @@ -22,8 +24,6 @@ mod inspector; mod journaled_state; #[cfg(feature = "optimism")] pub mod optimism; -#[cfg(feature = "bsc")] -pub mod bsc; // Export items. From e40aca3157500bea3ed8ca0e56212a6e84570fa7 Mon Sep 17 00:00:00 2001 From: Roshan Date: Fri, 7 Jun 2024 11:55:53 +0800 Subject: [PATCH 05/18] fix CI issues --- .github/workflows/ci.yml | 83 +++++++++++++++----------- crates/precompile/src/tm_secp256k1.rs | 2 +- crates/primitives/src/specification.rs | 20 ++++--- 3 files changed, 61 insertions(+), 44 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a6b82262..f59f1695 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -22,7 +22,8 @@ jobs: fail-fast: false matrix: rust: ["stable", "beta", "nightly"] - flags: ["--no-default-features", "", "--all-features"] +# flags: ["--no-default-features", "", "--all-features"] + flags: ["", "--features bsc", "--features optimism,opbnb"] steps: - uses: actions/checkout@v4 - uses: dtolnay/rust-toolchain@master @@ -42,57 +43,71 @@ jobs: # targets: riscv32imac-unknown-none-elf # - run: cargo check --target riscv32imac-unknown-none-elf --no-default-features - check-no-default-features: - name: check no-default-features - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - uses: actions/checkout@v4 - - run: | - cd crates/revm - cargo check --no-default-features - - check-serde: - name: check serde - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - uses: actions/checkout@v4 - - run: | - cd crates/revm - cargo check --no-default-features --features serde - - check-std: - name: check std - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - uses: actions/checkout@v4 - - run: | - cd crates/revm - cargo check --no-default-features --features std +# check-no-default-features: +# name: check no-default-features +# runs-on: ubuntu-latest +# timeout-minutes: 30 +# steps: +# - uses: actions/checkout@v4 +# - run: | +# cd crates/revm +# cargo check --no-default-features +# +# check-serde: +# name: check serde +# runs-on: ubuntu-latest +# timeout-minutes: 30 +# steps: +# - uses: actions/checkout@v4 +# - run: | +# cd crates/revm +# cargo check --no-default-features --features serde +# +# check-std: +# name: check std +# runs-on: ubuntu-latest +# timeout-minutes: 30 +# steps: +# - uses: actions/checkout@v4 +# - run: | +# cd crates/revm +# cargo check --no-default-features --features std clippy: - name: clippy + name: clippy / ${{ matrix.network }} runs-on: ubuntu-latest timeout-minutes: 30 + strategy: + matrix: + include: + - network: optimism + extra-features: "opbnb" + - network: bsc + extra-features: "" steps: - uses: actions/checkout@v4 - uses: dtolnay/rust-toolchain@stable - - run: cargo clippy --workspace --all-targets --all-features + - run: cargo clippy --workspace --all-targets --features "${{ matrix.network }} ${{ matrix.extra-features }}" env: RUSTFLAGS: -Dwarnings docs: - name: docs + name: docs / ${{ matrix.network }} runs-on: ubuntu-latest timeout-minutes: 30 + strategy: + matrix: + include: + - network: optimism + extra-features: "opbnb" + - network: bsc + extra-features: "" steps: - uses: actions/checkout@v4 - uses: dtolnay/rust-toolchain@stable with: components: rust-docs - - run: cargo doc --workspace --all-features --no-deps --document-private-items + - run: cargo doc --workspace --no-deps --document-private-items --features "${{ matrix.network }} ${{ matrix.extra-features }}" env: RUSTDOCFLAGS: "--cfg docsrs -D warnings" diff --git a/crates/precompile/src/tm_secp256k1.rs b/crates/precompile/src/tm_secp256k1.rs index 69d6d446..0e3876b9 100644 --- a/crates/precompile/src/tm_secp256k1.rs +++ b/crates/precompile/src/tm_secp256k1.rs @@ -5,7 +5,7 @@ use tendermint::{account, public_key}; /// Tendermint SECP256K1 signature recover precompile for BSC. pub(crate) const TM_SECP256K1_SIGNATURE_RECOVER: PrecompileWithAddress = PrecompileWithAddress( crate::u64_to_address(105), - Precompile::Standard(crate::tm_secp256k1::tm_secp256k1_signature_recover_run), + Precompile::Standard(tm_secp256k1_signature_recover_run), ); const SECP256K1_PUBKEY_LENGTH: usize = 33; diff --git a/crates/primitives/src/specification.rs b/crates/primitives/src/specification.rs index 32b5ac1c..82d1fd08 100644 --- a/crates/primitives/src/specification.rs +++ b/crates/primitives/src/specification.rs @@ -682,21 +682,21 @@ mod tests { spec_to_generic!(LATEST, assert_eq!(SPEC::SPEC_ID, LATEST)); #[cfg(feature = "bsc")] - spec_to_generic!(RAMANUJAN, assert_eq!(SPEC::SPEC_ID, RAMANUJAN)); + spec_to_generic!(RAMANUJAN, assert_eq!(SPEC::SPEC_ID, ISTANBUL)); #[cfg(feature = "bsc")] - spec_to_generic!(NIELS, assert_eq!(SPEC::SPEC_ID, NIELS)); + spec_to_generic!(NIELS, assert_eq!(SPEC::SPEC_ID, ISTANBUL)); #[cfg(feature = "bsc")] - spec_to_generic!(MIRROR_SYNC, assert_eq!(SPEC::SPEC_ID, MIRROR_SYNC)); + spec_to_generic!(MIRROR_SYNC, assert_eq!(SPEC::SPEC_ID, ISTANBUL)); #[cfg(feature = "bsc")] - spec_to_generic!(BRUNO, assert_eq!(SPEC::SPEC_ID, BRUNO)); + spec_to_generic!(BRUNO, assert_eq!(SPEC::SPEC_ID, ISTANBUL)); #[cfg(feature = "bsc")] - spec_to_generic!(EULER, assert_eq!(SPEC::SPEC_ID, EULER)); + spec_to_generic!(EULER, assert_eq!(SPEC::SPEC_ID, ISTANBUL)); #[cfg(feature = "bsc")] spec_to_generic!(NANO, assert_eq!(SPEC::SPEC_ID, NANO)); #[cfg(feature = "bsc")] spec_to_generic!(MORAN, assert_eq!(SPEC::SPEC_ID, MORAN)); #[cfg(feature = "bsc")] - spec_to_generic!(GIBBS, assert_eq!(SPEC::SPEC_ID, GIBBS)); + spec_to_generic!(GIBBS, assert_eq!(SPEC::SPEC_ID, MORAN)); #[cfg(feature = "bsc")] spec_to_generic!(PLANCK, assert_eq!(SPEC::SPEC_ID, PLANCK)); #[cfg(feature = "bsc")] @@ -706,13 +706,15 @@ mod tests { #[cfg(feature = "bsc")] spec_to_generic!(HERTZ, assert_eq!(SPEC::SPEC_ID, HERTZ)); #[cfg(feature = "bsc")] - spec_to_generic!(HERTZ_FIX, assert_eq!(SPEC::SPEC_ID, HERTZ_FIX)); + spec_to_generic!(HERTZ_FIX, assert_eq!(SPEC::SPEC_ID, HERTZ)); #[cfg(feature = "bsc")] - spec_to_generic!(KEPLER, assert_eq!(SPEC::SPEC_ID, KEPLER)); + spec_to_generic!(KEPLER, assert_eq!(SPEC::SPEC_ID, HERTZ)); #[cfg(feature = "bsc")] spec_to_generic!(FEYNMAN, assert_eq!(SPEC::SPEC_ID, FEYNMAN)); #[cfg(feature = "bsc")] - spec_to_generic!(FEYNMAN_FIX, assert_eq!(SPEC::SPEC_ID, FEYNMAN_FIX)); + spec_to_generic!(FEYNMAN_FIX, assert_eq!(SPEC::SPEC_ID, FEYNMAN)); + #[cfg(feature = "bsc")] + spec_to_generic!(HABER, assert_eq!(SPEC::SPEC_ID, HABER)); } } From da7908ebc17ed19bc1e716d222a3a1c2f080f8db Mon Sep 17 00:00:00 2001 From: Roshan Date: Fri, 7 Jun 2024 14:58:30 +0800 Subject: [PATCH 06/18] fix CI issues --- .github/workflows/ci.yml | 80 +++++++++++++------------- crates/precompile/Cargo.toml | 2 +- crates/precompile/src/cometbft.rs | 4 +- crates/precompile/src/double_sign.rs | 29 +++++----- crates/precompile/src/iavl.rs | 30 +++++----- crates/precompile/src/lib.rs | 9 +-- crates/precompile/src/tendermint.rs | 4 +- crates/precompile/src/tm_secp256k1.rs | 10 ++-- crates/primitives/src/specification.rs | 10 ++-- 9 files changed, 89 insertions(+), 89 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f59f1695..27a80efa 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -23,7 +23,7 @@ jobs: matrix: rust: ["stable", "beta", "nightly"] # flags: ["--no-default-features", "", "--all-features"] - flags: ["", "--features bsc", "--features optimism,opbnb"] + flags: ["--no-default-features", "", "--features bsc", "--features optimism,opbnb"] steps: - uses: actions/checkout@v4 - uses: dtolnay/rust-toolchain@master @@ -32,46 +32,46 @@ jobs: - uses: Swatinem/rust-cache@v2 - run: cargo test --workspace ${{ matrix.flags }} - # test-no-std: - # name: test no_std - # runs-on: ubuntu-latest - # timeout-minutes: 30 - # steps: - # - uses: actions/checkout@v4 - # - uses: dtolnay/rust-toolchain@stable - # with: - # targets: riscv32imac-unknown-none-elf - # - run: cargo check --target riscv32imac-unknown-none-elf --no-default-features + test-no-std: + name: test no_std + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - uses: actions/checkout@v4 + - uses: dtolnay/rust-toolchain@stable + with: + targets: riscv32imac-unknown-none-elf + - run: cargo check --target riscv32imac-unknown-none-elf --no-default-features -# check-no-default-features: -# name: check no-default-features -# runs-on: ubuntu-latest -# timeout-minutes: 30 -# steps: -# - uses: actions/checkout@v4 -# - run: | -# cd crates/revm -# cargo check --no-default-features -# -# check-serde: -# name: check serde -# runs-on: ubuntu-latest -# timeout-minutes: 30 -# steps: -# - uses: actions/checkout@v4 -# - run: | -# cd crates/revm -# cargo check --no-default-features --features serde -# -# check-std: -# name: check std -# runs-on: ubuntu-latest -# timeout-minutes: 30 -# steps: -# - uses: actions/checkout@v4 -# - run: | -# cd crates/revm -# cargo check --no-default-features --features std + check-no-default-features: + name: check no-default-features + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - uses: actions/checkout@v4 + - run: | + cd crates/revm + cargo check --no-default-features + + check-serde: + name: check serde + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - uses: actions/checkout@v4 + - run: | + cd crates/revm + cargo check --no-default-features --features serde + + check-std: + name: check std + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - uses: actions/checkout@v4 + - run: | + cd crates/revm + cargo check --no-default-features --features std clippy: name: clippy / ${{ matrix.network }} diff --git a/crates/precompile/Cargo.toml b/crates/precompile/Cargo.toml index 77de5480..c89f2746 100644 --- a/crates/precompile/Cargo.toml +++ b/crates/precompile/Cargo.toml @@ -83,7 +83,7 @@ std = [ hashbrown = ["revm-primitives/hashbrown"] asm-keccak = ["revm-primitives/asm-keccak"] -bsc = ["revm-primitives/bsc"] +bsc = ["revm-primitives/bsc", "secp256k1"] optimism = ["revm-primitives/optimism", "secp256r1"] # Optimism default handler enabled Optimism handler register by default in EvmBuilder. optimism-default-handler = [ diff --git a/crates/precompile/src/cometbft.rs b/crates/precompile/src/cometbft.rs index 65b7f3b3..f3f0df6e 100644 --- a/crates/precompile/src/cometbft.rs +++ b/crates/precompile/src/cometbft.rs @@ -48,14 +48,14 @@ const MAX_CONSENSUS_STATE_LENGTH: u64 = CHAIN_ID_LENGTH + 99 * SINGLE_VALIDATOR_BYTES_LENGTH; fn cometbft_light_block_validation_run(input: &Bytes, gas_limit: u64) -> PrecompileResult { - return cometbft_light_block_validation_run_inner(input, gas_limit, true); + cometbft_light_block_validation_run_inner(input, gas_limit, true) } fn cometbft_light_block_validation_run_before_hertz( input: &Bytes, gas_limit: u64, ) -> PrecompileResult { - return cometbft_light_block_validation_run_inner(input, gas_limit, false); + cometbft_light_block_validation_run_inner(input, gas_limit, false) } fn cometbft_light_block_validation_run_inner( diff --git a/crates/precompile/src/double_sign.rs b/crates/precompile/src/double_sign.rs index 69745ad9..3dc455bb 100644 --- a/crates/precompile/src/double_sign.rs +++ b/crates/precompile/src/double_sign.rs @@ -81,36 +81,36 @@ fn double_sign_evidence_validation_run(input: &Bytes, gas_limit: u64) -> Precomp let evidence = match DoubleSignEvidence::decode(&mut input.iter().as_ref()) { Ok(e) => e, - Err(_) => return Err(PrecompileError::Other(String::from("invalid evidence"))), + Err(_) => return Err(PrecompileError::other("invalid evidence")), }; let header1 = match Header::decode(&mut evidence.header_bytes1.as_ref()) { Ok(e) => e, - Err(_) => return Err(PrecompileError::Other(String::from("invalid evidence"))), + Err(_) => return Err(PrecompileError::other("invalid evidence")), }; let header2 = match Header::decode(&mut evidence.header_bytes2.as_ref()) { Ok(e) => e, - Err(_) => return Err(PrecompileError::Other(String::from("invalid evidence"))), + Err(_) => return Err(PrecompileError::other("invalid evidence")), }; // basic check if header1.number.to_be_bytes().len() > 32 || header2.number.to_be_bytes().len() > 32 { - return Err(PrecompileError::Other(String::from("invalid evidence"))); + return Err(PrecompileError::other("invalid evidence")); } if header1.number != header2.number { - return Err(PrecompileError::Other(String::from("invalid evidence"))); + return Err(PrecompileError::other("invalid evidence")); } if header1.parent_hash.cmp(&header2.parent_hash) != Ordering::Equal { - return Err(PrecompileError::Other(String::from("invalid evidence"))); + return Err(PrecompileError::other("invalid evidence")); } if header1.extra.len() < EXTRA_SEAL_LENGTH || header1.extra.len() < EXTRA_SEAL_LENGTH { - return Err(PrecompileError::Other(String::from("invalid evidence"))); + return Err(PrecompileError::other("invalid evidence")); } let sig1 = &header1.extra[header1.extra.len() - EXTRA_SEAL_LENGTH..]; let sig2 = &header2.extra[header2.extra.len() - EXTRA_SEAL_LENGTH..]; if sig1.eq(sig2) { - return Err(PrecompileError::Other(String::from("invalid evidence"))); + return Err(PrecompileError::other("invalid evidence")); } // check signature @@ -118,25 +118,25 @@ fn double_sign_evidence_validation_run(input: &Bytes, gas_limit: u64) -> Precomp let msg_hash2 = seal_hash(&header2, evidence.chain_id); if msg_hash1.eq(&msg_hash2) { - return Err(PrecompileError::Other(String::from("invalid evidence"))); + return Err(PrecompileError::other("invalid evidence")); } let recid1 = sig1[64]; let sig1 = <&B512>::try_from(&sig1[..64]).unwrap(); let addr1 = match secp256k1::ecrecover(sig1, recid1, &msg_hash1) { Ok(pk) => pk, - Err(_) => return Err(PrecompileError::Other(String::from("invalid evidence"))), + Err(_) => return Err(PrecompileError::other("invalid evidence")), }; let recid2 = sig2[64]; let sig2 = <&B512>::try_from(&sig2[..64]).unwrap(); let addr2 = match secp256k1::ecrecover(sig2, recid2, &msg_hash2) { Ok(pk) => pk, - Err(_) => return Err(PrecompileError::Other(String::from("invalid evidence"))), + Err(_) => return Err(PrecompileError::other("invalid evidence")), }; if !addr1.eq(&addr2) { - return Err(PrecompileError::Other(String::from("invalid evidence"))); + return Err(PrecompileError::other("invalid evidence")); } let mut res = [0; 52]; @@ -197,9 +197,6 @@ mod tests { let input = hex::decode("f9066b38b90332f9032fa01062d3d5015b9242bc193a9b0769f3d3780ecb55f97f40a752ae26d0b68cd0d8a0fae1a05fcb14bfd9b8a9f2b65007a9b6c2000de0627a73be644dd993d32342c494df87f0e2b8519ea2dd4abd8b639cdd628497ed25a0f385cc58ed297ff0d66eb5580b02853d3478ba418b1819ac659ee05df49b9794a0bf88464af369ed6b8cf02db00f0b9556ffa8d49cd491b00952a7f83431446638a00a6d0870e586a76278fbfdcedf76ef6679af18fc1f9137cfad495f434974ea81b901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001a1010000000000000000000000000000000000000000000000000000000000000000830f4240830f42408465bc6996b90115d983010306846765746889676f312e32302e3131856c696e7578000053474aa9f8b25fb860b0844a5082bfaa2299d2a23f076e2f6b17b15f839cc3e7d5a875656f6733fd4b87ba3401f906d15f3dea263cd9a6076107c7db620a4630dd3832c4a4b57eb8f497e28a3d69e5c03b30205c4b45675747d513e1accd66329770f3c35b18c9d023f84c84023a5ad6a086a28d985d9a6c8e7f9a4feadd5ace0adba9818e1e1727edca755fcc0bd8344684023a5ad7a0bc3492196b2e68b8e6ceea87cfa7588b4d590089eb885c4f2c1e9d9fb450f7b980988e1b9d0beb91dab063e04879a24c43d33baae3759dee41fd62ffa83c77fd202bea27a829b49e8025bdd198393526dd12b223ab16052fd26a43f3aabf63e76901a0232c9ba2d41b40d36ed794c306747bcbc49bf61a0f37409c18bfe2b5bef26a2d880000000000000000b90332f9032fa01062d3d5015b9242bc193a9b0769f3d3780ecb55f97f40a752ae26d0b68cd0d8a0b2789a5357827ed838335283e15c4dcc42b9bebcbf2919a18613246787e2f96094df87f0e2b8519ea2dd4abd8b639cdd628497ed25a071ce4c09ee275206013f0063761bc19c93c13990582f918cc57333634c94ce89a00e095703e5c9b149f253fe89697230029e32484a410b4b1f2c61442d73c3095aa0d317ae19ede7c8a2d3ac9ef98735b049bcb7278d12f48c42b924538b60a25e12b901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001a1010000000000000000000000000000000000000000000000000000000000000000830f4240830f42408465bc6996b90115d983010306846765746889676f312e32302e3131856c696e7578000053474aa9f8b25fb860b0844a5082bfaa2299d2a23f076e2f6b17b15f839cc3e7d5a875656f6733fd4b87ba3401f906d15f3dea263cd9a6076107c7db620a4630dd3832c4a4b57eb8f497e28a3d69e5c03b30205c4b45675747d513e1accd66329770f3c35b18c9d023f84c84023a5ad6a086a28d985d9a6c8e7f9a4feadd5ace0adba9818e1e1727edca755fcc0bd8344684023a5ad7a0bc3492196b2e68b8e6ceea87cfa7588b4d590089eb885c4f2c1e9d9fb450f7b9804c71ed015dd0c5c2d7393b68c2927f83f0a5da4c66f761f09e2f950cc610832c7876144599368404096ddef0eadacfde57717e2c7d23982b927285b797d41bfa00a0b56228685be711834d0f154292d07826dea42a0fad3e4f56c31470b7fbfbea26880000000000000000").unwrap(); let res = double_sign_evidence_validation_run(&Bytes::from(input), 10_000); - assert_eq!( - res.err(), - Some(PrecompileError::Other(String::from("invalid evidence"))) - ); + assert_eq!(res.err(), Some(PrecompileError::other("invalid evidence"))); } } diff --git a/crates/precompile/src/iavl.rs b/crates/precompile/src/iavl.rs index 66b61152..6ad3fecc 100644 --- a/crates/precompile/src/iavl.rs +++ b/crates/precompile/src/iavl.rs @@ -1,3 +1,5 @@ +#![allow(dead_code)] + use crate::{Bytes, Error, Precompile, PrecompileError, PrecompileResult, PrecompileWithAddress}; use parity_bytes::BytesRef; use tendermint::lite::iavl_proof; @@ -5,56 +7,56 @@ use tendermint::lite::iavl_proof; /// Iavl proof validation precompile for BSC. pub(crate) const IAVL_PROOF_VALIDATION: PrecompileWithAddress = PrecompileWithAddress( crate::u64_to_address(101), - Precompile::Standard(crate::iavl::iavl_proof_validation_run), + Precompile::Standard(iavl_proof_validation_run), ); /// Iavl proof validation precompile for BSC after Nano hardfork. pub(crate) const IAVL_PROOF_VALIDATION_NANO: PrecompileWithAddress = PrecompileWithAddress( crate::u64_to_address(101), - Precompile::Standard(crate::iavl::iavl_proof_validation_run_nano), + Precompile::Standard(iavl_proof_validation_run_nano), ); /// Iavl proof validation precompile for BSC after Moran hardfork. pub(crate) const IAVL_PROOF_VALIDATION_MORAN: PrecompileWithAddress = PrecompileWithAddress( crate::u64_to_address(101), - Precompile::Standard(crate::iavl::iavl_proof_validation_run_moran), + Precompile::Standard(iavl_proof_validation_run_moran), ); /// Iavl proof validation precompile for BSC after Planck hardfork. pub(crate) const IAVL_PROOF_VALIDATION_PLANCK: PrecompileWithAddress = PrecompileWithAddress( crate::u64_to_address(101), - Precompile::Standard(crate::iavl::iavl_proof_validation_run_planck), + Precompile::Standard(iavl_proof_validation_run_planck), ); /// Iavl proof validation precompile for BSC after Plato hardfork. pub(crate) const IAVL_PROOF_VALIDATION_PLATO: PrecompileWithAddress = PrecompileWithAddress( crate::u64_to_address(101), - Precompile::Standard(crate::iavl::iavl_proof_validation_run_plato), + Precompile::Standard(iavl_proof_validation_run_plato), ); /// Run Iavl proof validation. fn iavl_proof_validation_run(input: &Bytes, gas_limit: u64) -> PrecompileResult { - return iavl_proof_validation_run_inner(input, gas_limit, false, false, false); + iavl_proof_validation_run_inner(input, gas_limit, false, false, false) } /// Run Iavl proof validation with Nano hardfork. fn iavl_proof_validation_run_nano(_input: &Bytes, _gas_limit: u64) -> PrecompileResult { - return Err(PrecompileError::other("suspended")); + Err(PrecompileError::other("suspended")) } /// Run Iavl proof validation with Moran hardfork. fn iavl_proof_validation_run_moran(input: &Bytes, gas_limit: u64) -> PrecompileResult { - return iavl_proof_validation_run_inner(input, gas_limit, true, false, false); + iavl_proof_validation_run_inner(input, gas_limit, true, false, false) } /// Run Iavl proof validation with Planck hardfork. fn iavl_proof_validation_run_planck(input: &Bytes, gas_limit: u64) -> PrecompileResult { - return iavl_proof_validation_run_inner(input, gas_limit, false, true, false); + iavl_proof_validation_run_inner(input, gas_limit, false, true, false) } /// Run Iavl proof validation with Plato hardfork. fn iavl_proof_validation_run_plato(input: &Bytes, gas_limit: u64) -> PrecompileResult { - return iavl_proof_validation_run_inner(input, gas_limit, false, false, true); + iavl_proof_validation_run_inner(input, gas_limit, false, false, true) } /// Run Iavl proof validation with given hardfork toggles. @@ -79,7 +81,7 @@ fn iavl_proof_validation_run_inner( IAVL_PROOF_VALIDATION_BASE, Bytes::copy_from_slice(&output[..]), )), - Err(str) => Err(PrecompileError::Other(String::from(str))), + Err(str) => Err(PrecompileError::other(str)), } } @@ -125,7 +127,7 @@ mod tests { assert_eq!( res.err(), - Some(PrecompileError::Other(String::from("invalid merkle proof"))) + Some(PrecompileError::other("invalid merkle proof")) ); } @@ -146,7 +148,7 @@ mod tests { assert_eq!( res.err(), - Some(PrecompileError::Other(String::from("invalid merkle proof"))) + Some(PrecompileError::other("invalid merkle proof")) ); }); @@ -155,7 +157,7 @@ mod tests { assert_eq!( res.err(), - Some(PrecompileError::Other(String::from("invalid merkle proof"))) + Some(PrecompileError::other("invalid merkle proof")) ); } diff --git a/crates/precompile/src/lib.rs b/crates/precompile/src/lib.rs index e02fc3e9..0c211fc8 100644 --- a/crates/precompile/src/lib.rs +++ b/crates/precompile/src/lib.rs @@ -25,6 +25,7 @@ pub mod secp256k1; #[cfg(feature = "secp256r1")] pub mod secp256r1; mod tendermint; +#[cfg(feature = "secp256k1")] mod tm_secp256k1; pub mod utilities; @@ -286,10 +287,10 @@ impl Precompiles { let precompiles = Self::hertz().clone(); let precompiles = { let mut precompiles = precompiles; - precompiles.extend([ - tm_secp256k1::TM_SECP256K1_SIGNATURE_RECOVER, - double_sign::DOUBLE_SIGN_EVIDENCE_VALIDATION, - ]); + // this feature is enabled with bsc + #[cfg(feature = "secp256k1")] + precompiles.extend([tm_secp256k1::TM_SECP256K1_SIGNATURE_RECOVER]); + precompiles.extend([double_sign::DOUBLE_SIGN_EVIDENCE_VALIDATION]); precompiles }; diff --git a/crates/precompile/src/tendermint.rs b/crates/precompile/src/tendermint.rs index d02b6c4a..ef06c96e 100644 --- a/crates/precompile/src/tendermint.rs +++ b/crates/precompile/src/tendermint.rs @@ -16,7 +16,7 @@ pub(crate) const TENDERMINT_HEADER_VALIDATION_NANO: PrecompileWithAddress = Prec /// Run the Tendermint header validation precompile after Nano hardfork. fn tendermint_header_validation_run_nano(_input: &Bytes, _gas_limit: u64) -> PrecompileResult { - return Err(PrecompileError::other("suspended")); + Err(PrecompileError::other("suspended")) } /// Run the Tendermint header validation precompile. @@ -32,7 +32,7 @@ fn tendermint_header_validation_run(input: &Bytes, gas_limit: u64) -> Precompile let res = light_client::TmHeaderVerifier::execute(input.as_ref(), &mut bytes); match res { Ok(()) => Ok((TENDERMINT_HEADER_VALIDATION_BASE, Bytes::from(output))), - Err(str) => Err(PrecompileError::Other(String::from(str))), + Err(str) => Err(PrecompileError::other(str)), } } diff --git a/crates/precompile/src/tm_secp256k1.rs b/crates/precompile/src/tm_secp256k1.rs index 0e3876b9..7dacc9e2 100644 --- a/crates/precompile/src/tm_secp256k1.rs +++ b/crates/precompile/src/tm_secp256k1.rs @@ -30,12 +30,12 @@ fn tm_secp256k1_signature_recover_run(input: &Bytes, gas_limit: u64) -> Precompi if input_length != SECP256K1_PUBKEY_LENGTH + SECP256K1_SIGNATURE_LENGTH + SECP256K1_SIGNATURE_MSGHASH_LENGTH { - return Err(PrecompileError::Other(String::from("invalid input"))); + return Err(PrecompileError::other("invalid input")); } let public_key = match PublicKey::from_slice(&input[..SECP256K1_PUBKEY_LENGTH]) { Ok(pk) => pk, - Err(_) => return Err(PrecompileError::Other(String::from("invalid pubkey"))), + Err(_) => return Err(PrecompileError::other("invalid pubkey")), }; let message = Message::from_digest( @@ -48,19 +48,19 @@ fn tm_secp256k1_signature_recover_run(input: &Bytes, gas_limit: u64) -> Precompi &input[SECP256K1_PUBKEY_LENGTH..SECP256K1_PUBKEY_LENGTH + SECP256K1_SIGNATURE_LENGTH], ) { Ok(s) => s, - Err(_) => return Err(PrecompileError::Other(String::from("invalid signature"))), + Err(_) => return Err(PrecompileError::other("invalid signature")), }; let res = sig.verify(&message, &public_key).is_ok(); if !res { - return Err(PrecompileError::Other(String::from("invalid signature"))); + return Err(PrecompileError::other("invalid signature")); } let tm_pub_key = match public_key::PublicKey::from_raw_secp256k1(&input[..SECP256K1_PUBKEY_LENGTH]) { Some(pk) => pk, - None => return Err(PrecompileError::Other(String::from("invalid pubkey"))), + None => return Err(PrecompileError::other("invalid pubkey")), }; return Ok(( diff --git a/crates/primitives/src/specification.rs b/crates/primitives/src/specification.rs index 82d1fd08..dfb345ee 100644 --- a/crates/primitives/src/specification.rs +++ b/crates/primitives/src/specification.rs @@ -105,11 +105,11 @@ pub enum SpecId { LONDON = 22, // London 31302048 HERTZ = 23, // Hertz 31302048 HERTZ_FIX = 24, // HertzFix 34140700 - SHANGHAI = 25, // Shanghai timestamp(1705996800) 2024-01-23 08:00:00 AM UTC - KEPLER = 26, // Kepler timestamp(1705996800) 2024-01-23 08:00:00 AM UTC - FEYNMAN = 27, // Feynman timestamp(1713419340) 2024-04-18 05:49:00 AM UTC - FEYNMAN_FIX = 28, // FeynmanFix timestamp(1713419340) 2024-04-18 05:49:00 AM UTC - CANCUN = 29, // Cancun timestamp(1718863500) 2024-06-20 06:05:00 AM UTC + SHANGHAI = 25, // Shanghai timestamp(1705996800) + KEPLER = 26, // Kepler timestamp(1705996800) + FEYNMAN = 27, // Feynman timestamp(1713419340) + FEYNMAN_FIX = 28, // FeynmanFix timestamp(1713419340) + CANCUN = 29, // Cancun timestamp(1718863500) HABER = 30, // Haber TBD // TODO: or u8::MAX - n? From b567d8bdc94bae7599c5a5ce6b5c2efc01830528 Mon Sep 17 00:00:00 2001 From: Roshan Date: Fri, 7 Jun 2024 15:10:51 +0800 Subject: [PATCH 07/18] fix CI issues --- .github/workflows/ci.yml | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 27a80efa..bd9b5308 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -32,16 +32,16 @@ jobs: - uses: Swatinem/rust-cache@v2 - run: cargo test --workspace ${{ matrix.flags }} - test-no-std: - name: test no_std - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - uses: actions/checkout@v4 - - uses: dtolnay/rust-toolchain@stable - with: - targets: riscv32imac-unknown-none-elf - - run: cargo check --target riscv32imac-unknown-none-elf --no-default-features +# test-no-std: +# name: test no_std +# runs-on: ubuntu-latest +# timeout-minutes: 30 +# steps: +# - uses: actions/checkout@v4 +# - uses: dtolnay/rust-toolchain@stable +# with: +# targets: riscv32imac-unknown-none-elf +# - run: cargo check --target riscv32imac-unknown-none-elf --no-default-features check-no-default-features: name: check no-default-features From 8de695835a41b086d1ced81845935e84df7eb4ba Mon Sep 17 00:00:00 2001 From: Roshan Date: Sun, 9 Jun 2024 23:43:58 +0800 Subject: [PATCH 08/18] fix wrong precompile contracts set --- crates/precompile/src/lib.rs | 89 +++++++++++++----------------------- 1 file changed, 32 insertions(+), 57 deletions(-) diff --git a/crates/precompile/src/lib.rs b/crates/precompile/src/lib.rs index 0c211fc8..b92ae3f3 100644 --- a/crates/precompile/src/lib.rs +++ b/crates/precompile/src/lib.rs @@ -149,6 +149,9 @@ impl Precompiles { pub fn berlin() -> &'static Self { static INSTANCE: OnceBox = OnceBox::new(); INSTANCE.get_or_init(|| { + #[cfg(feature = "bsc")] + let mut precompiles = Self::plato().clone(); + #[cfg(not(feature = "bsc"))] let mut precompiles = Self::istanbul().clone(); precompiles.extend([ // EIP-2565: ModExp Gas Cost. @@ -164,15 +167,11 @@ impl Precompiles { pub fn fermat() -> &'static Self { static INSTANCE: OnceBox = OnceBox::new(); INSTANCE.get_or_init(|| { - let precompiles = Self::berlin().clone(); - let precompiles = { - let mut precompiles = precompiles; - precompiles.extend([ - bls::BLS_SIGNATURE_VALIDATION, - cometbft::COMETBFT_LIGHT_BLOCK_VALIDATION, - ]); - precompiles - }; + let mut precompiles = Self::berlin().clone(); + precompiles.extend([ + bls::BLS_SIGNATURE_VALIDATION, + cometbft::COMETBFT_LIGHT_BLOCK_VALIDATION, + ]); Box::new(precompiles) }) @@ -182,15 +181,11 @@ impl Precompiles { pub fn nano() -> &'static Self { static INSTANCE: OnceBox = OnceBox::new(); INSTANCE.get_or_init(|| { - let precompiles = Self::istanbul().clone(); - let precompiles = { - let mut precompiles = precompiles; - precompiles.extend([ - tendermint::TENDERMINT_HEADER_VALIDATION_NANO, - iavl::IAVL_PROOF_VALIDATION_NANO, - ]); - precompiles - }; + let mut precompiles = Self::istanbul().clone(); + precompiles.extend([ + tendermint::TENDERMINT_HEADER_VALIDATION_NANO, + iavl::IAVL_PROOF_VALIDATION_NANO, + ]); Box::new(precompiles) }) @@ -200,15 +195,11 @@ impl Precompiles { pub fn moran() -> &'static Self { static INSTANCE: OnceBox = OnceBox::new(); INSTANCE.get_or_init(|| { - let precompiles = Self::istanbul().clone(); - let precompiles = { - let mut precompiles = precompiles; - precompiles.extend([ - tendermint::TENDERMINT_HEADER_VALIDATION, - iavl::IAVL_PROOF_VALIDATION_MORAN, - ]); - precompiles - }; + let mut precompiles = Self::istanbul().clone(); + precompiles.extend([ + tendermint::TENDERMINT_HEADER_VALIDATION, + iavl::IAVL_PROOF_VALIDATION_MORAN, + ]); Box::new(precompiles) }) @@ -218,15 +209,11 @@ impl Precompiles { pub fn planck() -> &'static Self { static INSTANCE: OnceBox = OnceBox::new(); INSTANCE.get_or_init(|| { - let precompiles = Self::istanbul().clone(); - let precompiles = { - let mut precompiles = precompiles; - precompiles.extend([ - tendermint::TENDERMINT_HEADER_VALIDATION, - iavl::IAVL_PROOF_VALIDATION_PLANCK, - ]); - precompiles - }; + let mut precompiles = Self::istanbul().clone(); + precompiles.extend([ + tendermint::TENDERMINT_HEADER_VALIDATION, + iavl::IAVL_PROOF_VALIDATION_PLANCK, + ]); Box::new(precompiles) }) @@ -236,15 +223,11 @@ impl Precompiles { pub fn luban() -> &'static Self { static INSTANCE: OnceBox = OnceBox::new(); INSTANCE.get_or_init(|| { - let precompiles = Self::planck().clone(); - let precompiles = { - let mut precompiles = precompiles; - precompiles.extend([ - bls::BLS_SIGNATURE_VALIDATION, - cometbft::COMETBFT_LIGHT_BLOCK_VALIDATION_BEFORE_HERTZ, - ]); - precompiles - }; + let mut precompiles = Self::planck().clone(); + precompiles.extend([ + bls::BLS_SIGNATURE_VALIDATION, + cometbft::COMETBFT_LIGHT_BLOCK_VALIDATION_BEFORE_HERTZ, + ]); Box::new(precompiles) }) @@ -254,12 +237,8 @@ impl Precompiles { pub fn plato() -> &'static Self { static INSTANCE: OnceBox = OnceBox::new(); INSTANCE.get_or_init(|| { - let precompiles = Self::luban().clone(); - let precompiles = { - let mut precompiles = precompiles; - precompiles.extend([iavl::IAVL_PROOF_VALIDATION_PLATO]); - precompiles - }; + let mut precompiles = Self::luban().clone(); + precompiles.extend([iavl::IAVL_PROOF_VALIDATION_PLATO]); Box::new(precompiles) }) @@ -269,12 +248,8 @@ impl Precompiles { pub fn hertz() -> &'static Self { static INSTANCE: OnceBox = OnceBox::new(); INSTANCE.get_or_init(|| { - let precompiles = Self::plato().clone(); - let precompiles = { - let mut precompiles = precompiles; - precompiles.extend([cometbft::COMETBFT_LIGHT_BLOCK_VALIDATION]); - precompiles - }; + let mut precompiles = Self::berlin().clone(); + precompiles.extend([cometbft::COMETBFT_LIGHT_BLOCK_VALIDATION]); Box::new(precompiles) }) From 54cb75989de30ae46edc026ce1babe3ef8156007 Mon Sep 17 00:00:00 2001 From: Roshan Date: Tue, 11 Jun 2024 16:39:03 +0800 Subject: [PATCH 09/18] fix precompile revert error --- crates/precompile/src/bls.rs | 27 ++++++++++++++------------ crates/precompile/src/double_sign.rs | 15 +++++++------- crates/primitives/src/precompile.rs | 9 --------- crates/revm/src/context/evm_context.rs | 10 ++++++++-- 4 files changed, 31 insertions(+), 30 deletions(-) diff --git a/crates/precompile/src/bls.rs b/crates/precompile/src/bls.rs index b0a87513..eca4651b 100644 --- a/crates/precompile/src/bls.rs +++ b/crates/precompile/src/bls.rs @@ -29,7 +29,8 @@ fn bls_signature_validation_run(input: &Bytes, gas_limit: u64) -> PrecompileResu if (input_length <= msg_and_sig_length) || ((input_length - msg_and_sig_length) % BLS_SINGLE_PUBKEY_LENGTH != 0) { - return Err(Error::BLSInvalidInputLength); + // return zero bytes rather than error to keep align with bsc + return Ok((cost, Bytes::default())); } let msg_hash: &Vec = &input[..BLS_MSG_HASH_LENGTH as usize].to_vec(); @@ -37,7 +38,9 @@ fn bls_signature_validation_run(input: &Bytes, gas_limit: u64) -> PrecompileResu let pub_keys_data = &input[msg_and_sig_length as usize..].to_vec(); // check signature format - let _ = bls::signature_to_point(&signature.to_vec()).map_err(|_| Error::BLSInvalidSignature)?; + if let Err(_) = bls::signature_to_point(&signature.to_vec()) { + return Ok((cost, Bytes::default())); + } let pub_key_count = (input_length - msg_and_sig_length) / BLS_SINGLE_PUBKEY_LENGTH; let mut pub_keys = Vec::with_capacity(pub_key_count as usize); @@ -48,13 +51,13 @@ fn bls_signature_validation_run(input: &Bytes, gas_limit: u64) -> PrecompileResu let pub_key = &pub_keys_data[i as usize * BLS_SINGLE_PUBKEY_LENGTH as usize ..(i + 1) as usize * BLS_SINGLE_PUBKEY_LENGTH as usize]; if !bls::key_validate(&pub_key.to_vec()) { - return Err(Error::BLSInvalidPublicKey); + return Ok((cost, Bytes::default())); } pub_keys.push(pub_key.to_vec()); msg_hashes.push(msg_hash.clone().to_vec()); } if pub_keys.is_empty() { - return Err(Error::BLSInvalidPublicKey); + return Ok((cost, Bytes::default())); } // verify signature @@ -133,8 +136,8 @@ mod tests { input.extend_from_slice(&pub_key); match bls_signature_validation_run(&Bytes::from(input.clone()), 100_000_000) { - Ok(_) => panic!("BLS signature validation failed, expect error"), - Err(e) => assert_eq!(e, Error::BLSInvalidSignature), + Ok((_, data)) => assert_eq!(data, Bytes::default()), + Err(_) => panic!("should not return error"), } // wrong pubkey @@ -147,8 +150,8 @@ mod tests { input.extend_from_slice(&pub_key); match bls_signature_validation_run(&Bytes::from(input.clone()), 100_000_000) { - Ok(_) => panic!("BLS signature validation failed, expect error"), - Err(e) => assert_eq!(e, Error::BLSInvalidSignature), + Ok((_, data)) => assert_eq!(data, Bytes::default()), + Err(_) => panic!("should not return error"), } } @@ -205,8 +208,8 @@ mod tests { input.extend_from_slice(&pub_key3); match bls_signature_validation_run(&Bytes::from(input.clone()), 100_000_000) { - Ok(_) => panic!("BLS signature validation failed, expect error"), - Err(e) => assert_eq!(e, Error::BLSInvalidSignature), + Ok((_, data)) => assert_eq!(data, Bytes::default()), + Err(_) => panic!("should not return error"), } // invalid pubkey @@ -223,8 +226,8 @@ mod tests { input.extend_from_slice(&pub_key3); match bls_signature_validation_run(&Bytes::from(input.clone()), 100_000_000) { - Ok(_) => panic!("BLS signature validation failed, expect error"), - Err(e) => assert_eq!(e, Error::BLSInvalidSignature), + Ok((_, data)) => assert_eq!(data, Bytes::default()), + Err(_) => panic!("should not return error"), } // duplicate pubkey diff --git a/crates/precompile/src/double_sign.rs b/crates/precompile/src/double_sign.rs index 3dc455bb..fde64d6c 100644 --- a/crates/precompile/src/double_sign.rs +++ b/crates/precompile/src/double_sign.rs @@ -9,7 +9,7 @@ use revm_primitives::{keccak256, PrecompileError, B256}; /// Double sign evidence validation precompile for BSC. pub(crate) const DOUBLE_SIGN_EVIDENCE_VALIDATION: PrecompileWithAddress = PrecompileWithAddress( crate::u64_to_address(104), - Precompile::Standard(crate::double_sign::double_sign_evidence_validation_run), + Precompile::Standard(double_sign_evidence_validation_run), ); const EXTRA_SEAL_LENGTH: usize = 65; @@ -81,16 +81,17 @@ fn double_sign_evidence_validation_run(input: &Bytes, gas_limit: u64) -> Precomp let evidence = match DoubleSignEvidence::decode(&mut input.iter().as_ref()) { Ok(e) => e, - Err(_) => return Err(PrecompileError::other("invalid evidence")), + // return zero bytes rather than error to keep align with bsc + Err(_) => return Ok((DOUBLE_SIGN_EVIDENCE_VALIDATION_BASE, Bytes::default())), }; let header1 = match Header::decode(&mut evidence.header_bytes1.as_ref()) { Ok(e) => e, - Err(_) => return Err(PrecompileError::other("invalid evidence")), + Err(_) => return Ok((DOUBLE_SIGN_EVIDENCE_VALIDATION_BASE, Bytes::default())), }; let header2 = match Header::decode(&mut evidence.header_bytes2.as_ref()) { Ok(e) => e, - Err(_) => return Err(PrecompileError::other("invalid evidence")), + Err(_) => return Ok((DOUBLE_SIGN_EVIDENCE_VALIDATION_BASE, Bytes::default())), }; // basic check @@ -125,14 +126,14 @@ fn double_sign_evidence_validation_run(input: &Bytes, gas_limit: u64) -> Precomp let sig1 = <&B512>::try_from(&sig1[..64]).unwrap(); let addr1 = match secp256k1::ecrecover(sig1, recid1, &msg_hash1) { Ok(pk) => pk, - Err(_) => return Err(PrecompileError::other("invalid evidence")), + Err(_) => return Ok((DOUBLE_SIGN_EVIDENCE_VALIDATION_BASE, Bytes::default())), }; let recid2 = sig2[64]; let sig2 = <&B512>::try_from(&sig2[..64]).unwrap(); let addr2 = match secp256k1::ecrecover(sig2, recid2, &msg_hash2) { Ok(pk) => pk, - Err(_) => return Err(PrecompileError::other("invalid evidence")), + Err(_) => return Ok((DOUBLE_SIGN_EVIDENCE_VALIDATION_BASE, Bytes::default())), }; if !addr1.eq(&addr2) { @@ -197,6 +198,6 @@ mod tests { let input = hex::decode("f9066b38b90332f9032fa01062d3d5015b9242bc193a9b0769f3d3780ecb55f97f40a752ae26d0b68cd0d8a0fae1a05fcb14bfd9b8a9f2b65007a9b6c2000de0627a73be644dd993d32342c494df87f0e2b8519ea2dd4abd8b639cdd628497ed25a0f385cc58ed297ff0d66eb5580b02853d3478ba418b1819ac659ee05df49b9794a0bf88464af369ed6b8cf02db00f0b9556ffa8d49cd491b00952a7f83431446638a00a6d0870e586a76278fbfdcedf76ef6679af18fc1f9137cfad495f434974ea81b901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001a1010000000000000000000000000000000000000000000000000000000000000000830f4240830f42408465bc6996b90115d983010306846765746889676f312e32302e3131856c696e7578000053474aa9f8b25fb860b0844a5082bfaa2299d2a23f076e2f6b17b15f839cc3e7d5a875656f6733fd4b87ba3401f906d15f3dea263cd9a6076107c7db620a4630dd3832c4a4b57eb8f497e28a3d69e5c03b30205c4b45675747d513e1accd66329770f3c35b18c9d023f84c84023a5ad6a086a28d985d9a6c8e7f9a4feadd5ace0adba9818e1e1727edca755fcc0bd8344684023a5ad7a0bc3492196b2e68b8e6ceea87cfa7588b4d590089eb885c4f2c1e9d9fb450f7b980988e1b9d0beb91dab063e04879a24c43d33baae3759dee41fd62ffa83c77fd202bea27a829b49e8025bdd198393526dd12b223ab16052fd26a43f3aabf63e76901a0232c9ba2d41b40d36ed794c306747bcbc49bf61a0f37409c18bfe2b5bef26a2d880000000000000000b90332f9032fa01062d3d5015b9242bc193a9b0769f3d3780ecb55f97f40a752ae26d0b68cd0d8a0b2789a5357827ed838335283e15c4dcc42b9bebcbf2919a18613246787e2f96094df87f0e2b8519ea2dd4abd8b639cdd628497ed25a071ce4c09ee275206013f0063761bc19c93c13990582f918cc57333634c94ce89a00e095703e5c9b149f253fe89697230029e32484a410b4b1f2c61442d73c3095aa0d317ae19ede7c8a2d3ac9ef98735b049bcb7278d12f48c42b924538b60a25e12b901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001a1010000000000000000000000000000000000000000000000000000000000000000830f4240830f42408465bc6996b90115d983010306846765746889676f312e32302e3131856c696e7578000053474aa9f8b25fb860b0844a5082bfaa2299d2a23f076e2f6b17b15f839cc3e7d5a875656f6733fd4b87ba3401f906d15f3dea263cd9a6076107c7db620a4630dd3832c4a4b57eb8f497e28a3d69e5c03b30205c4b45675747d513e1accd66329770f3c35b18c9d023f84c84023a5ad6a086a28d985d9a6c8e7f9a4feadd5ace0adba9818e1e1727edca755fcc0bd8344684023a5ad7a0bc3492196b2e68b8e6ceea87cfa7588b4d590089eb885c4f2c1e9d9fb450f7b9804c71ed015dd0c5c2d7393b68c2927f83f0a5da4c66f761f09e2f950cc610832c7876144599368404096ddef0eadacfde57717e2c7d23982b927285b797d41bfa00a0b56228685be711834d0f154292d07826dea42a0fad3e4f56c31470b7fbfbea26880000000000000000").unwrap(); let res = double_sign_evidence_validation_run(&Bytes::from(input), 10_000); - assert_eq!(res.err(), Some(PrecompileError::other("invalid evidence"))); + assert_eq!(res.unwrap().1, Bytes::default()); } } diff --git a/crates/primitives/src/precompile.rs b/crates/primitives/src/precompile.rs index 5fd5845d..69d68565 100644 --- a/crates/primitives/src/precompile.rs +++ b/crates/primitives/src/precompile.rs @@ -125,12 +125,6 @@ pub enum PrecompileError { BlobMismatchedVersion, /// The proof verification failed. BlobVerifyKzgProofFailed, - /// The input length is not matching the expected length. - BLSInvalidInputLength, - /// The bls signature is invalid. - BLSInvalidSignature, - /// The bls public key is invalid. - BLSInvalidPublicKey, /// The cometbft validation input is invalid. CometBftInvalidInput, /// The cometbft apply block failed. @@ -165,9 +159,6 @@ impl fmt::Display for PrecompileError { Self::BlobInvalidInputLength => "invalid blob input length", Self::BlobMismatchedVersion => "mismatched blob version", Self::BlobVerifyKzgProofFailed => "verifying blob kzg proof failed", - Self::BLSInvalidInputLength => "invalid input length for BLS", - Self::BLSInvalidSignature => "invalid BLS signature", - Self::BLSInvalidPublicKey => "invalid BLS public key", Self::CometBftInvalidInput => "invalid cometbft light block validation input", Self::CometBftApplyBlockFailed => "failed to apply cometbft block", Self::CometBftEncodeConsensusStateFailed => "failed to encode cometbft consensus state", diff --git a/crates/revm/src/context/evm_context.rs b/crates/revm/src/context/evm_context.rs index b92d711d..f375b9be 100644 --- a/crates/revm/src/context/evm_context.rs +++ b/crates/revm/src/context/evm_context.rs @@ -121,8 +121,14 @@ impl EvmContext { match out { Ok((gas_used, data)) => { if result.gas.record_cost(gas_used) { - result.result = InstructionResult::Return; - result.output = data; + // to keep align with bsc, revert if data is empty. + // revert will not cost all gas + if data.is_empty() { + result.result = InstructionResult::Revert; + } else { + result.result = InstructionResult::Return; + result.output = data; + } } else { result.result = InstructionResult::PrecompileOOG; } From 29a08a37d4b0354aeb05f4e82e6f72df0e06757d Mon Sep 17 00:00:00 2001 From: Roshan Date: Tue, 11 Jun 2024 17:36:32 +0800 Subject: [PATCH 10/18] add check for bsc precompile --- crates/precompile/src/bls.rs | 2 +- crates/revm/src/context/evm_context.rs | 11 ++++++++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/crates/precompile/src/bls.rs b/crates/precompile/src/bls.rs index eca4651b..179602b4 100644 --- a/crates/precompile/src/bls.rs +++ b/crates/precompile/src/bls.rs @@ -38,7 +38,7 @@ fn bls_signature_validation_run(input: &Bytes, gas_limit: u64) -> PrecompileResu let pub_keys_data = &input[msg_and_sig_length as usize..].to_vec(); // check signature format - if let Err(_) = bls::signature_to_point(&signature.to_vec()) { + if bls::signature_to_point(&signature.to_vec()).is_err() { return Ok((cost, Bytes::default())); } diff --git a/crates/revm/src/context/evm_context.rs b/crates/revm/src/context/evm_context.rs index f375b9be..633f526e 100644 --- a/crates/revm/src/context/evm_context.rs +++ b/crates/revm/src/context/evm_context.rs @@ -13,6 +13,7 @@ use core::{ fmt, ops::{Deref, DerefMut}, }; +use revm_precompile::u64_to_address; use std::boxed::Box; /// EVM context that contains the inner EVM context and precompiles. @@ -123,7 +124,7 @@ impl EvmContext { if result.gas.record_cost(gas_used) { // to keep align with bsc, revert if data is empty. // revert will not cost all gas - if data.is_empty() { + if is_bsc_precompile(address) && data.is_empty() { result.result = InstructionResult::Revert; } else { result.result = InstructionResult::Return; @@ -226,6 +227,14 @@ impl EvmContext { } } +// Helper to check if the address is some specific bsc precompile address. +fn is_bsc_precompile(address: Address) -> bool { + let bls_sig_validation = u64_to_address(102); + let double_sign_evidence_validation = u64_to_address(104); + + address == bls_sig_validation || address == double_sign_evidence_validation +} + /// Test utilities for the [`EvmContext`]. #[cfg(any(test, feature = "test-utils"))] pub(crate) mod test_utils { From 66cc801c611db2d4ca8e878dbda0a431ff658fe0 Mon Sep 17 00:00:00 2001 From: Roshan Date: Thu, 13 Jun 2024 01:09:23 +0800 Subject: [PATCH 11/18] add `PrecompileError::Reverted` --- crates/precompile/src/bls.rs | 25 +++++++++---------- crates/precompile/src/double_sign.rs | 29 +++++++++++----------- crates/primitives/src/precompile.rs | 5 ++++ crates/revm/src/context/evm_context.rs | 34 ++++++++++---------------- 4 files changed, 44 insertions(+), 49 deletions(-) diff --git a/crates/precompile/src/bls.rs b/crates/precompile/src/bls.rs index 179602b4..0f73bb3b 100644 --- a/crates/precompile/src/bls.rs +++ b/crates/precompile/src/bls.rs @@ -29,8 +29,7 @@ fn bls_signature_validation_run(input: &Bytes, gas_limit: u64) -> PrecompileResu if (input_length <= msg_and_sig_length) || ((input_length - msg_and_sig_length) % BLS_SINGLE_PUBKEY_LENGTH != 0) { - // return zero bytes rather than error to keep align with bsc - return Ok((cost, Bytes::default())); + return Err(Error::Reverted(cost)); } let msg_hash: &Vec = &input[..BLS_MSG_HASH_LENGTH as usize].to_vec(); @@ -39,7 +38,7 @@ fn bls_signature_validation_run(input: &Bytes, gas_limit: u64) -> PrecompileResu // check signature format if bls::signature_to_point(&signature.to_vec()).is_err() { - return Ok((cost, Bytes::default())); + return Err(Error::Reverted(cost)); } let pub_key_count = (input_length - msg_and_sig_length) / BLS_SINGLE_PUBKEY_LENGTH; @@ -51,13 +50,13 @@ fn bls_signature_validation_run(input: &Bytes, gas_limit: u64) -> PrecompileResu let pub_key = &pub_keys_data[i as usize * BLS_SINGLE_PUBKEY_LENGTH as usize ..(i + 1) as usize * BLS_SINGLE_PUBKEY_LENGTH as usize]; if !bls::key_validate(&pub_key.to_vec()) { - return Ok((cost, Bytes::default())); + return Err(Error::Reverted(cost)); } pub_keys.push(pub_key.to_vec()); msg_hashes.push(msg_hash.clone().to_vec()); } if pub_keys.is_empty() { - return Ok((cost, Bytes::default())); + return Err(Error::Reverted(cost)); } // verify signature @@ -136,8 +135,8 @@ mod tests { input.extend_from_slice(&pub_key); match bls_signature_validation_run(&Bytes::from(input.clone()), 100_000_000) { - Ok((_, data)) => assert_eq!(data, Bytes::default()), - Err(_) => panic!("should not return error"), + Ok(_) => panic!("BLS signature validation failed, expect error"), + Err(e) => assert_eq!(e, Error::Reverted(4500)), } // wrong pubkey @@ -150,8 +149,8 @@ mod tests { input.extend_from_slice(&pub_key); match bls_signature_validation_run(&Bytes::from(input.clone()), 100_000_000) { - Ok((_, data)) => assert_eq!(data, Bytes::default()), - Err(_) => panic!("should not return error"), + Ok(_) => panic!("BLS signature validation failed, expect error"), + Err(e) => assert_eq!(e, Error::Reverted(4500)), } } @@ -208,8 +207,8 @@ mod tests { input.extend_from_slice(&pub_key3); match bls_signature_validation_run(&Bytes::from(input.clone()), 100_000_000) { - Ok((_, data)) => assert_eq!(data, Bytes::default()), - Err(_) => panic!("should not return error"), + Ok(_) => panic!("BLS signature validation failed, expect error"), + Err(e) => assert_eq!(e, Error::Reverted(11500)), } // invalid pubkey @@ -226,8 +225,8 @@ mod tests { input.extend_from_slice(&pub_key3); match bls_signature_validation_run(&Bytes::from(input.clone()), 100_000_000) { - Ok((_, data)) => assert_eq!(data, Bytes::default()), - Err(_) => panic!("should not return error"), + Ok(_) => panic!("BLS signature validation failed, expect error"), + Err(e) => assert_eq!(e, Error::Reverted(11500)), } // duplicate pubkey diff --git a/crates/precompile/src/double_sign.rs b/crates/precompile/src/double_sign.rs index fde64d6c..f7ad52d4 100644 --- a/crates/precompile/src/double_sign.rs +++ b/crates/precompile/src/double_sign.rs @@ -4,7 +4,7 @@ use alloy_primitives::{BlockNumber, ChainId, U256}; use alloy_rlp::{Decodable, RlpDecodable, RlpEncodable}; use core::cmp::Ordering; use revm_primitives::alloy_primitives::B512; -use revm_primitives::{keccak256, PrecompileError, B256}; +use revm_primitives::{keccak256, B256}; /// Double sign evidence validation precompile for BSC. pub(crate) const DOUBLE_SIGN_EVIDENCE_VALIDATION: PrecompileWithAddress = PrecompileWithAddress( @@ -81,37 +81,36 @@ fn double_sign_evidence_validation_run(input: &Bytes, gas_limit: u64) -> Precomp let evidence = match DoubleSignEvidence::decode(&mut input.iter().as_ref()) { Ok(e) => e, - // return zero bytes rather than error to keep align with bsc - Err(_) => return Ok((DOUBLE_SIGN_EVIDENCE_VALIDATION_BASE, Bytes::default())), + Err(_) => return Err(Error::Reverted(DOUBLE_SIGN_EVIDENCE_VALIDATION_BASE)), }; let header1 = match Header::decode(&mut evidence.header_bytes1.as_ref()) { Ok(e) => e, - Err(_) => return Ok((DOUBLE_SIGN_EVIDENCE_VALIDATION_BASE, Bytes::default())), + Err(_) => return Err(Error::Reverted(DOUBLE_SIGN_EVIDENCE_VALIDATION_BASE)), }; let header2 = match Header::decode(&mut evidence.header_bytes2.as_ref()) { Ok(e) => e, - Err(_) => return Ok((DOUBLE_SIGN_EVIDENCE_VALIDATION_BASE, Bytes::default())), + Err(_) => return Err(Error::Reverted(DOUBLE_SIGN_EVIDENCE_VALIDATION_BASE)), }; // basic check if header1.number.to_be_bytes().len() > 32 || header2.number.to_be_bytes().len() > 32 { - return Err(PrecompileError::other("invalid evidence")); + return Err(Error::other("invalid evidence")); } if header1.number != header2.number { - return Err(PrecompileError::other("invalid evidence")); + return Err(Error::other("invalid evidence")); } if header1.parent_hash.cmp(&header2.parent_hash) != Ordering::Equal { - return Err(PrecompileError::other("invalid evidence")); + return Err(Error::other("invalid evidence")); } if header1.extra.len() < EXTRA_SEAL_LENGTH || header1.extra.len() < EXTRA_SEAL_LENGTH { - return Err(PrecompileError::other("invalid evidence")); + return Err(Error::other("invalid evidence")); } let sig1 = &header1.extra[header1.extra.len() - EXTRA_SEAL_LENGTH..]; let sig2 = &header2.extra[header2.extra.len() - EXTRA_SEAL_LENGTH..]; if sig1.eq(sig2) { - return Err(PrecompileError::other("invalid evidence")); + return Err(Error::other("invalid evidence")); } // check signature @@ -119,25 +118,25 @@ fn double_sign_evidence_validation_run(input: &Bytes, gas_limit: u64) -> Precomp let msg_hash2 = seal_hash(&header2, evidence.chain_id); if msg_hash1.eq(&msg_hash2) { - return Err(PrecompileError::other("invalid evidence")); + return Err(Error::other("invalid evidence")); } let recid1 = sig1[64]; let sig1 = <&B512>::try_from(&sig1[..64]).unwrap(); let addr1 = match secp256k1::ecrecover(sig1, recid1, &msg_hash1) { Ok(pk) => pk, - Err(_) => return Ok((DOUBLE_SIGN_EVIDENCE_VALIDATION_BASE, Bytes::default())), + Err(_) => return Err(Error::Reverted(DOUBLE_SIGN_EVIDENCE_VALIDATION_BASE)), }; let recid2 = sig2[64]; let sig2 = <&B512>::try_from(&sig2[..64]).unwrap(); let addr2 = match secp256k1::ecrecover(sig2, recid2, &msg_hash2) { Ok(pk) => pk, - Err(_) => return Ok((DOUBLE_SIGN_EVIDENCE_VALIDATION_BASE, Bytes::default())), + Err(_) => return Err(Error::Reverted(DOUBLE_SIGN_EVIDENCE_VALIDATION_BASE)), }; if !addr1.eq(&addr2) { - return Err(PrecompileError::other("invalid evidence")); + return Err(Error::other("invalid evidence")); } let mut res = [0; 52]; @@ -198,6 +197,6 @@ mod tests { let input = hex::decode("f9066b38b90332f9032fa01062d3d5015b9242bc193a9b0769f3d3780ecb55f97f40a752ae26d0b68cd0d8a0fae1a05fcb14bfd9b8a9f2b65007a9b6c2000de0627a73be644dd993d32342c494df87f0e2b8519ea2dd4abd8b639cdd628497ed25a0f385cc58ed297ff0d66eb5580b02853d3478ba418b1819ac659ee05df49b9794a0bf88464af369ed6b8cf02db00f0b9556ffa8d49cd491b00952a7f83431446638a00a6d0870e586a76278fbfdcedf76ef6679af18fc1f9137cfad495f434974ea81b901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001a1010000000000000000000000000000000000000000000000000000000000000000830f4240830f42408465bc6996b90115d983010306846765746889676f312e32302e3131856c696e7578000053474aa9f8b25fb860b0844a5082bfaa2299d2a23f076e2f6b17b15f839cc3e7d5a875656f6733fd4b87ba3401f906d15f3dea263cd9a6076107c7db620a4630dd3832c4a4b57eb8f497e28a3d69e5c03b30205c4b45675747d513e1accd66329770f3c35b18c9d023f84c84023a5ad6a086a28d985d9a6c8e7f9a4feadd5ace0adba9818e1e1727edca755fcc0bd8344684023a5ad7a0bc3492196b2e68b8e6ceea87cfa7588b4d590089eb885c4f2c1e9d9fb450f7b980988e1b9d0beb91dab063e04879a24c43d33baae3759dee41fd62ffa83c77fd202bea27a829b49e8025bdd198393526dd12b223ab16052fd26a43f3aabf63e76901a0232c9ba2d41b40d36ed794c306747bcbc49bf61a0f37409c18bfe2b5bef26a2d880000000000000000b90332f9032fa01062d3d5015b9242bc193a9b0769f3d3780ecb55f97f40a752ae26d0b68cd0d8a0b2789a5357827ed838335283e15c4dcc42b9bebcbf2919a18613246787e2f96094df87f0e2b8519ea2dd4abd8b639cdd628497ed25a071ce4c09ee275206013f0063761bc19c93c13990582f918cc57333634c94ce89a00e095703e5c9b149f253fe89697230029e32484a410b4b1f2c61442d73c3095aa0d317ae19ede7c8a2d3ac9ef98735b049bcb7278d12f48c42b924538b60a25e12b901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001a1010000000000000000000000000000000000000000000000000000000000000000830f4240830f42408465bc6996b90115d983010306846765746889676f312e32302e3131856c696e7578000053474aa9f8b25fb860b0844a5082bfaa2299d2a23f076e2f6b17b15f839cc3e7d5a875656f6733fd4b87ba3401f906d15f3dea263cd9a6076107c7db620a4630dd3832c4a4b57eb8f497e28a3d69e5c03b30205c4b45675747d513e1accd66329770f3c35b18c9d023f84c84023a5ad6a086a28d985d9a6c8e7f9a4feadd5ace0adba9818e1e1727edca755fcc0bd8344684023a5ad7a0bc3492196b2e68b8e6ceea87cfa7588b4d590089eb885c4f2c1e9d9fb450f7b9804c71ed015dd0c5c2d7393b68c2927f83f0a5da4c66f761f09e2f950cc610832c7876144599368404096ddef0eadacfde57717e2c7d23982b927285b797d41bfa00a0b56228685be711834d0f154292d07826dea42a0fad3e4f56c31470b7fbfbea26880000000000000000").unwrap(); let res = double_sign_evidence_validation_run(&Bytes::from(input), 10_000); - assert_eq!(res.unwrap().1, Bytes::default()); + assert_eq!(res.err(), Some(Error::Reverted(10000))); } } diff --git a/crates/primitives/src/precompile.rs b/crates/primitives/src/precompile.rs index 69d68565..903013ff 100644 --- a/crates/primitives/src/precompile.rs +++ b/crates/primitives/src/precompile.rs @@ -133,6 +133,10 @@ pub enum PrecompileError { CometBftEncodeConsensusStateFailed, /// Catch-all variant for other errors. Other(String), + /// Reverted error + /// This is for BSC EVM compatibility specially. + /// This error will not consume all gas but only the returned amount. + Reverted(u64), } impl PrecompileError { @@ -163,6 +167,7 @@ impl fmt::Display for PrecompileError { Self::CometBftApplyBlockFailed => "failed to apply cometbft block", Self::CometBftEncodeConsensusStateFailed => "failed to encode cometbft consensus state", Self::Other(s) => s, + Self::Reverted(_) => "execution reverted", }; f.write_str(s) } diff --git a/crates/revm/src/context/evm_context.rs b/crates/revm/src/context/evm_context.rs index 633f526e..62356ef6 100644 --- a/crates/revm/src/context/evm_context.rs +++ b/crates/revm/src/context/evm_context.rs @@ -13,7 +13,6 @@ use core::{ fmt, ops::{Deref, DerefMut}, }; -use revm_precompile::u64_to_address; use std::boxed::Box; /// EVM context that contains the inner EVM context and precompiles. @@ -122,23 +121,24 @@ impl EvmContext { match out { Ok((gas_used, data)) => { if result.gas.record_cost(gas_used) { - // to keep align with bsc, revert if data is empty. - // revert will not cost all gas - if is_bsc_precompile(address) && data.is_empty() { - result.result = InstructionResult::Revert; - } else { - result.result = InstructionResult::Return; - result.output = data; - } + result.result = InstructionResult::Return; + result.output = data; } else { result.result = InstructionResult::PrecompileOOG; } } Err(e) => { - result.result = if e == crate::precompile::Error::OutOfGas { - InstructionResult::PrecompileOOG - } else { - InstructionResult::PrecompileError + result.result = match e{ + crate::precompile::Error::OutOfGas => InstructionResult::PrecompileOOG, + // for BSC compatibility + crate::precompile::Error::Reverted(gas_used) => { + if result.gas.record_cost(gas_used) { + InstructionResult::Revert + } else { + InstructionResult::PrecompileOOG + } + }, + _ => InstructionResult::PrecompileError, }; } } @@ -227,14 +227,6 @@ impl EvmContext { } } -// Helper to check if the address is some specific bsc precompile address. -fn is_bsc_precompile(address: Address) -> bool { - let bls_sig_validation = u64_to_address(102); - let double_sign_evidence_validation = u64_to_address(104); - - address == bls_sig_validation || address == double_sign_evidence_validation -} - /// Test utilities for the [`EvmContext`]. #[cfg(any(test, feature = "test-utils"))] pub(crate) mod test_utils { From 88b9a1337dc625f0f6935e9c1f125278e7dd01b5 Mon Sep 17 00:00:00 2001 From: Roshan Date: Thu, 13 Jun 2024 01:14:29 +0800 Subject: [PATCH 12/18] fix evm spec for `KEPLER` --- crates/primitives/src/specification.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/crates/primitives/src/specification.rs b/crates/primitives/src/specification.rs index dfb345ee..99bd5b36 100644 --- a/crates/primitives/src/specification.rs +++ b/crates/primitives/src/specification.rs @@ -599,12 +599,12 @@ macro_rules! spec_to_generic { use $crate::MergeSpec as SPEC; $e } - $crate::SpecId::SHANGHAI => { - use $crate::ShanghaiSpec as SPEC; + $crate::SpecId::HERTZ | $crate::SpecId::HERTZ_FIX => { + use $crate::HertzSpec as SPEC; $e } - $crate::SpecId::HERTZ | $crate::SpecId::HERTZ_FIX | $crate::SpecId::KEPLER => { - use $crate::HertzSpec as SPEC; + $crate::SpecId::SHANGHAI | $crate::SpecId::KEPLER => { + use $crate::ShanghaiSpec as SPEC; $e } $crate::SpecId::FEYNMAN | $crate::SpecId::FEYNMAN_FIX => { From a7773a99ab832d08b31de475798a924fa6f74a90 Mon Sep 17 00:00:00 2001 From: Roshan Date: Thu, 13 Jun 2024 10:20:42 +0800 Subject: [PATCH 13/18] fix CI issues --- crates/primitives/src/specification.rs | 2 +- crates/revm/src/context/evm_context.rs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/crates/primitives/src/specification.rs b/crates/primitives/src/specification.rs index 99bd5b36..ae2ee650 100644 --- a/crates/primitives/src/specification.rs +++ b/crates/primitives/src/specification.rs @@ -708,7 +708,7 @@ mod tests { #[cfg(feature = "bsc")] spec_to_generic!(HERTZ_FIX, assert_eq!(SPEC::SPEC_ID, HERTZ)); #[cfg(feature = "bsc")] - spec_to_generic!(KEPLER, assert_eq!(SPEC::SPEC_ID, HERTZ)); + spec_to_generic!(KEPLER, assert_eq!(SPEC::SPEC_ID, SHANGHAI)); #[cfg(feature = "bsc")] spec_to_generic!(FEYNMAN, assert_eq!(SPEC::SPEC_ID, FEYNMAN)); #[cfg(feature = "bsc")] diff --git a/crates/revm/src/context/evm_context.rs b/crates/revm/src/context/evm_context.rs index 62356ef6..85a3d7e9 100644 --- a/crates/revm/src/context/evm_context.rs +++ b/crates/revm/src/context/evm_context.rs @@ -128,7 +128,7 @@ impl EvmContext { } } Err(e) => { - result.result = match e{ + result.result = match e { crate::precompile::Error::OutOfGas => InstructionResult::PrecompileOOG, // for BSC compatibility crate::precompile::Error::Reverted(gas_used) => { @@ -137,7 +137,7 @@ impl EvmContext { } else { InstructionResult::PrecompileOOG } - }, + } _ => InstructionResult::PrecompileError, }; } From a21eec775b5954253e73a267a6527ccd001c92b3 Mon Sep 17 00:00:00 2001 From: Roshan Date: Thu, 13 Jun 2024 14:56:39 +0800 Subject: [PATCH 14/18] add `haber` precompile set and fix errors --- crates/precompile/src/lib.rs | 49 ++++++++++++++------ crates/primitives/src/specification.rs | 10 +++- crates/revm/src/optimism/handler_register.rs | 2 +- 3 files changed, 45 insertions(+), 16 deletions(-) diff --git a/crates/precompile/src/lib.rs b/crates/precompile/src/lib.rs index b92ae3f3..a63d84c2 100644 --- a/crates/precompile/src/lib.rs +++ b/crates/precompile/src/lib.rs @@ -84,6 +84,7 @@ impl Precompiles { PrecompileSpecId::FEYNMAN => Self::feynman(), PrecompileSpecId::CANCUN => Self::cancun(), PrecompileSpecId::PRAGUE => Self::prague(), + PrecompileSpecId::HABER => Self::haber(), PrecompileSpecId::LATEST => Self::latest(), } } @@ -259,15 +260,12 @@ impl Precompiles { pub fn feynman() -> &'static Self { static INSTANCE: OnceBox = OnceBox::new(); INSTANCE.get_or_init(|| { - let precompiles = Self::hertz().clone(); - let precompiles = { - let mut precompiles = precompiles; - // this feature is enabled with bsc - #[cfg(feature = "secp256k1")] - precompiles.extend([tm_secp256k1::TM_SECP256K1_SIGNATURE_RECOVER]); - precompiles.extend([double_sign::DOUBLE_SIGN_EVIDENCE_VALIDATION]); - precompiles - }; + let mut precompiles = Self::hertz().clone(); + precompiles.extend([double_sign::DOUBLE_SIGN_EVIDENCE_VALIDATION]); + + // this feature is enabled with bsc + #[cfg(feature = "secp256k1")] + precompiles.extend([tm_secp256k1::TM_SECP256K1_SIGNATURE_RECOVER]); Box::new(precompiles) }) @@ -280,6 +278,9 @@ impl Precompiles { pub fn cancun() -> &'static Self { static INSTANCE: OnceBox = OnceBox::new(); INSTANCE.get_or_init(|| { + #[cfg(feature = "bsc")] + let precompiles = Self::feynman().clone(); + #[cfg(not(feature = "bsc"))] let precompiles = Self::berlin().clone(); // Don't include KZG point evaluation precompile in no_std builds. @@ -319,9 +320,30 @@ impl Precompiles { }) } + /// Returns precompiles for Haber spec. + pub fn haber() -> &'static Self { + static INSTANCE: OnceBox = OnceBox::new(); + INSTANCE.get_or_init(|| { + let precompiles = Self::cancun().clone(); + + #[cfg(feature = "secp256r1")] + let precompiles = { + let mut precompiles = precompiles; + precompiles.extend([secp256r1::P256VERIFY]); + precompiles + }; + + Box::new(precompiles) + }) + } + /// Returns the precompiles for the latest spec. pub fn latest() -> &'static Self { - Self::prague() + if cfg!(feature = "bsc") { + Self::haber() + } else { + Self::prague() + } } /// Returns an iterator over the precompiles addresses. @@ -402,6 +424,7 @@ pub enum PrecompileSpecId { PLATO, // BSC PLATO HARDFORK HERTZ, // BSC HERTZ HARDFORK FEYNMAN, // BSC FEYNMAN HARDFORK + HABER, // BSC HABER HARDFORK CANCUN, PRAGUE, @@ -434,7 +457,7 @@ impl PrecompileSpecId { #[cfg(feature = "bsc")] HERTZ | HERTZ_FIX | KEPLER => Self::HERTZ, #[cfg(feature = "bsc")] - FEYNMAN | FEYNMAN_FIX | HABER => Self::FEYNMAN, + FEYNMAN | FEYNMAN_FIX => Self::FEYNMAN, CANCUN => Self::CANCUN, PRAGUE => Self::PRAGUE, #[cfg(feature = "optimism")] @@ -443,8 +466,8 @@ impl PrecompileSpecId { ECOTONE | FJORD => Self::CANCUN, #[cfg(feature = "opbnb")] FERMAT => Self::FERMAT, - #[cfg(feature = "opbnb")] - HABER => Self::CANCUN, + #[cfg(any(feature = "bsc", feature = "opbnb"))] + HABER => Self::HABER, LATEST => Self::LATEST, } } diff --git a/crates/primitives/src/specification.rs b/crates/primitives/src/specification.rs index ae2ee650..ebf2ded5 100644 --- a/crates/primitives/src/specification.rs +++ b/crates/primitives/src/specification.rs @@ -344,6 +344,8 @@ spec!(PLATO, PlatoSpec); #[cfg(feature = "bsc")] spec!(HERTZ, HertzSpec); #[cfg(feature = "bsc")] +spec!(KEPLER, KeplerSpec); +#[cfg(feature = "bsc")] spec!(FEYNMAN, FeynmanSpec); #[cfg(any(feature = "bsc", feature = "opbnb"))] spec!(HABER, HaberSpec); @@ -603,10 +605,14 @@ macro_rules! spec_to_generic { use $crate::HertzSpec as SPEC; $e } - $crate::SpecId::SHANGHAI | $crate::SpecId::KEPLER => { + $crate::SpecId::SHANGHAI => { use $crate::ShanghaiSpec as SPEC; $e } + $crate::SpecId::KEPLER => { + use $crate::KeplerSpec as SPEC; + $e + } $crate::SpecId::FEYNMAN | $crate::SpecId::FEYNMAN_FIX => { use $crate::FeynmanSpec as SPEC; $e @@ -708,7 +714,7 @@ mod tests { #[cfg(feature = "bsc")] spec_to_generic!(HERTZ_FIX, assert_eq!(SPEC::SPEC_ID, HERTZ)); #[cfg(feature = "bsc")] - spec_to_generic!(KEPLER, assert_eq!(SPEC::SPEC_ID, SHANGHAI)); + spec_to_generic!(KEPLER, assert_eq!(SPEC::SPEC_ID, KEPLER)); #[cfg(feature = "bsc")] spec_to_generic!(FEYNMAN, assert_eq!(SPEC::SPEC_ID, FEYNMAN)); #[cfg(feature = "bsc")] diff --git a/crates/revm/src/optimism/handler_register.rs b/crates/revm/src/optimism/handler_register.rs index 6ce298b5..d4996cca 100644 --- a/crates/revm/src/optimism/handler_register.rs +++ b/crates/revm/src/optimism/handler_register.rs @@ -145,7 +145,7 @@ pub fn last_frame_return( pub fn load_precompiles() -> ContextPrecompiles { let mut precompiles = Precompiles::new(PrecompileSpecId::from_spec_id(SPEC::SPEC_ID)).clone(); - if SPEC::enabled(SpecId::FJORD) || SPEC::enabled(SpecId::HABER) { + if SPEC::enabled(SpecId::FJORD) { precompiles.extend([ // EIP-7212: secp256r1 P256verify secp256r1::P256VERIFY, From da3e04abb285f7d3df466e03c67260f66425483a Mon Sep 17 00:00:00 2001 From: Roshan Date: Fri, 14 Jun 2024 10:48:31 +0800 Subject: [PATCH 15/18] add EIP4844 data fee to `collect_system_reward` --- crates/revm/src/bsc/handler_register.rs | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/crates/revm/src/bsc/handler_register.rs b/crates/revm/src/bsc/handler_register.rs index d87429ed..3100f9ba 100644 --- a/crates/revm/src/bsc/handler_register.rs +++ b/crates/revm/src/bsc/handler_register.rs @@ -5,7 +5,7 @@ use crate::{ interpreter::Gas, primitives::{ address, db::Database, spec_to_generic, Address, EVMError, Env, ExecutionResult, - InvalidTransaction, ResultAndState, Spec, SpecId, U256, + InvalidTransaction, ResultAndState, Spec, SpecId, CANCUN, U256, }, Context, FrameResult, }; @@ -53,6 +53,18 @@ pub fn collect_system_reward( gas: &Gas, ) -> Result<(), EVMError> { let effective_gas_price = context.evm.env.effective_gas_price(); + let mut tx_fee = U256::from(gas.spent() - gas.refunded() as u64) * effective_gas_price; + + // EIP-4844 + if SPEC::enabled(CANCUN) { + let data_fee = &context + .evm + .inner + .env + .calc_data_fee() + .expect("already checked"); + tx_fee = tx_fee.saturating_add(*data_fee); + } let (system_account, _) = context .evm @@ -61,10 +73,7 @@ pub fn collect_system_reward( .load_account(SYSTEM_ADDRESS, &mut context.evm.inner.db)?; system_account.mark_touch(); - system_account.info.balance = system_account - .info - .balance - .saturating_add(effective_gas_price * U256::from(gas.spent() - gas.refunded() as u64)); + system_account.info.balance = system_account.info.balance.saturating_add(tx_fee); Ok(()) } From 38c604ee82389961a4ddd11cf81716c118719dce Mon Sep 17 00:00:00 2001 From: Roshan Date: Fri, 14 Jun 2024 16:34:56 +0800 Subject: [PATCH 16/18] update bsc feature dep --- Cargo.lock | 15 +++++++-------- crates/precompile/Cargo.toml | 2 +- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1928f084..050aa710 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2364,12 +2364,12 @@ dependencies = [ [[package]] name = "http-body-util" -version = "0.1.1" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0475f8b2ac86659c21b64320d5d653f9efe42acd2a4e560073ec61a155a34f1d" +checksum = "793429d76616a256bcb62c2a2ec2bed781c8307e797e2598c50010f2bee2544f" dependencies = [ "bytes 1.6.0", - "futures-core", + "futures-util", "http 1.1.0", "http-body 1.0.0", "pin-project-lite", @@ -2463,9 +2463,9 @@ dependencies = [ [[package]] name = "hyper-util" -version = "0.1.3" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca38ef113da30126bbff9cd1705f9273e15d45498615d138b0c20279ac7a76aa" +checksum = "7b875924a60b96e5d7b9ae7b066540b1dd1cbd90d1828f54c92e02a283351c56" dependencies = [ "bytes 1.6.0", "futures-channel", @@ -2824,11 +2824,10 @@ dependencies = [ [[package]] name = "native-tls" -version = "0.2.11" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e" +checksum = "a8614eb2c83d59d1c8cc974dd3f920198647674a0a035e1af1fa58707e317466" dependencies = [ - "lazy_static", "libc", "log", "openssl", diff --git a/crates/precompile/Cargo.toml b/crates/precompile/Cargo.toml index c89f2746..0fd57e1e 100644 --- a/crates/precompile/Cargo.toml +++ b/crates/precompile/Cargo.toml @@ -83,7 +83,7 @@ std = [ hashbrown = ["revm-primitives/hashbrown"] asm-keccak = ["revm-primitives/asm-keccak"] -bsc = ["revm-primitives/bsc", "secp256k1"] +bsc = ["revm-primitives/bsc", "secp256k1", "secp256r1"] optimism = ["revm-primitives/optimism", "secp256r1"] # Optimism default handler enabled Optimism handler register by default in EvmBuilder. optimism-default-handler = [ From 28b7d6da7cfd33989d1597a7caddbec0eafb0a02 Mon Sep 17 00:00:00 2001 From: Roshan Date: Mon, 17 Jun 2024 10:36:07 +0800 Subject: [PATCH 17/18] fix review comments --- Cargo.lock | 4 ++-- crates/precompile/Cargo.toml | 2 +- crates/primitives/src/specification.rs | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 050aa710..5e077e73 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4795,7 +4795,7 @@ dependencies = [ [[package]] name = "tendermint" version = "0.17.0" -source = "git+https://github.com/forcodedancing/tendermint-rs-parlia?rev=10cfd14bac4cd4f1180a6670ea44edabfeda2519#10cfd14bac4cd4f1180a6670ea44edabfeda2519" +source = "git+https://github.com/bnb-chain/tendermint-rs-parlia?rev=5c5cccaaf6fb0459c433e6312bed2a24386159db#5c5cccaaf6fb0459c433e6312bed2a24386159db" dependencies = [ "anomaly", "async-trait", @@ -4834,7 +4834,7 @@ dependencies = [ [[package]] name = "tendermint-proto" version = "0.17.0" -source = "git+https://github.com/forcodedancing/tendermint-rs-parlia?rev=10cfd14bac4cd4f1180a6670ea44edabfeda2519#10cfd14bac4cd4f1180a6670ea44edabfeda2519" +source = "git+https://github.com/bnb-chain/tendermint-rs-parlia?rev=5c5cccaaf6fb0459c433e6312bed2a24386159db#5c5cccaaf6fb0459c433e6312bed2a24386159db" dependencies = [ "anomaly", "bytes 0.5.6", diff --git a/crates/precompile/Cargo.toml b/crates/precompile/Cargo.toml index 0fd57e1e..0a463d96 100644 --- a/crates/precompile/Cargo.toml +++ b/crates/precompile/Cargo.toml @@ -46,7 +46,7 @@ cometbft-proto = { git = "https://github.com/bnb-chain/greenfield-cometbft-rs.g cometbft-light-client = { git = "https://github.com/bnb-chain/greenfield-cometbft-rs.git", rev = "1282547" } prost = { version = "0.12.3" } bls_on_arkworks = "0.3.0" -tendermint = { git = "https://github.com/forcodedancing/tendermint-rs-parlia", rev = "10cfd14bac4cd4f1180a6670ea44edabfeda2519", features = ["secp256k1"] } +tendermint = { git = "https://github.com/bnb-chain/tendermint-rs-parlia", rev = "5c5cccaaf6fb0459c433e6312bed2a24386159db", features = ["secp256k1"] } parity-bytes = { version = "0.1.2", default-features = false } alloy-rlp = { version = "0.3", default-features = false, features = [ "arrayvec", diff --git a/crates/primitives/src/specification.rs b/crates/primitives/src/specification.rs index ebf2ded5..918b9039 100644 --- a/crates/primitives/src/specification.rs +++ b/crates/primitives/src/specification.rs @@ -110,7 +110,7 @@ pub enum SpecId { FEYNMAN = 27, // Feynman timestamp(1713419340) FEYNMAN_FIX = 28, // FeynmanFix timestamp(1713419340) CANCUN = 29, // Cancun timestamp(1718863500) - HABER = 30, // Haber TBD + HABER = 30, // Haber timestamp(1718863500) // TODO: or u8::MAX - n? /// Not enabled in bsc From 785147a6d3044bcaa6d7c092f608f0329f99f576 Mon Sep 17 00:00:00 2001 From: Roshan Date: Mon, 17 Jun 2024 11:08:57 +0800 Subject: [PATCH 18/18] update `tendermint` version --- Cargo.lock | 4 ++-- crates/precompile/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5e077e73..bfa4a9d8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4795,7 +4795,7 @@ dependencies = [ [[package]] name = "tendermint" version = "0.17.0" -source = "git+https://github.com/bnb-chain/tendermint-rs-parlia?rev=5c5cccaaf6fb0459c433e6312bed2a24386159db#5c5cccaaf6fb0459c433e6312bed2a24386159db" +source = "git+https://github.com/bnb-chain/tendermint-rs-parlia?tag=v0.1.0-beta.1#5c5cccaaf6fb0459c433e6312bed2a24386159db" dependencies = [ "anomaly", "async-trait", @@ -4834,7 +4834,7 @@ dependencies = [ [[package]] name = "tendermint-proto" version = "0.17.0" -source = "git+https://github.com/bnb-chain/tendermint-rs-parlia?rev=5c5cccaaf6fb0459c433e6312bed2a24386159db#5c5cccaaf6fb0459c433e6312bed2a24386159db" +source = "git+https://github.com/bnb-chain/tendermint-rs-parlia?tag=v0.1.0-beta.1#5c5cccaaf6fb0459c433e6312bed2a24386159db" dependencies = [ "anomaly", "bytes 0.5.6", diff --git a/crates/precompile/Cargo.toml b/crates/precompile/Cargo.toml index 0a463d96..5f066031 100644 --- a/crates/precompile/Cargo.toml +++ b/crates/precompile/Cargo.toml @@ -46,7 +46,7 @@ cometbft-proto = { git = "https://github.com/bnb-chain/greenfield-cometbft-rs.g cometbft-light-client = { git = "https://github.com/bnb-chain/greenfield-cometbft-rs.git", rev = "1282547" } prost = { version = "0.12.3" } bls_on_arkworks = "0.3.0" -tendermint = { git = "https://github.com/bnb-chain/tendermint-rs-parlia", rev = "5c5cccaaf6fb0459c433e6312bed2a24386159db", features = ["secp256k1"] } +tendermint = { git = "https://github.com/bnb-chain/tendermint-rs-parlia", tag = "v0.1.0-beta.1", features = ["secp256k1"] } parity-bytes = { version = "0.1.2", default-features = false } alloy-rlp = { version = "0.3", default-features = false, features = [ "arrayvec",