diff --git a/Cargo.lock b/Cargo.lock index 35c501906b..6c6832c167 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -331,7 +331,7 @@ dependencies = [ "num-traits", "rusticata-macros", "thiserror", - "time 0.3.22", + "time 0.3.23", ] [[package]] @@ -347,7 +347,7 @@ dependencies = [ "num-traits", "rusticata-macros", "thiserror", - "time 0.3.22", + "time 0.3.23", ] [[package]] @@ -515,9 +515,14 @@ dependencies = [ name = "astar-primitives" version = "0.1.0" dependencies = [ + "ethereum", + "ethereum-types", + "fp-evm", "frame-support", "log", "pallet-xc-asset-config", + "parity-scale-codec", + "scale-info", "sp-core", "sp-runtime", "sp-std", @@ -622,9 +627,9 @@ dependencies = [ [[package]] name = "async-channel" -version = "1.8.0" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf46fee83e5ccffc220104713af3292ff9bc7c64c7de289f66dae8e38d826833" +checksum = "81953c529336010edd6d8e358f886d9581267795c61b19475b71314bffa46d35" dependencies = [ "concurrent-queue", "event-listener", @@ -645,7 +650,7 @@ dependencies = [ "log", "parking", "polling", - "rustix 0.37.22", + "rustix 0.37.23", "slab", "socket2 0.4.9", "waker-fn", @@ -662,13 +667,13 @@ dependencies = [ [[package]] name = "async-trait" -version = "0.1.70" +version = "0.1.71" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79fa67157abdfd688a259b6648808757db9347af834624f27ec646da976aee5d" +checksum = "a564d521dd56509c4c47480d00b80ee55f7e385ae48db5744c67ad50c92d2ebf" dependencies = [ "proc-macro2", "quote", - "syn 2.0.23", + "syn 2.0.25", ] [[package]] @@ -858,7 +863,7 @@ checksum = "3c2f0dc9a68c6317d884f97cc36cf5a3d20ba14ce404227df55e1af708ab04bc" dependencies = [ "arrayref", "arrayvec 0.7.4", - "constant_time_eq", + "constant_time_eq 0.2.6", ] [[package]] @@ -869,20 +874,20 @@ checksum = "6637f448b9e61dfadbdcbae9a885fadee1f3eaffb1f8d3c1965d3ade8bdfd44f" dependencies = [ "arrayref", "arrayvec 0.7.4", - "constant_time_eq", + "constant_time_eq 0.2.6", ] [[package]] name = "blake3" -version = "1.4.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "729b71f35bd3fa1a4c86b85d32c8b9069ea7fe14f7a53cfabb65f62d4265b888" +checksum = "199c42ab6972d92c9f8995f086273d25c42fc0f7b2a1fcefba465c1352d25ba5" dependencies = [ "arrayref", "arrayvec 0.7.4", "cc", "cfg-if", - "constant_time_eq", + "constant_time_eq 0.3.0", "digest 0.10.7", ] @@ -976,14 +981,14 @@ checksum = "ba3569f383e8f1598449f1a423e72e99569137b47740b1da11ef19af3d5c3223" dependencies = [ "lazy_static", "memchr", - "regex-automata", + "regex-automata 0.1.10", ] [[package]] name = "bstr" -version = "1.5.0" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a246e68bb43f6cd9db24bea052a53e40405417c5fb372e3d1a8a7f770a564ef5" +checksum = "6798148dccfbff0fae41c7574d2fa8f1ef3492fba0face179de5d8d447d67b05" dependencies = [ "memchr", "serde", @@ -1230,9 +1235,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.3.10" +version = "4.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "384e169cc618c613d5e3ca6404dda77a8685a63e08660dcc64abaf7da7cb0c7a" +checksum = "1640e5cc7fb47dbb8338fd471b105e7ed6c3cb2aeb00c2e067127ffd3764a05d" dependencies = [ "clap_builder", "clap_derive", @@ -1241,9 +1246,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.3.10" +version = "4.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef137bbe35aab78bdb468ccfba75a5f4d8321ae011d34063770780545176af2d" +checksum = "98c59138d527eeaf9b53f35a77fcc1fad9d883116070c63d5de1c7dc7b00c72b" dependencies = [ "anstream", "anstyle", @@ -1260,7 +1265,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.23", + "syn 2.0.25", ] [[package]] @@ -1341,6 +1346,12 @@ version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "21a53c0a4d288377e7415b53dcfc3c04da5cdc2cc95c8d5ac178b58f0b861ad6" +[[package]] +name = "constant_time_eq" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7144d30dcf0fafbce74250a3963025d8d52177934239851c917d29f1df280c2" + [[package]] name = "convert_case" version = "0.4.0" @@ -1393,9 +1404,9 @@ dependencies = [ [[package]] name = "cpufeatures" -version = "0.2.8" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03e69e28e9f7f77debdedbaafa2866e1de9ba56df55a8bd7cfc724c25a09987c" +checksum = "a17b76ff3a4162b0b27f354a0c87015ddad39d35f9c0c36607a3bdd175dde1f1" dependencies = [ "libc", ] @@ -2180,9 +2191,9 @@ dependencies = [ [[package]] name = "cxx" -version = "1.0.97" +version = "1.0.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e88abab2f5abbe4c56e8f1fb431b784d710b709888f35755a160e62e33fe38e8" +checksum = "e928d50d5858b744d1ea920b790641129c347a770d1530c3a85b77705a5ee031" dependencies = [ "cc", "cxxbridge-flags", @@ -2192,9 +2203,9 @@ dependencies = [ [[package]] name = "cxx-build" -version = "1.0.97" +version = "1.0.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c0c11acd0e63bae27dcd2afced407063312771212b7a823b4fd72d633be30fb" +checksum = "8332ba63f8a8040ca479de693150129067304a3496674477fff6d0c372cc34ae" dependencies = [ "cc", "codespan-reporting", @@ -2202,24 +2213,24 @@ dependencies = [ "proc-macro2", "quote", "scratch", - "syn 2.0.23", + "syn 2.0.25", ] [[package]] name = "cxxbridge-flags" -version = "1.0.97" +version = "1.0.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d3816ed957c008ccd4728485511e3d9aaf7db419aa321e3d2c5a2f3411e36c8" +checksum = "5966a5a87b6e9bb342f5fab7170a93c77096efe199872afffc4b477cfeb86957" [[package]] name = "cxxbridge-macro" -version = "1.0.97" +version = "1.0.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a26acccf6f445af85ea056362561a24ef56cdc15fcc685f03aec50b9c702cb6d" +checksum = "81b2dab6991c7ab1572fea8cb049db819b1aeea1e2dac74c0869f244d9f21a7c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.23", + "syn 2.0.25", ] [[package]] @@ -2483,7 +2494,7 @@ checksum = "487585f4d0c6655fe74905e2504d8ad6908e4db67f744eb140876906c2f3175d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.23", + "syn 2.0.25", ] [[package]] @@ -2643,7 +2654,7 @@ checksum = "5e9a1f9f7d83e59740248a6e14ecf93929ade55027844dfcea78beafccc15745" dependencies = [ "proc-macro2", "quote", - "syn 2.0.23", + "syn 2.0.25", ] [[package]] @@ -2654,7 +2665,7 @@ checksum = "c9838a970f5de399d3070ae1739e131986b2f5dcc223c7423ca0927e3a878522" dependencies = [ "proc-macro2", "quote", - "syn 2.0.23", + "syn 2.0.25", ] [[package]] @@ -2945,7 +2956,7 @@ dependencies = [ [[package]] name = "fc-consensus" version = "2.0.0-dev" -source = "git+https://github.com/AstarNetwork/frontier?branch=polkadot-v0.9.40#ca5c1a0210264b595e950100c39811fdfa6819a5" +source = "git+https://github.com/AstarNetwork/frontier?branch=polkadot-v0.9.40#e2f5879d243f5d9b8272a1ae640669065c8546f2" dependencies = [ "async-trait", "fc-db", @@ -2962,7 +2973,7 @@ dependencies = [ [[package]] name = "fc-db" version = "2.0.0-dev" -source = "git+https://github.com/AstarNetwork/frontier?branch=polkadot-v0.9.40#ca5c1a0210264b595e950100c39811fdfa6819a5" +source = "git+https://github.com/AstarNetwork/frontier?branch=polkadot-v0.9.40#e2f5879d243f5d9b8272a1ae640669065c8546f2" dependencies = [ "fp-storage", "kvdb-rocksdb", @@ -2981,7 +2992,7 @@ dependencies = [ [[package]] name = "fc-mapping-sync" version = "2.0.0-dev" -source = "git+https://github.com/AstarNetwork/frontier?branch=polkadot-v0.9.40#ca5c1a0210264b595e950100c39811fdfa6819a5" +source = "git+https://github.com/AstarNetwork/frontier?branch=polkadot-v0.9.40#e2f5879d243f5d9b8272a1ae640669065c8546f2" dependencies = [ "fc-db", "fc-storage", @@ -3002,7 +3013,7 @@ dependencies = [ [[package]] name = "fc-rpc" version = "2.0.0-dev" -source = "git+https://github.com/AstarNetwork/frontier?branch=polkadot-v0.9.40#ca5c1a0210264b595e950100c39811fdfa6819a5" +source = "git+https://github.com/AstarNetwork/frontier?branch=polkadot-v0.9.40#e2f5879d243f5d9b8272a1ae640669065c8546f2" dependencies = [ "ethereum", "ethereum-types", @@ -3051,7 +3062,7 @@ dependencies = [ [[package]] name = "fc-rpc-core" version = "1.1.0-dev" -source = "git+https://github.com/AstarNetwork/frontier?branch=polkadot-v0.9.40#ca5c1a0210264b595e950100c39811fdfa6819a5" +source = "git+https://github.com/AstarNetwork/frontier?branch=polkadot-v0.9.40#e2f5879d243f5d9b8272a1ae640669065c8546f2" dependencies = [ "ethereum", "ethereum-types", @@ -3064,7 +3075,7 @@ dependencies = [ [[package]] name = "fc-storage" version = "1.0.0-dev" -source = "git+https://github.com/AstarNetwork/frontier?branch=polkadot-v0.9.40#ca5c1a0210264b595e950100c39811fdfa6819a5" +source = "git+https://github.com/AstarNetwork/frontier?branch=polkadot-v0.9.40#e2f5879d243f5d9b8272a1ae640669065c8546f2" dependencies = [ "ethereum", "ethereum-types", @@ -3206,7 +3217,7 @@ dependencies = [ [[package]] name = "fp-account" version = "1.0.0-dev" -source = "git+https://github.com/AstarNetwork/frontier?branch=polkadot-v0.9.40#ca5c1a0210264b595e950100c39811fdfa6819a5" +source = "git+https://github.com/AstarNetwork/frontier?branch=polkadot-v0.9.40#e2f5879d243f5d9b8272a1ae640669065c8546f2" dependencies = [ "hex", "impl-serde", @@ -3224,7 +3235,7 @@ dependencies = [ [[package]] name = "fp-consensus" version = "2.0.0-dev" -source = "git+https://github.com/AstarNetwork/frontier?branch=polkadot-v0.9.40#ca5c1a0210264b595e950100c39811fdfa6819a5" +source = "git+https://github.com/AstarNetwork/frontier?branch=polkadot-v0.9.40#e2f5879d243f5d9b8272a1ae640669065c8546f2" dependencies = [ "ethereum", "parity-scale-codec", @@ -3236,7 +3247,7 @@ dependencies = [ [[package]] name = "fp-ethereum" version = "1.0.0-dev" -source = "git+https://github.com/AstarNetwork/frontier?branch=polkadot-v0.9.40#ca5c1a0210264b595e950100c39811fdfa6819a5" +source = "git+https://github.com/AstarNetwork/frontier?branch=polkadot-v0.9.40#e2f5879d243f5d9b8272a1ae640669065c8546f2" dependencies = [ "ethereum", "ethereum-types", @@ -3250,7 +3261,7 @@ dependencies = [ [[package]] name = "fp-evm" version = "3.0.0-dev" -source = "git+https://github.com/AstarNetwork/frontier?branch=polkadot-v0.9.40#ca5c1a0210264b595e950100c39811fdfa6819a5" +source = "git+https://github.com/AstarNetwork/frontier?branch=polkadot-v0.9.40#e2f5879d243f5d9b8272a1ae640669065c8546f2" dependencies = [ "evm", "frame-support", @@ -3264,7 +3275,7 @@ dependencies = [ [[package]] name = "fp-rpc" version = "3.0.0-dev" -source = "git+https://github.com/AstarNetwork/frontier?branch=polkadot-v0.9.40#ca5c1a0210264b595e950100c39811fdfa6819a5" +source = "git+https://github.com/AstarNetwork/frontier?branch=polkadot-v0.9.40#e2f5879d243f5d9b8272a1ae640669065c8546f2" dependencies = [ "ethereum", "ethereum-types", @@ -3281,7 +3292,7 @@ dependencies = [ [[package]] name = "fp-self-contained" version = "1.0.0-dev" -source = "git+https://github.com/AstarNetwork/frontier?branch=polkadot-v0.9.40#ca5c1a0210264b595e950100c39811fdfa6819a5" +source = "git+https://github.com/AstarNetwork/frontier?branch=polkadot-v0.9.40#e2f5879d243f5d9b8272a1ae640669065c8546f2" dependencies = [ "frame-support", "parity-scale-codec", @@ -3293,7 +3304,7 @@ dependencies = [ [[package]] name = "fp-storage" version = "2.0.0" -source = "git+https://github.com/AstarNetwork/frontier?branch=polkadot-v0.9.40#ca5c1a0210264b595e950100c39811fdfa6819a5" +source = "git+https://github.com/AstarNetwork/frontier?branch=polkadot-v0.9.40#e2f5879d243f5d9b8272a1ae640669065c8546f2" dependencies = [ "parity-scale-codec", "serde", @@ -3596,7 +3607,7 @@ version = "0.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2eeb4ed9e12f43b7fa0baae3f9cdda28352770132ef2e09a23760c29cae8bd47" dependencies = [ - "rustix 0.38.2", + "rustix 0.38.3", "windows-sys 0.48.0", ] @@ -3684,7 +3695,7 @@ checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" dependencies = [ "proc-macro2", "quote", - "syn 2.0.23", + "syn 2.0.25", ] [[package]] @@ -3845,7 +3856,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "029d74589adefde59de1a0c4f4732695c32805624aec7b68d91503d4dba79afc" dependencies = [ "aho-corasick 0.7.20", - "bstr 1.5.0", + "bstr 1.6.0", "fnv", "log", "regex", @@ -4378,12 +4389,12 @@ checksum = "28b29a3cd74f0f4598934efe3aeba42bae0eb4680554128851ebbecb02af14e6" [[package]] name = "is-terminal" -version = "0.4.8" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24fddda5af7e54bf7da53067d6e802dbcc381d0a8eef629df528e3ebf68755cb" +checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b" dependencies = [ "hermit-abi 0.3.2", - "rustix 0.38.2", + "rustix 0.38.3", "windows-sys 0.48.0", ] @@ -5491,7 +5502,7 @@ version = "0.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f099785f7595cc4b4553a174ce30dd7589ef93391ff414dbb67f62392b9e0ce1" dependencies = [ - "regex-automata", + "regex-automata 0.1.10", ] [[package]] @@ -5531,7 +5542,7 @@ version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ffc89ccdc6e10d6907450f753537ebc5c5d3460d2e4e62ea74bd571db62c0f9e" dependencies = [ - "rustix 0.37.22", + "rustix 0.37.23", ] [[package]] @@ -6006,9 +6017,9 @@ dependencies = [ [[package]] name = "nalgebra" -version = "0.32.2" +version = "0.32.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d68d47bba83f9e2006d117a9a33af1524e655516b8919caac694427a6fb1e511" +checksum = "307ed9b18cc2423f29e83f84fd23a8e73628727990181f18641a8b5dc2ab1caa" dependencies = [ "approx", "matrixmultiply", @@ -6022,9 +6033,9 @@ dependencies = [ [[package]] name = "nalgebra-macros" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d232c68884c0c99810a5a4d333ef7e47689cfd0edc85efc9e54e1e6bf5212766" +checksum = "91761aed67d03ad966ef783ae962ef9bbaca728d2dd7ceb7939ec110fffad998" dependencies = [ "proc-macro2", "quote", @@ -6591,7 +6602,7 @@ dependencies = [ [[package]] name = "pallet-base-fee" version = "1.0.0" -source = "git+https://github.com/AstarNetwork/frontier?branch=polkadot-v0.9.40#ca5c1a0210264b595e950100c39811fdfa6819a5" +source = "git+https://github.com/AstarNetwork/frontier?branch=polkadot-v0.9.40#e2f5879d243f5d9b8272a1ae640669065c8546f2" dependencies = [ "fp-evm", "frame-support", @@ -7002,7 +7013,7 @@ dependencies = [ [[package]] name = "pallet-ethereum" version = "4.0.0-dev" -source = "git+https://github.com/AstarNetwork/frontier?branch=polkadot-v0.9.40#ca5c1a0210264b595e950100c39811fdfa6819a5" +source = "git+https://github.com/AstarNetwork/frontier?branch=polkadot-v0.9.40#e2f5879d243f5d9b8272a1ae640669065c8546f2" dependencies = [ "environmental", "ethereum", @@ -7023,10 +7034,34 @@ dependencies = [ "sp-std", ] +[[package]] +name = "pallet-ethereum-checked" +version = "0.1.0" +dependencies = [ + "astar-primitives", + "ethereum", + "ethereum-types", + "fp-ethereum", + "fp-evm", + "frame-benchmarking", + "frame-support", + "frame-system", + "hex", + "pallet-balances", + "pallet-ethereum", + "pallet-evm", + "pallet-timestamp", + "parity-scale-codec", + "scale-info", + "sp-io", + "sp-runtime", + "sp-std", +] + [[package]] name = "pallet-evm" version = "6.0.0-dev" -source = "git+https://github.com/AstarNetwork/frontier?branch=polkadot-v0.9.40#ca5c1a0210264b595e950100c39811fdfa6819a5" +source = "git+https://github.com/AstarNetwork/frontier?branch=polkadot-v0.9.40#e2f5879d243f5d9b8272a1ae640669065c8546f2" dependencies = [ "environmental", "evm", @@ -7050,7 +7085,7 @@ dependencies = [ [[package]] name = "pallet-evm-chain-id" version = "1.0.0-dev" -source = "git+https://github.com/AstarNetwork/frontier?branch=polkadot-v0.9.40#ca5c1a0210264b595e950100c39811fdfa6819a5" +source = "git+https://github.com/AstarNetwork/frontier?branch=polkadot-v0.9.40#e2f5879d243f5d9b8272a1ae640669065c8546f2" dependencies = [ "frame-support", "frame-system", @@ -7087,7 +7122,7 @@ dependencies = [ [[package]] name = "pallet-evm-precompile-blake2" version = "2.0.0-dev" -source = "git+https://github.com/AstarNetwork/frontier?branch=polkadot-v0.9.40#ca5c1a0210264b595e950100c39811fdfa6819a5" +source = "git+https://github.com/AstarNetwork/frontier?branch=polkadot-v0.9.40#e2f5879d243f5d9b8272a1ae640669065c8546f2" dependencies = [ "fp-evm", ] @@ -7095,7 +7130,7 @@ dependencies = [ [[package]] name = "pallet-evm-precompile-bn128" version = "2.0.0-dev" -source = "git+https://github.com/AstarNetwork/frontier?branch=polkadot-v0.9.40#ca5c1a0210264b595e950100c39811fdfa6819a5" +source = "git+https://github.com/AstarNetwork/frontier?branch=polkadot-v0.9.40#e2f5879d243f5d9b8272a1ae640669065c8546f2" dependencies = [ "fp-evm", "sp-core", @@ -7130,7 +7165,7 @@ dependencies = [ [[package]] name = "pallet-evm-precompile-dispatch" version = "2.0.0-dev" -source = "git+https://github.com/AstarNetwork/frontier?branch=polkadot-v0.9.40#ca5c1a0210264b595e950100c39811fdfa6819a5" +source = "git+https://github.com/AstarNetwork/frontier?branch=polkadot-v0.9.40#e2f5879d243f5d9b8272a1ae640669065c8546f2" dependencies = [ "fp-evm", "frame-support", @@ -7140,7 +7175,7 @@ dependencies = [ [[package]] name = "pallet-evm-precompile-ed25519" version = "2.0.0-dev" -source = "git+https://github.com/AstarNetwork/frontier?branch=polkadot-v0.9.40#ca5c1a0210264b595e950100c39811fdfa6819a5" +source = "git+https://github.com/AstarNetwork/frontier?branch=polkadot-v0.9.40#e2f5879d243f5d9b8272a1ae640669065c8546f2" dependencies = [ "ed25519-dalek", "fp-evm", @@ -7149,7 +7184,7 @@ dependencies = [ [[package]] name = "pallet-evm-precompile-modexp" version = "2.0.0-dev" -source = "git+https://github.com/AstarNetwork/frontier?branch=polkadot-v0.9.40#ca5c1a0210264b595e950100c39811fdfa6819a5" +source = "git+https://github.com/AstarNetwork/frontier?branch=polkadot-v0.9.40#e2f5879d243f5d9b8272a1ae640669065c8546f2" dependencies = [ "fp-evm", "num", @@ -7158,7 +7193,7 @@ dependencies = [ [[package]] name = "pallet-evm-precompile-sha3fips" version = "2.0.0-dev" -source = "git+https://github.com/AstarNetwork/frontier?branch=polkadot-v0.9.40#ca5c1a0210264b595e950100c39811fdfa6819a5" +source = "git+https://github.com/AstarNetwork/frontier?branch=polkadot-v0.9.40#e2f5879d243f5d9b8272a1ae640669065c8546f2" dependencies = [ "fp-evm", "tiny-keccak", @@ -7167,7 +7202,7 @@ dependencies = [ [[package]] name = "pallet-evm-precompile-simple" version = "2.0.0-dev" -source = "git+https://github.com/AstarNetwork/frontier?branch=polkadot-v0.9.40#ca5c1a0210264b595e950100c39811fdfa6819a5" +source = "git+https://github.com/AstarNetwork/frontier?branch=polkadot-v0.9.40#e2f5879d243f5d9b8272a1ae640669065c8546f2" dependencies = [ "fp-evm", "ripemd", @@ -8231,7 +8266,7 @@ dependencies = [ "pest_meta", "proc-macro2", "quote", - "syn 2.0.23", + "syn 2.0.25", ] [[package]] @@ -8272,7 +8307,7 @@ checksum = "ec2e072ecce94ec471b13398d5402c188e76ac03cf74dd1a975161b23a3f6d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.23", + "syn 2.0.25", ] [[package]] @@ -9663,9 +9698,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.63" +version = "1.0.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b368fba921b0dce7e60f5e04ec15e565b3303972b42bcfde1d0713b881959eb" +checksum = "78803b62cbf1f46fde80d7c0e803111524b9877184cfe7c3033659490ac7a7da" dependencies = [ "unicode-ident", ] @@ -9958,7 +9993,7 @@ checksum = "6413f3de1edee53342e6138e75b56d32e7bc6e332b3bd62d497b1929d4cfbcdd" dependencies = [ "pem", "ring", - "time 0.3.22", + "time 0.3.23", "x509-parser 0.13.2", "yasna", ] @@ -9971,7 +10006,7 @@ checksum = "ffbe84efe2f38dea12e9bfc1f65377fdf03e53a18cb3b995faedf7934c7e785b" dependencies = [ "pem", "ring", - "time 0.3.22", + "time 0.3.23", "yasna", ] @@ -10034,7 +10069,7 @@ checksum = "68bf53dad9b6086826722cdc99140793afd9f62faa14a1ad07eb4f955e7a7216" dependencies = [ "proc-macro2", "quote", - "syn 2.0.23", + "syn 2.0.25", ] [[package]] @@ -10051,13 +10086,14 @@ dependencies = [ [[package]] name = "regex" -version = "1.8.4" +version = "1.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0ab3ca65655bb1e41f2a8c8cd662eb4fb035e67c3f78da1d61dffe89d07300f" +checksum = "b2eae68fc220f7cf2532e4494aded17545fce192d59cd996e0fe7887f4ceb575" dependencies = [ "aho-corasick 1.0.2", "memchr", - "regex-syntax 0.7.2", + "regex-automata 0.3.2", + "regex-syntax 0.7.3", ] [[package]] @@ -10069,6 +10105,17 @@ dependencies = [ "regex-syntax 0.6.29", ] +[[package]] +name = "regex-automata" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83d3daa6976cffb758ec878f108ba0e062a45b2d6ca3a2cca965338855476caf" +dependencies = [ + "aho-corasick 1.0.2", + "memchr", + "regex-syntax 0.7.3", +] + [[package]] name = "regex-syntax" version = "0.6.29" @@ -10077,9 +10124,9 @@ checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" [[package]] name = "regex-syntax" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "436b050e76ed2903236f032a59761c1eb99e1b0aead2c257922771dab1fc8c78" +checksum = "2ab07dc67230e4a4718e70fd5c20055a4334b121f1f9db8fe63ef39ce9b8c846" [[package]] name = "region" @@ -10378,9 +10425,9 @@ dependencies = [ [[package]] name = "rustix" -version = "0.36.14" +version = "0.36.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14e4d67015953998ad0eb82887a0eb0129e18a7e2f3b7b0f6c422fddcd503d62" +checksum = "c37f1bd5ef1b5422177b7646cba67430579cfe2ace80f284fee876bca52ad941" dependencies = [ "bitflags 1.3.2", "errno", @@ -10392,9 +10439,9 @@ dependencies = [ [[package]] name = "rustix" -version = "0.37.22" +version = "0.37.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8818fa822adcc98b18fedbb3632a6a33213c070556b5aa7c4c8cc21cff565c4c" +checksum = "4d69718bf81c6127a49dc64e44a742e8bb9213c0ff8869a22c308f84c1d4ab06" dependencies = [ "bitflags 1.3.2", "errno", @@ -10406,9 +10453,9 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.2" +version = "0.38.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aabcb0461ebd01d6b79945797c27f8529082226cb630a9865a71870ff63532a4" +checksum = "ac5ffa1efe7548069688cd7028f32591853cd7b5b756d41bcffd2353e4fc75b4" dependencies = [ "bitflags 2.3.3", "errno", @@ -11037,7 +11084,7 @@ dependencies = [ "libc", "log", "once_cell", - "rustix 0.36.14", + "rustix 0.36.15", "sc-allocator", "sc-executor-common", "sp-runtime-interface", @@ -11726,9 +11773,9 @@ checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" [[package]] name = "scratch" -version = "1.0.5" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1792db035ce95be60c3f8853017b3999209281c24e2ba5bc8e59bf97a0c590c1" +checksum = "764cad9e7e1ca5fe15b552859ff5d96a314e6ed2934f2260168cd5dfa5891409" [[package]] name = "sct" @@ -11861,22 +11908,22 @@ checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" [[package]] name = "serde" -version = "1.0.166" +version = "1.0.171" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d01b7404f9d441d3ad40e6a636a7782c377d2abdbe4fa2440e2edcc2f4f10db8" +checksum = "30e27d1e4fd7659406c492fd6cfaf2066ba8773de45ca75e855590f856dc34a9" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.166" +version = "1.0.171" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dd83d6dde2b6b2d466e14d9d1acce8816dedee94f735eac6395808b3483c6d6" +checksum = "389894603bd18c46fa56231694f8d827779c0951a667087194cf9de94ed24682" dependencies = [ "proc-macro2", "quote", - "syn 2.0.23", + "syn 2.0.25", ] [[package]] @@ -12289,9 +12336,9 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.10.0" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" +checksum = "62bb4feee49fdd9f707ef802e22365a35de4b7b299de4763d44bfea899442ff9" [[package]] name = "snap" @@ -13349,9 +13396,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.23" +version = "2.0.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59fb7d6d8281a51045d62b8eb3a7d1ce347b76f312af50cd3dc0af39c87c1737" +checksum = "15e3fc8c0c74267e2df136e5e5fb656a464158aa57624053375eb9c8c6e25ae2" dependencies = [ "proc-macro2", "quote", @@ -13413,7 +13460,7 @@ dependencies = [ "cfg-if", "fastrand", "redox_syscall 0.3.5", - "rustix 0.37.22", + "rustix 0.37.23", "windows-sys 0.48.0", ] @@ -13434,22 +13481,22 @@ checksum = "3369f5ac52d5eb6ab48c6b4ffdc8efbcad6b89c765749064ba298f2c68a16a76" [[package]] name = "thiserror" -version = "1.0.41" +version = "1.0.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c16a64ba9387ef3fdae4f9c1a7f07a0997fce91985c0336f1ddc1822b3b37802" +checksum = "a35fc5b8971143ca348fa6df4f024d4d55264f3468c71ad1c2f365b0a4d58c42" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.41" +version = "1.0.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d14928354b01c4d6a4f0e549069adef399a284e7995c7ccca94e8a07a5346c59" +checksum = "463fe12d7993d3b327787537ce8dd4dfa058de32fc2b195ef3cde03dc4771e8f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.23", + "syn 2.0.25", ] [[package]] @@ -13524,9 +13571,9 @@ dependencies = [ [[package]] name = "time" -version = "0.3.22" +version = "0.3.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea9e1b3cf1243ae005d9e74085d4d542f3125458f3a81af210d901dcd7411efd" +checksum = "59e399c068f43a5d116fedaf73b203fa4f9c519f17e2b34f63221d3792f81446" dependencies = [ "itoa", "serde", @@ -13542,9 +13589,9 @@ checksum = "7300fbefb4dadc1af235a9cef3737cea692a9d97e1b9cbcd4ebdae6f8868e6fb" [[package]] name = "time-macros" -version = "0.2.9" +version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "372950940a5f07bf38dbe211d7283c9e6d7327df53794992d293e534c733d09b" +checksum = "96ba15a897f3c86766b757e5ac7221554c6750054d74d5b28844fce5fb36a6c4" dependencies = [ "time-core", ] @@ -13630,7 +13677,7 @@ checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.23", + "syn 2.0.25", ] [[package]] @@ -13688,9 +13735,9 @@ checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b" [[package]] name = "toml_edit" -version = "0.19.11" +version = "0.19.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "266f016b7f039eec8a1a80dfe6156b633d208b9fccca5e4db1d6775b0c4e34a7" +checksum = "c500344a19072298cd05a7224b3c0c629348b78692bf48466c5238656e315a78" dependencies = [ "indexmap 2.0.0", "toml_datetime", @@ -13759,7 +13806,7 @@ checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab" dependencies = [ "proc-macro2", "quote", - "syn 2.0.23", + "syn 2.0.25", ] [[package]] @@ -14015,9 +14062,9 @@ checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" [[package]] name = "ucd-trie" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e79c4d996edb816c91e4308506774452e55e95c3c9de07b6729e17e15a5ef81" +checksum = "ed646292ffc8188ef8ea4d1e0e0150fb15a5c2e12ad9b8fc191ae7a8a7f3c4b9" [[package]] name = "uint" @@ -14231,7 +14278,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.23", + "syn 2.0.25", "wasm-bindgen-shared", ] @@ -14265,7 +14312,7 @@ checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.23", + "syn 2.0.25", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -14481,7 +14528,7 @@ dependencies = [ "directories-next", "file-per-thread-logger", "log", - "rustix 0.36.14", + "rustix 0.36.15", "serde", "sha2 0.10.7", "toml", @@ -14561,7 +14608,7 @@ checksum = "eed41cbcbf74ce3ff6f1d07d1b707888166dc408d1a880f651268f4f7c9194b2" dependencies = [ "object 0.29.0", "once_cell", - "rustix 0.36.14", + "rustix 0.36.15", ] [[package]] @@ -14592,7 +14639,7 @@ dependencies = [ "memoffset 0.6.5", "paste", "rand 0.8.5", - "rustix 0.36.14", + "rustix 0.36.15", "wasmtime-asm-macros", "wasmtime-environ", "wasmtime-jit-debug", @@ -14676,7 +14723,7 @@ dependencies = [ "sha2 0.10.7", "stun", "thiserror", - "time 0.3.22", + "time 0.3.23", "tokio", "turn", "url", @@ -15224,9 +15271,9 @@ checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" [[package]] name = "winnow" -version = "0.4.7" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca0ace3845f0d96209f0375e6d367e3eb87eb65d27d445bdc9f1843a26f39448" +checksum = "81a2094c43cc94775293eaa0e499fbc30048a6d824ac82c0351a8c0bf9112529" dependencies = [ "memchr", ] @@ -15288,7 +15335,7 @@ dependencies = [ "ring", "rusticata-macros", "thiserror", - "time 0.3.22", + "time 0.3.23", ] [[package]] @@ -15306,7 +15353,7 @@ dependencies = [ "oid-registry 0.6.1", "rusticata-macros", "thiserror", - "time 0.3.22", + "time 0.3.23", ] [[package]] @@ -15483,7 +15530,7 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e17bb3549cc1321ae1296b9cdc2698e2b6cb1992adfa19a8c72e5b7a738f44cd" dependencies = [ - "time 0.3.22", + "time 0.3.23", ] [[package]] @@ -15503,7 +15550,7 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.23", + "syn 2.0.25", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 5f8165d97d..a7c43c8821 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -200,6 +200,7 @@ pallet-evm-precompile-simple = { git = "https://github.com/AstarNetwork/frontier pallet-base-fee = { git = "https://github.com/AstarNetwork/frontier", branch = "polkadot-v0.9.40", default-features = false } pallet-evm-chain-id = { git = "https://github.com/AstarNetwork/frontier", branch = "polkadot-v0.9.40", default-features = false } fp-evm = { git = "https://github.com/AstarNetwork/frontier", branch = "polkadot-v0.9.40", default-features = false } +fp-ethereum = { git = "https://github.com/AstarNetwork/frontier", branch = "polkadot-v0.9.40", default-features = false } # (native) fc-consensus = { git = "https://github.com/AstarNetwork/frontier", branch = "polkadot-v0.9.40" } diff --git a/pallets/ethereum-checked/Cargo.toml b/pallets/ethereum-checked/Cargo.toml new file mode 100644 index 0000000000..6bb34e881e --- /dev/null +++ b/pallets/ethereum-checked/Cargo.toml @@ -0,0 +1,63 @@ +[package] +name = "pallet-ethereum-checked" +version = "0.1.0" +description = "Pallet for Ethereum like checked transactions" +authors.workspace = true +edition.workspace = true +homepage.workspace = true +repository.workspace = true + +[dependencies] +parity-scale-codec = { workspace = true } +scale-info = { workspace = true } + +ethereum-types = { workspace = true } +fp-ethereum = { workspace = true } +fp-evm = { workspace = true } +pallet-evm = { workspace = true } + +frame-benchmarking = { workspace = true, optional = true } +frame-support = { workspace = true } +frame-system = { workspace = true } +sp-runtime = { workspace = true } +sp-std = { workspace = true } + +astar-primitives = { workspace = true } + +[dev-dependencies] +ethereum = { workspace = true } +hex = { workspace = true } +pallet-balances = { workspace = true } +pallet-ethereum = { workspace = true } +pallet-evm = { workspace = true } +pallet-timestamp = { workspace = true } +sp-io = { workspace = true } + +[features] +default = ["std"] +std = [ + "parity-scale-codec/std", + "scale-info/std", + "ethereum/std", + "ethereum-types/std", + "fp-ethereum/std", + "fp-evm/std", + "pallet-evm/std", + "sp-std/std", + "sp-runtime/std", + "sp-io/std", + "frame-support/std", + "frame-system/std", + "pallet-balances/std", + "pallet-timestamp/std", + "pallet-evm/std", + "pallet-ethereum/std", + "astar-primitives/std", +] +runtime-benchmarks = [ + "frame-benchmarking", + "frame-support/runtime-benchmarks", + "frame-system/runtime-benchmarks", + "sp-runtime/runtime-benchmarks", +] +try-runtime = ["frame-support/try-runtime"] diff --git a/pallets/ethereum-checked/src/lib.rs b/pallets/ethereum-checked/src/lib.rs new file mode 100644 index 0000000000..4be7799d86 --- /dev/null +++ b/pallets/ethereum-checked/src/lib.rs @@ -0,0 +1,234 @@ +// This file is part of Astar. + +// Copyright (C) 2019-2023 Stake Technologies Pte.Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later + +// Astar is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Astar is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Astar. If not, see . + +//! # Ethereum Checked Pallet +//! +//! ## Overview +//! +//! A `pallet-ethererum` like pallet that execute transactions from checked source, +//! like XCM remote call, cross-VM call, etc. Only `Call` transactions are supported +//! (no `Create`). +//! +//! The checked source guarantees that transactions are valid with prior checks, so these +//! transactions are not required to include valid signatures. Instead, `pallet-ethereum-checked` +//! will add the same dummy signature to them. To avoid transaction hash collisions, a global +//! nonce shared with all users are used. +//! +//! ## Interface +//! +//! ### Dispatch-able calls +//! +//! - `transact`: transact an Ethereum transaction. Similar to `pallet_ethereum::Transact`, +//! but is only for XCM remote call. +//! +//! ### Implementation +//! +//! - Implements `CheckedEthereumTransact` trait. +//! + +#![cfg_attr(not(feature = "std"), no_std)] + +use parity_scale_codec::{Decode, Encode}; +use scale_info::TypeInfo; + +use ethereum_types::{H160, U256}; +use fp_ethereum::{TransactionData, ValidatedTransaction}; +use fp_evm::{ + CallInfo, CallOrCreateInfo, CheckEvmTransaction, CheckEvmTransactionConfig, + InvalidEvmTransactionError, +}; +use pallet_evm::GasWeightMapping; + +use frame_support::{ + dispatch::{DispatchErrorWithPostInfo, PostDispatchInfo}, + pallet_prelude::*, +}; +use frame_system::pallet_prelude::*; +#[cfg(feature = "runtime-benchmarks")] +use sp_runtime::traits::TrailingZeroInput; +use sp_runtime::traits::UniqueSaturatedInto; +use sp_std::{marker::PhantomData, result::Result}; + +use astar_primitives::ethereum_checked::{ + AccountMapping, CheckedEthereumTransact, CheckedEthereumTx, +}; + +pub use pallet::*; + +mod mock; +mod tests; + +/// Origin for dispatch-able calls. +#[derive(PartialEq, Eq, Clone, Encode, Decode, RuntimeDebug, TypeInfo, MaxEncodedLen)] +pub enum RawOrigin { + XcmEthereumTx(AccountId), +} + +/// Ensure the origin is with XCM calls. +pub struct EnsureXcmEthereumTx(PhantomData); +impl, O>> + From>, AccountId: Decode> + EnsureOrigin for EnsureXcmEthereumTx +{ + type Success = AccountId; + + fn try_origin(o: O) -> Result { + o.into().map(|o| match o { + RawOrigin::XcmEthereumTx(account_id) => account_id, + }) + } + + #[cfg(feature = "runtime-benchmarks")] + fn try_successful_origin() -> Result { + let zero_account_id = + AccountId::decode(&mut TrailingZeroInput::zeroes()).map_err(|_| ())?; + Ok(O::from(RawOrigin::XcmEthereumTx(zero_account_id))) + } +} + +/// Transaction kind. +#[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo)] +pub enum CheckedEthereumTxKind { + /// The tx is from XCM remote call. + Xcm, + /// The tx is from cross-VM call. + Xvm, +} + +#[frame_support::pallet] +pub mod pallet { + use super::*; + + #[pallet::pallet] + pub struct Pallet(PhantomData); + + #[pallet::config] + pub trait Config: frame_system::Config + pallet_evm::Config { + /// Reserved Xcmp weight for block gas limit calculation. + type ReservedXcmpWeight: Get; + + /// Xcm transaction weight limit, for block gas limit calculation. + type XvmTxWeightLimit: Get; + + /// Invalid tx error. + type InvalidEvmTransactionError: From; + + /// Validated tx execution. + type ValidatedTransaction: ValidatedTransaction; + + /// Account mapping. + type AccountMapping: AccountMapping; + + /// Origin for `transact` call. + type XcmTransactOrigin: EnsureOrigin; + } + + #[pallet::origin] + pub type Origin = RawOrigin<::AccountId>; + + /// Global nonce for all transactions to avoid hash collision, which is + /// caused by the same dummy signatures for all transactions. + #[pallet::storage] + pub type Nonce = StorageValue<_, U256, ValueQuery>; + + #[pallet::call] + impl Pallet { + /// Transact an Ethereum transaction. Similar to `pallet_ethereum::Transact`, + /// but is only for XCM remote call. + #[pallet::call_index(0)] + #[pallet::weight({ + let weight_limit = T::GasWeightMapping::gas_to_weight(tx.gas_limit.unique_saturated_into(), false); + // `Nonce` storage read 1, write 1. + weight_limit.saturating_add(T::DbWeight::get().reads_writes(1, 1)) + })] + pub fn transact(origin: OriginFor, tx: CheckedEthereumTx) -> DispatchResultWithPostInfo { + let source = T::XcmTransactOrigin::ensure_origin(origin)?; + Self::do_transact( + T::AccountMapping::into_h160(source), + tx.into(), + CheckedEthereumTxKind::Xcm, + ) + .map(|(post_info, _)| post_info) + } + } +} + +impl Pallet { + /// Validate and execute the checked tx. Only `Call` transaction action is allowed. + fn do_transact( + source: H160, + checked_tx: CheckedEthereumTx, + tx_kind: CheckedEthereumTxKind, + ) -> Result<(PostDispatchInfo, CallInfo), DispatchErrorWithPostInfo> { + let chain_id = T::ChainId::get(); + let nonce = Nonce::::get(); + let tx = checked_tx.into_ethereum_tx(Nonce::::get(), chain_id); + let tx_data: TransactionData = (&tx).into(); + + // Validate the tx. + let _ = CheckEvmTransaction::::new( + CheckEvmTransactionConfig { + evm_config: T::config(), + block_gas_limit: U256::from(Self::block_gas_limit(&tx_kind)), + base_fee: U256::zero(), + chain_id, + is_transactional: true, + }, + tx_data.into(), + ) + // Gas limit validation. The fee payment has been validated as the tx is `checked`. + .validate_common() + .map_err(|_| DispatchErrorWithPostInfo { + post_info: PostDispatchInfo { + // `Nonce` storage read 1. + actual_weight: Some(T::DbWeight::get().reads(1)), + pays_fee: Pays::Yes, + }, + error: DispatchError::Other("Failed to validate Ethereum tx"), + })?; + + Nonce::::put(nonce.saturating_add(U256::one())); + + // Execute the tx. + let (post_info, apply_info) = T::ValidatedTransaction::apply(source, tx)?; + match apply_info { + CallOrCreateInfo::Call(info) => Ok((post_info, info)), + // It is not possible to have a `Create` transaction via `CheckedEthereumTx`. + CallOrCreateInfo::Create(_) => { + unreachable!("Cannot create a 'Create' transaction; qed") + } + } + } + + /// Block gas limit calculation based on the tx kind. + fn block_gas_limit(tx_kind: &CheckedEthereumTxKind) -> u64 { + let weight_limit = match tx_kind { + CheckedEthereumTxKind::Xcm => T::ReservedXcmpWeight::get(), + CheckedEthereumTxKind::Xvm => T::XvmTxWeightLimit::get(), + }; + T::GasWeightMapping::weight_to_gas(weight_limit) + } +} + +impl CheckedEthereumTransact for Pallet { + fn xvm_transact( + source: H160, + checked_tx: CheckedEthereumTx, + ) -> Result<(PostDispatchInfo, CallInfo), DispatchErrorWithPostInfo> { + Self::do_transact(source, checked_tx, CheckedEthereumTxKind::Xvm) + } +} diff --git a/pallets/ethereum-checked/src/mock.rs b/pallets/ethereum-checked/src/mock.rs new file mode 100644 index 0000000000..6f301ed0ef --- /dev/null +++ b/pallets/ethereum-checked/src/mock.rs @@ -0,0 +1,306 @@ +// This file is part of Astar. + +// Copyright (C) 2019-2023 Stake Technologies Pte.Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later + +// Astar is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Astar is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Astar. If not, see . + +#![cfg(test)] + +use super::*; +use crate as pallet_ethereum_checked; + +use ethereum_types::H256; + +use frame_support::{ + assert_ok, construct_runtime, parameter_types, + sp_io::TestExternalities, + traits::{ConstU128, ConstU64, FindAuthor}, + weights::Weight, +}; +use pallet_ethereum::PostLogContent; +use pallet_evm::{AddressMapping, FeeCalculator}; +use sp_io::hashing::blake2_256; +use sp_runtime::{ + testing::Header, + traits::{BlakeTwo256, IdentityLookup}, + AccountId32, ConsensusEngineId, +}; + +parameter_types! { + pub BlockWeights: frame_system::limits::BlockWeights = + frame_system::limits::BlockWeights::simple_max(Weight::from_parts(1024, 0)); +} + +impl frame_system::Config for TestRuntime { + type BaseCallFilter = frame_support::traits::Everything; + type BlockWeights = (); + type BlockLength = (); + type RuntimeOrigin = RuntimeOrigin; + type Index = u64; + type RuntimeCall = RuntimeCall; + type BlockNumber = BlockNumber; + type Hash = H256; + type Hashing = BlakeTwo256; + type AccountId = AccountId; + type Lookup = IdentityLookup; + type Header = Header; + type RuntimeEvent = RuntimeEvent; + type BlockHashCount = ConstU64<250>; + type DbWeight = (); + type Version = (); + type PalletInfo = PalletInfo; + type AccountData = pallet_balances::AccountData; + type OnNewAccount = (); + type OnKilledAccount = (); + type SystemWeightInfo = (); + type SS58Prefix = (); + type OnSetCode = (); + type MaxConsumers = frame_support::traits::ConstU32<16>; +} + +impl pallet_balances::Config for TestRuntime { + type MaxLocks = ConstU32<4>; + type MaxReserves = (); + type ReserveIdentifier = [u8; 8]; + type Balance = Balance; + type RuntimeEvent = RuntimeEvent; + type DustRemoval = (); + type ExistentialDeposit = ConstU128<2>; + type AccountStore = System; + type WeightInfo = (); +} + +impl pallet_timestamp::Config for TestRuntime { + type Moment = u64; + type OnTimestampSet = (); + type MinimumPeriod = ConstU64<3>; + type WeightInfo = (); +} + +pub struct MockFeeCalculator; +impl FeeCalculator for MockFeeCalculator { + fn min_gas_price() -> (U256, Weight) { + (U256::one(), Weight::zero()) + } +} + +pub struct MockFindAuthor; +impl FindAuthor for MockFindAuthor { + fn find_author<'a, I>(_digests: I) -> Option + where + I: 'a + IntoIterator, + { + Some(H160::from_low_u64_be(1)) + } +} + +pub struct MockAddressMapping; +impl AddressMapping for MockAddressMapping { + fn into_account_id(address: H160) -> AccountId32 { + if address == ALICE_H160 { + return ALICE; + } + if address == BOB_H160 { + return BOB; + } + if address == CHARLIE_H160 { + return CHARLIE; + } + + return pallet_evm::HashedAddressMapping::::into_account_id(address); + } +} + +pub struct MockAccountMapping; +impl AccountMapping for MockAccountMapping { + fn into_h160(account_id: AccountId) -> H160 { + if account_id == ALICE { + return ALICE_H160; + } + if account_id == BOB { + return BOB_H160; + } + if account_id == CHARLIE { + return CHARLIE_H160; + } + + let data = (b"evm:", account_id); + return H160::from_slice(&data.using_encoded(blake2_256)[0..20]); + } +} + +parameter_types! { + pub WeightPerGas: Weight = Weight::from_parts(1, 0); + pub const BlockGasLimit: U256 = U256::MAX; +} + +impl pallet_evm::Config for TestRuntime { + type FeeCalculator = MockFeeCalculator; + type GasWeightMapping = pallet_evm::FixedGasWeightMapping; + type WeightPerGas = WeightPerGas; + type BlockHashMapping = pallet_ethereum::EthereumBlockHashMapping; + type CallOrigin = pallet_evm::EnsureAddressRoot; + type WithdrawOrigin = pallet_evm::EnsureAddressTruncated; + type AddressMapping = MockAddressMapping; + type Currency = Balances; + type RuntimeEvent = RuntimeEvent; + type Runner = pallet_evm::runner::stack::Runner; + type PrecompilesType = (); + type PrecompilesValue = (); + type ChainId = ConstU64<1024>; + type OnChargeTransaction = (); + type BlockGasLimit = BlockGasLimit; + type OnCreate = (); + type FindAuthor = MockFindAuthor; + type Timestamp = Timestamp; + type WeightInfo = pallet_evm::weights::SubstrateWeight; +} + +parameter_types! { + pub const PostBlockAndTxnHashes: PostLogContent = PostLogContent::BlockAndTxnHashes; +} + +impl pallet_ethereum::Config for TestRuntime { + type RuntimeEvent = RuntimeEvent; + type StateRoot = pallet_ethereum::IntermediateStateRoot; + type PostLogContent = PostBlockAndTxnHashes; + type ExtraDataLength = ConstU32<30>; +} + +parameter_types! { + pub TxWeightLimit: Weight = Weight::from_parts(u64::max_value(), 0); +} + +impl pallet_ethereum_checked::Config for TestRuntime { + type ReservedXcmpWeight = TxWeightLimit; + type XvmTxWeightLimit = TxWeightLimit; + type InvalidEvmTransactionError = pallet_ethereum::InvalidTransactionWrapper; + type ValidatedTransaction = pallet_ethereum::ValidatedTransaction; + type AccountMapping = MockAccountMapping; + type XcmTransactOrigin = EnsureXcmEthereumTx; +} + +pub(crate) type AccountId = AccountId32; +pub(crate) type BlockNumber = u64; +pub(crate) type Balance = u128; + +pub const ALICE: AccountId32 = AccountId32::new([0u8; 32]); +pub const BOB: AccountId32 = AccountId32::new([1u8; 32]); +pub const CHARLIE: AccountId32 = AccountId32::new([2u8; 32]); + +type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic; +type Block = frame_system::mocking::MockBlock; + +construct_runtime!( + pub struct TestRuntime + where + Block = Block, + NodeBlock = Block, + UncheckedExtrinsic = UncheckedExtrinsic, + { + System: frame_system, + Timestamp: pallet_timestamp, + Balances: pallet_balances, + Evm: pallet_evm, + Ethereum: pallet_ethereum, + EthereumChecked: pallet_ethereum_checked::{Pallet, Call, Origin}, + } +); + +pub const ALICE_H160: H160 = H160::repeat_byte(1); +pub const BOB_H160: H160 = H160::repeat_byte(2); +pub const CHARLIE_H160: H160 = H160::repeat_byte(3); + +/* Testing contract + +pragma solidity >=0.8.2 <0.9.0; + +contract Storage { + uint256 number; + + /** + * @dev Store value in variable + * @param num value to store + */ + function store(uint256 num) public { + number = num; + } + + /** + * @dev Return value + * @return value of 'number' + */ + function retrieve() public view returns (uint256){ + return number; + } +} +*/ +const STORAGE_CONTRACT: &str = "608060405234801561001057600080fd5b50610150806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c80632e64cec11461003b5780636057361d14610059575b600080fd5b610043610075565b60405161005091906100a1565b60405180910390f35b610073600480360381019061006e91906100ed565b61007e565b005b60008054905090565b8060008190555050565b6000819050919050565b61009b81610088565b82525050565b60006020820190506100b66000830184610092565b92915050565b600080fd5b6100ca81610088565b81146100d557600080fd5b50565b6000813590506100e7816100c1565b92915050565b600060208284031215610103576101026100bc565b5b6000610111848285016100d8565b9150509291505056fea2646970667358221220322c78243e61b783558509c9cc22cb8493dde6925aa5e89a08cdf6e22f279ef164736f6c63430008120033"; + +pub fn contract_address() -> H160 { + H160::from_slice(&hex::decode("dfb975d018f03994a3b943808e3aa0964bd78463").unwrap()) +} + +pub struct ExtBuilder { + balances: Vec<(AccountId, Balance)>, +} + +impl Default for ExtBuilder { + fn default() -> Self { + Self { + balances: vec![ + (ALICE, 1_000_000_000_000), + (BOB, 1_000_000_000_000), + (CHARLIE, 1_000_000_000_000), + ], + } + } +} + +impl ExtBuilder { + pub fn build(self) -> TestExternalities { + let mut t = frame_system::GenesisConfig::default() + .build_storage::() + .unwrap(); + + pallet_balances::GenesisConfig:: { + balances: self.balances, + } + .assimilate_storage(&mut t) + .unwrap(); + + let mut ext = TestExternalities::from(t); + ext.execute_with(|| { + System::set_block_number(1); + + assert_ok!(Evm::create2( + RuntimeOrigin::root(), + ALICE_H160, + hex::decode(STORAGE_CONTRACT).unwrap(), + H256::zero(), + U256::zero(), + 1_000_000, + U256::one(), + None, + Some(U256::zero()), + vec![], + )); + System::assert_last_event(RuntimeEvent::Evm(pallet_evm::Event::Created { + address: contract_address(), + })); + }); + ext + } +} diff --git a/pallets/ethereum-checked/src/tests.rs b/pallets/ethereum-checked/src/tests.rs new file mode 100644 index 0000000000..d474f94282 --- /dev/null +++ b/pallets/ethereum-checked/src/tests.rs @@ -0,0 +1,141 @@ +// This file is part of Astar. + +// Copyright (C) 2019-2023 Stake Technologies Pte.Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later + +// Astar is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Astar is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Astar. If not, see . + +#![cfg(test)] + +use super::*; +use mock::*; + +use astar_primitives::ethereum_checked::MAX_ETHEREUM_TX_INPUT_SIZE; +use ethereum::{ReceiptV3, TransactionV2 as Transaction}; +use frame_support::{assert_noop, assert_ok, traits::ConstU32}; +use sp_runtime::DispatchError; + +fn bounded_input(data: &'static str) -> BoundedVec> { + BoundedVec::>::try_from(hex::decode(data).unwrap()) + .unwrap() +} + +#[test] +fn transact_works() { + ExtBuilder::default().build().execute_with(|| { + let store_tx = CheckedEthereumTx { + gas_limit: U256::from(1_000_000), + target: contract_address(), + value: U256::zero(), + // Calling `store(3)` + input: bounded_input( + "6057361d0000000000000000000000000000000000000000000000000000000000000003", + ), + maybe_access_list: None, + }; + assert_ok!(EthereumChecked::transact( + RawOrigin::XcmEthereumTx(ALICE).into(), + store_tx.clone() + )); + assert_ok!(EthereumChecked::transact( + RawOrigin::XcmEthereumTx(ALICE).into(), + store_tx + )); + let pending = pallet_ethereum::Pending::::get(); + assert_eq!(pending.len(), 2); + + match pending[0] { + (Transaction::EIP1559(ref t), _, ReceiptV3::EIP1559(ref r)) => { + // nonce 0, status code 1 (success) + assert_eq!(t.nonce, U256::zero()); + assert_eq!(r.status_code, 1); + } + _ => panic!("unexpected transaction type"), + } + match pending[1] { + (Transaction::EIP1559(ref t), _, ReceiptV3::EIP1559(ref r)) => { + // nonce 1, status code 1 (success) + assert_eq!(t.nonce, U256::one()); + assert_eq!(r.status_code, 1); + } + _ => panic!("unexpected transaction type"), + } + assert_eq!(Nonce::::get(), U256::from(2)); + }); +} + +#[test] +fn origin_check_works() { + ExtBuilder::default().build().execute_with(|| { + let store_tx = CheckedEthereumTx { + gas_limit: U256::from(1_000_000), + target: contract_address(), + value: U256::zero(), + // Calling `store(3)` + input: bounded_input( + "6057361d0000000000000000000000000000000000000000000000000000000000000003", + ), + maybe_access_list: None, + }; + assert_noop!( + EthereumChecked::transact(RuntimeOrigin::signed(ALICE), store_tx.clone()), + DispatchError::BadOrigin + ); + assert_noop!( + EthereumChecked::transact(RuntimeOrigin::root(), store_tx.clone()), + DispatchError::BadOrigin + ); + assert_noop!( + EthereumChecked::transact(RuntimeOrigin::none(), store_tx), + DispatchError::BadOrigin + ); + }); +} + +#[test] +fn no_hash_collision() { + ExtBuilder::default().build().execute_with(|| { + let store_tx = CheckedEthereumTx { + gas_limit: U256::from(1_000_000), + target: contract_address(), + value: U256::zero(), + // Calling `store(3)` + input: bounded_input( + "6057361d0000000000000000000000000000000000000000000000000000000000000003", + ), + maybe_access_list: None, + }; + for _ in 0..5 { + assert_ok!(EthereumChecked::transact( + RawOrigin::XcmEthereumTx(ALICE).into(), + store_tx.clone() + )); + assert_ok!(::xvm_transact( + BOB_H160, + store_tx.clone() + )); + assert_ok!(::xvm_transact( + CHARLIE_H160, + store_tx.clone() + )); + } + + let mut tx_hashes = pallet_ethereum::Pending::::get() + .iter() + .map(|(tx, _, _)| tx.hash()) + .collect::>(); + tx_hashes.dedup(); + assert_eq!(tx_hashes.len(), 15); + }); +} diff --git a/primitives/Cargo.toml b/primitives/Cargo.toml index cf498aa57d..5e7e99fb5c 100644 --- a/primitives/Cargo.toml +++ b/primitives/Cargo.toml @@ -9,6 +9,13 @@ repository.workspace = true [dependencies] # third-party dependencies log = { workspace = true } +parity-scale-codec = { workspace = true } +scale-info = { workspace = true } + +# Ethereum/Frontier dependencies +ethereum = { workspace = true, features = ["with-codec"] } +ethereum-types = { workspace = true } +fp-evm = { workspace = true } # Substrate dependencies frame-support = { workspace = true } @@ -28,6 +35,11 @@ pallet-xc-asset-config = { workspace = true } default = ["std"] std = [ "log/std", + "parity-scale-codec/std", + "scale-info/std", + "ethereum-types/std", + "ethereum/std", + "fp-evm/std", "frame-support/std", "sp-std/std", "sp-runtime/std", diff --git a/primitives/src/ethereum_checked.rs b/primitives/src/ethereum_checked.rs new file mode 100644 index 0000000000..e50edc318c --- /dev/null +++ b/primitives/src/ethereum_checked.rs @@ -0,0 +1,101 @@ +// This file is part of Astar. + +// Copyright (C) 2019-2023 Stake Technologies Pte.Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later + +// Astar is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Astar is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Astar. If not, see . + +use parity_scale_codec::{Decode, Encode}; +use scale_info::TypeInfo; + +use ethereum::{ + AccessListItem, EIP1559Transaction, TransactionAction, TransactionV2 as Transaction, +}; +use ethereum_types::{H160, H256, U256}; +use fp_evm::CallInfo; +use frame_support::{ + dispatch::{DispatchErrorWithPostInfo, PostDispatchInfo}, + pallet_prelude::*, + traits::ConstU32, + BoundedVec, +}; +use sp_std::{prelude::*, result::Result}; + +/// Max Ethereum tx input size: 65_536 bytes +pub const MAX_ETHEREUM_TX_INPUT_SIZE: u32 = 2u32.pow(16); + +/// The checked Ethereum transaction. Only contracts `call` is support(no `create`). +#[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo)] +pub struct CheckedEthereumTx { + /// Gas limit. + pub gas_limit: U256, + /// Contract address to call. + pub target: H160, + /// Amount to transfer. + pub value: U256, + /// Input of a contract call. + pub input: BoundedVec>, + /// Optional access list, specified in EIP-2930. + pub maybe_access_list: Option)>>, +} + +impl CheckedEthereumTx { + pub fn into_ethereum_tx(&self, nonce: U256, chain_id: u64) -> Transaction { + let access_list = if let Some(ref list) = self.maybe_access_list { + list.iter() + .map(|(address, storage_keys)| AccessListItem { + address: *address, + storage_keys: storage_keys.clone(), + }) + .collect() + } else { + Vec::new() + }; + + Transaction::EIP1559(EIP1559Transaction { + chain_id, + nonce, + max_fee_per_gas: U256::zero(), + max_priority_fee_per_gas: U256::zero(), + gas_limit: self.gas_limit, + value: self.value, + action: TransactionAction::Call(self.target), + input: self.input.to_vec(), + access_list, + odd_y_parity: true, + r: dummy_rs(), + s: dummy_rs(), + }) + } +} + +/// Dummy signature for all transactions. +fn dummy_rs() -> H256 { + H256::from_low_u64_be(1u64) +} + +/// Transact an checked Ethereum transaction. Similar to `pallet_ethereum::Transact` but +/// doesn't require tx signature. +pub trait CheckedEthereumTransact { + /// Transact an checked Ethereum transaction in XVM. + fn xvm_transact( + source: H160, + checked_tx: CheckedEthereumTx, + ) -> Result<(PostDispatchInfo, CallInfo), DispatchErrorWithPostInfo>; +} + +/// Mapping from `Account` to `H160`. +pub trait AccountMapping { + fn into_h160(account: AccountId) -> H160; +} diff --git a/primitives/src/lib.rs b/primitives/src/lib.rs index 9790cb769f..386a79f5ae 100644 --- a/primitives/src/lib.rs +++ b/primitives/src/lib.rs @@ -23,6 +23,9 @@ //! These core Astar types are used by the Shiden, Shibuya, Astar and Local runtime. pub mod xcm; +/// Checked Ethereum transaction primitives. +pub mod ethereum_checked; + use sp_runtime::traits::BlakeTwo256; use sp_runtime::{ generic,