diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 217a450..be2a767 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1 +1 @@ -* @kotlarmilos @NZT48 +* @NZT48 diff --git a/Cargo.lock b/Cargo.lock index a8da5f0..9ecf2ec 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -75,9 +75,9 @@ dependencies = [ [[package]] name = "aho-corasick" -version = "0.7.18" +version = "0.7.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f" +checksum = "b4f55bd91a0978cbfd91c457a164bab8b4001c833b7f323132c0a4e1922dd44e" dependencies = [ "memchr", ] @@ -90,9 +90,9 @@ checksum = "fbf688625d06217d5b1bb0ea9d9c44a1635fd0ee3534466388d18203174f4d11" [[package]] name = "android_system_properties" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7ed72e1635e121ca3e79420540282af22da58be50de153d36f81ddc6b83aa9e" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" dependencies = [ "libc", ] @@ -108,9 +108,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.62" +version = "1.0.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1485d4d2cc45e7b201ee3767015c96faa5904387c9d87c6efdd0fb511f12d305" +checksum = "b9a8f622bcf6ff3df478e9deba3e03e4e04b300f8e6a139e192c05fa3490afc7" [[package]] name = "approx" @@ -197,9 +197,9 @@ dependencies = [ [[package]] name = "async-global-executor" -version = "2.2.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5262ed948da60dd8956c6c5aca4d4163593dddb7b32d73267c93dab7b2e98940" +checksum = "0da5b41ee986eed3f524c380e6d64965aea573882a8907682ad100f7859305ca" dependencies = [ "async-channel", "async-executor", @@ -207,15 +207,14 @@ dependencies = [ "async-lock", "blocking", "futures-lite", - "num_cpus", "once_cell", ] [[package]] name = "async-io" -version = "1.8.0" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ab006897723d9352f63e2b13047177c3982d8d79709d713ce7747a8f19fd1b0" +checksum = "83e21f3a490c72b3b0cf44962180e60045de2925d8dff97918f7ee43c8f637c7" dependencies = [ "autocfg", "concurrent-queue", @@ -348,6 +347,18 @@ dependencies = [ "winapi", ] +[[package]] +name = "auto_impl" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7862e21c893d65a1650125d157eaeec691439379a1cee17ee49031b79236ada4" +dependencies = [ + "proc-macro-error", + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "autocfg" version = "1.1.0" @@ -624,9 +635,9 @@ dependencies = [ [[package]] name = "block-buffer" -version = "0.10.2" +version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bf7fe51849ea569fd452f37822f606a5cabb684dc918707a0193fd4664ff324" +checksum = "69cce20737498f97b993470a6e536b8523f0af7892a4f928cceb1ac5e52ebe7e" dependencies = [ "generic-array 0.14.6", ] @@ -891,9 +902,9 @@ dependencies = [ [[package]] name = "clap" -version = "3.2.17" +version = "3.2.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29e724a68d9319343bb3328c9cc2dfde263f4b3142ee1059a9980580171c954b" +checksum = "23b71c3ce99b7611011217b366d923f1d0a7e07a92bb2dbf1e84508c673ca3bd" dependencies = [ "atty", "bitflags", @@ -908,9 +919,9 @@ dependencies = [ [[package]] name = "clap_derive" -version = "3.2.17" +version = "3.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13547f7012c01ab4a0e8f8967730ada8f9fdf419e8b6c792788f39cf4e46eefa" +checksum = "ea0c8bce528c4be4da13ea6fead8965e95b6073585a2f05204bd8f4119f82a65" dependencies = [ "heck", "proc-macro-error", @@ -951,9 +962,9 @@ dependencies = [ [[package]] name = "comfy-table" -version = "6.0.0" +version = "6.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "121d8a5b0346092c18a4b2fd6f620d7a06f0eb7ac0a45860939a0884bc579c56" +checksum = "85914173c2f558d61613bfbbf1911f14e630895087a7ed2fafc0f5319e1536e7" dependencies = [ "strum", "strum_macros", @@ -1023,9 +1034,9 @@ dependencies = [ [[package]] name = "cpufeatures" -version = "0.2.3" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1079fb8528d9f9c888b1e8aa651e6e079ade467323d58f75faf1d30b1808f540" +checksum = "28d997bd5e24a5928dd43e46dc529867e207907fe0b239c3477d924f7f2ca320" dependencies = [ "libc", ] @@ -1481,7 +1492,7 @@ dependencies = [ "environmental", "frame-support", "frame-system", - "impl-trait-for-tuples", + "impl-trait-for-tuples 0.2.2", "log", "pallet-balances", "parity-scale-codec", @@ -1847,7 +1858,7 @@ version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f2fb860ca6fafa5552fb6d0e816a69c8e49f0908bf524e30a90d97c85892d506" dependencies = [ - "block-buffer 0.10.2", + "block-buffer 0.10.3", "crypto-common", "subtle", ] @@ -2084,12 +2095,170 @@ dependencies = [ "libc", ] +[[package]] +name = "ethbloom" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11da94e443c60508eb62cf256243a64da87304c2802ac2528847f79d750007ef" +dependencies = [ + "crunchy", + "fixed-hash", + "impl-codec", + "impl-rlp", + "impl-serde", + "scale-info", + "tiny-keccak", +] + +[[package]] +name = "ethereum" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23750149fe8834c0e24bb9adcbacbe06c45b9861f15df53e09f26cb7c4ab91ef" +dependencies = [ + "bytes", + "ethereum-types", + "hash-db", + "hash256-std-hasher", + "parity-scale-codec", + "rlp", + "rlp-derive", + "scale-info", + "serde", + "sha3 0.10.4", + "triehash", +] + +[[package]] +name = "ethereum-types" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2827b94c556145446fcce834ca86b7abf0c39a805883fe20e72c5bfdb5a0dc6" +dependencies = [ + "ethbloom", + "fixed-hash", + "impl-codec", + "impl-rlp", + "impl-serde", + "primitive-types", + "scale-info", + "uint", +] + [[package]] name = "event-listener" version = "2.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" +[[package]] +name = "evm" +version = "0.35.0" +source = "git+https://github.com/rust-blockchain/evm?rev=01bcbd2205a212c34451d3b4fabc962793b057d3#01bcbd2205a212c34451d3b4fabc962793b057d3" +dependencies = [ + "auto_impl", + "environmental", + "ethereum", + "evm-core 0.35.0 (git+https://github.com/rust-blockchain/evm?rev=01bcbd2205a212c34451d3b4fabc962793b057d3)", + "evm-gasometer 0.35.0 (git+https://github.com/rust-blockchain/evm?rev=01bcbd2205a212c34451d3b4fabc962793b057d3)", + "evm-runtime 0.35.0 (git+https://github.com/rust-blockchain/evm?rev=01bcbd2205a212c34451d3b4fabc962793b057d3)", + "log", + "parity-scale-codec", + "primitive-types", + "rlp", + "scale-info", + "serde", + "sha3 0.10.4", +] + +[[package]] +name = "evm" +version = "0.35.0" +source = "git+https://github.com/rust-blockchain/evm?rev=0b686f8c2c83a52638917caa649dc23302fda80d#0b686f8c2c83a52638917caa649dc23302fda80d" +dependencies = [ + "auto_impl", + "environmental", + "ethereum", + "evm-core 0.35.0 (git+https://github.com/rust-blockchain/evm?rev=0b686f8c2c83a52638917caa649dc23302fda80d)", + "evm-gasometer 0.35.0 (git+https://github.com/rust-blockchain/evm?rev=0b686f8c2c83a52638917caa649dc23302fda80d)", + "evm-runtime 0.35.0 (git+https://github.com/rust-blockchain/evm?rev=0b686f8c2c83a52638917caa649dc23302fda80d)", + "log", + "parity-scale-codec", + "primitive-types", + "rlp", + "scale-info", + "serde", + "sha3 0.10.4", +] + +[[package]] +name = "evm-core" +version = "0.35.0" +source = "git+https://github.com/rust-blockchain/evm?rev=01bcbd2205a212c34451d3b4fabc962793b057d3#01bcbd2205a212c34451d3b4fabc962793b057d3" +dependencies = [ + "parity-scale-codec", + "primitive-types", + "scale-info", + "serde", +] + +[[package]] +name = "evm-core" +version = "0.35.0" +source = "git+https://github.com/rust-blockchain/evm?rev=0b686f8c2c83a52638917caa649dc23302fda80d#0b686f8c2c83a52638917caa649dc23302fda80d" +dependencies = [ + "parity-scale-codec", + "primitive-types", + "scale-info", + "serde", +] + +[[package]] +name = "evm-gasometer" +version = "0.35.0" +source = "git+https://github.com/rust-blockchain/evm?rev=01bcbd2205a212c34451d3b4fabc962793b057d3#01bcbd2205a212c34451d3b4fabc962793b057d3" +dependencies = [ + "environmental", + "evm-core 0.35.0 (git+https://github.com/rust-blockchain/evm?rev=01bcbd2205a212c34451d3b4fabc962793b057d3)", + "evm-runtime 0.35.0 (git+https://github.com/rust-blockchain/evm?rev=01bcbd2205a212c34451d3b4fabc962793b057d3)", + "primitive-types", +] + +[[package]] +name = "evm-gasometer" +version = "0.35.0" +source = "git+https://github.com/rust-blockchain/evm?rev=0b686f8c2c83a52638917caa649dc23302fda80d#0b686f8c2c83a52638917caa649dc23302fda80d" +dependencies = [ + "environmental", + "evm-core 0.35.0 (git+https://github.com/rust-blockchain/evm?rev=0b686f8c2c83a52638917caa649dc23302fda80d)", + "evm-runtime 0.35.0 (git+https://github.com/rust-blockchain/evm?rev=0b686f8c2c83a52638917caa649dc23302fda80d)", + "primitive-types", +] + +[[package]] +name = "evm-runtime" +version = "0.35.0" +source = "git+https://github.com/rust-blockchain/evm?rev=01bcbd2205a212c34451d3b4fabc962793b057d3#01bcbd2205a212c34451d3b4fabc962793b057d3" +dependencies = [ + "auto_impl", + "environmental", + "evm-core 0.35.0 (git+https://github.com/rust-blockchain/evm?rev=01bcbd2205a212c34451d3b4fabc962793b057d3)", + "primitive-types", + "sha3 0.10.4", +] + +[[package]] +name = "evm-runtime" +version = "0.35.0" +source = "git+https://github.com/rust-blockchain/evm?rev=0b686f8c2c83a52638917caa649dc23302fda80d#0b686f8c2c83a52638917caa649dc23302fda80d" +dependencies = [ + "auto_impl", + "environmental", + "evm-core 0.35.0 (git+https://github.com/rust-blockchain/evm?rev=0b686f8c2c83a52638917caa649dc23302fda80d)", + "primitive-types", + "sha3 0.10.4", +] + [[package]] name = "exit-future" version = "0.2.0" @@ -2170,6 +2339,92 @@ dependencies = [ "thiserror", ] +[[package]] +name = "fc-db" +version = "2.0.0-dev" +source = "git+https://github.com/OriginTrail/frontier?branch=polkadot-v0.9.27#1eba12c48e28ba334c53ea90d837e0a1f64cd95e" +dependencies = [ + "fp-storage", + "kvdb-rocksdb", + "parity-db", + "parity-scale-codec", + "parking_lot 0.12.1", + "sc-client-db", + "sp-core", + "sp-database", + "sp-runtime", +] + +[[package]] +name = "fc-mapping-sync" +version = "2.0.0-dev" +source = "git+https://github.com/OriginTrail/frontier?branch=polkadot-v0.9.27#1eba12c48e28ba334c53ea90d837e0a1f64cd95e" +dependencies = [ + "fc-db", + "fp-consensus", + "fp-rpc", + "futures", + "futures-timer", + "log", + "sc-client-api", + "sp-api", + "sp-blockchain", + "sp-runtime", +] + +[[package]] +name = "fc-rpc" +version = "2.0.0-dev" +source = "git+https://github.com/OriginTrail/frontier?branch=polkadot-v0.9.27#1eba12c48e28ba334c53ea90d837e0a1f64cd95e" +dependencies = [ + "ethereum", + "ethereum-types", + "evm 0.35.0 (git+https://github.com/rust-blockchain/evm?rev=01bcbd2205a212c34451d3b4fabc962793b057d3)", + "fc-db", + "fc-rpc-core", + "fp-rpc", + "fp-storage", + "futures", + "hex", + "jsonrpsee", + "libsecp256k1", + "log", + "lru 0.7.8", + "parity-scale-codec", + "prometheus", + "rand 0.8.5", + "rlp", + "sc-client-api", + "sc-network", + "sc-rpc", + "sc-service", + "sc-transaction-pool", + "sc-transaction-pool-api", + "sp-api", + "sp-block-builder", + "sp-blockchain", + "sp-core", + "sp-io", + "sp-runtime", + "sp-storage", + "substrate-prometheus-endpoint", + "tokio", +] + +[[package]] +name = "fc-rpc-core" +version = "1.1.0-dev" +source = "git+https://github.com/OriginTrail/frontier?branch=polkadot-v0.9.27#1eba12c48e28ba334c53ea90d837e0a1f64cd95e" +dependencies = [ + "ethereum", + "ethereum-types", + "jsonrpsee", + "rlp", + "rustc-hex", + "serde", + "serde_json", +] + [[package]] name = "fdlimit" version = "0.2.1" @@ -2280,6 +2535,85 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "fp-consensus" +version = "2.0.0-dev" +source = "git+https://github.com/OriginTrail/frontier?branch=polkadot-v0.9.27#1eba12c48e28ba334c53ea90d837e0a1f64cd95e" +dependencies = [ + "ethereum", + "parity-scale-codec", + "sp-core", + "sp-runtime", + "sp-std", +] + +[[package]] +name = "fp-ethereum" +version = "1.0.0-dev" +source = "git+https://github.com/OriginTrail/frontier?branch=polkadot-v0.9.27#1eba12c48e28ba334c53ea90d837e0a1f64cd95e" +dependencies = [ + "ethereum", + "ethereum-types", + "fp-evm", + "frame-support", + "parity-scale-codec", + "sp-core", + "sp-std", +] + +[[package]] +name = "fp-evm" +version = "3.0.0-dev" +source = "git+https://github.com/OriginTrail/frontier?branch=polkadot-v0.9.27#1eba12c48e28ba334c53ea90d837e0a1f64cd95e" +dependencies = [ + "evm 0.35.0 (git+https://github.com/rust-blockchain/evm?rev=01bcbd2205a212c34451d3b4fabc962793b057d3)", + "frame-support", + "parity-scale-codec", + "serde", + "sp-core", + "sp-std", +] + +[[package]] +name = "fp-rpc" +version = "3.0.0-dev" +source = "git+https://github.com/OriginTrail/frontier?branch=polkadot-v0.9.27#1eba12c48e28ba334c53ea90d837e0a1f64cd95e" +dependencies = [ + "ethereum", + "ethereum-types", + "fp-evm", + "parity-scale-codec", + "scale-info", + "sp-api", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", +] + +[[package]] +name = "fp-self-contained" +version = "1.0.0-dev" +source = "git+https://github.com/OriginTrail/frontier?branch=polkadot-v0.9.27#1eba12c48e28ba334c53ea90d837e0a1f64cd95e" +dependencies = [ + "ethereum", + "frame-support", + "parity-scale-codec", + "parity-util-mem", + "scale-info", + "serde", + "sp-runtime", +] + +[[package]] +name = "fp-storage" +version = "2.0.0" +source = "git+https://github.com/OriginTrail/frontier?branch=polkadot-v0.9.27#1eba12c48e28ba334c53ea90d837e0a1f64cd95e" +dependencies = [ + "parity-scale-codec", + "serde", +] + [[package]] name = "frame-benchmarking" version = "4.0.0-dev" @@ -2416,7 +2750,7 @@ dependencies = [ "bitflags", "frame-metadata", "frame-support-procedural", - "impl-trait-for-tuples", + "impl-trait-for-tuples 0.2.2", "k256", "log", "once_cell", @@ -2566,9 +2900,9 @@ checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" [[package]] name = "futures" -version = "0.3.23" +version = "0.3.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab30e97ab6aacfe635fad58f22c2bb06c8b685f7421eb1e064a729e2a5f481fa" +checksum = "7f21eda599937fba36daeb58a22e8f5cee2d14c4a17b5b7739c7c8e5e3b8230c" dependencies = [ "futures-channel", "futures-core", @@ -2581,9 +2915,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.23" +version = "0.3.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bfc52cbddcfd745bf1740338492bb0bd83d76c67b445f91c5fb29fae29ecaa1" +checksum = "30bdd20c28fadd505d0fd6712cdfcb0d4b5648baf45faef7f852afb2399bb050" dependencies = [ "futures-core", "futures-sink", @@ -2591,15 +2925,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.23" +version = "0.3.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2acedae88d38235936c3922476b10fced7b2b68136f5e3c03c2d5be348a1115" +checksum = "4e5aa3de05362c3fb88de6531e6296e85cde7739cccad4b9dfeeb7f6ebce56bf" [[package]] name = "futures-executor" -version = "0.3.23" +version = "0.3.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d11aa21b5b587a64682c0094c2bdd4df0076c5324961a40cc3abd7f37930528" +checksum = "9ff63c23854bee61b6e9cd331d523909f238fc7636290b96826e9cfa5faa00ab" dependencies = [ "futures-core", "futures-task", @@ -2609,9 +2943,9 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.23" +version = "0.3.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93a66fc6d035a26a3ae255a6d2bca35eda63ae4c5512bef54449113f7a1228e5" +checksum = "bbf4d2a7a308fd4578637c0b17c7e1c7ba127b8f6ba00b29f717e9655d85eb68" [[package]] name = "futures-lite" @@ -2630,9 +2964,9 @@ dependencies = [ [[package]] name = "futures-macro" -version = "0.3.23" +version = "0.3.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0db9cce532b0eae2ccf2766ab246f114b56b9cf6d445e00c2549fbc100ca045d" +checksum = "42cd15d1c7456c04dbdf7e88bcd69760d74f3a798d6444e16974b505b0e62f17" dependencies = [ "proc-macro2", "quote", @@ -2652,15 +2986,15 @@ dependencies = [ [[package]] name = "futures-sink" -version = "0.3.23" +version = "0.3.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca0bae1fe9752cf7fd9b0064c674ae63f97b37bc714d745cbde0afb7ec4e6765" +checksum = "21b20ba5a92e727ba30e72834706623d94ac93a725410b6a6b6fbc1b07f7ba56" [[package]] name = "futures-task" -version = "0.3.23" +version = "0.3.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "842fc63b931f4056a24d59de13fb1272134ce261816e063e634ad0c15cdc5306" +checksum = "a6508c467c73851293f390476d4491cf4d227dbabcd4170f3bb6044959b294f1" [[package]] name = "futures-timer" @@ -2670,9 +3004,9 @@ checksum = "e64b03909df88034c26dc1547e8970b91f98bdb65165d6a4e9110d94263dbb2c" [[package]] name = "futures-util" -version = "0.3.23" +version = "0.3.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0828a5471e340229c11c77ca80017937ce3c58cb788a17e5f1c2d5c485a9577" +checksum = "44fb6cb1be61cc1d2e43b262516aafcf63b241cffdb1d3fa115f91d9c7b09c90" dependencies = [ "futures-channel", "futures-core", @@ -2976,9 +3310,9 @@ dependencies = [ [[package]] name = "httparse" -version = "1.7.1" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "496ce29bb5a52785b44e0f7ca2847ae0bb839c9bd28f69acac9b99d461c0c04c" +checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" [[package]] name = "httpdate" @@ -3033,13 +3367,14 @@ dependencies = [ [[package]] name = "iana-time-zone" -version = "0.1.46" +version = "0.1.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad2bfd338099682614d3ee3fe0cd72e0b6a41ca6a87f6a74a3bd593c91650501" +checksum = "4c495f162af0bf17656d0014a0eded5f3cd2f365fdd204548c2869db89359dc7" dependencies = [ "android_system_properties", "core-foundation-sys", "js-sys", + "once_cell", "wasm-bindgen", "winapi", ] @@ -3092,6 +3427,15 @@ dependencies = [ "parity-scale-codec", ] +[[package]] +name = "impl-rlp" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f28220f89297a075ddc7245cd538076ee98b01f2a9c23a53a4f1105d5a322808" +dependencies = [ + "rlp", +] + [[package]] name = "impl-serde" version = "0.3.2" @@ -3101,6 +3445,17 @@ dependencies = [ "serde", ] +[[package]] +name = "impl-trait-for-tuples" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ef5550a42e3740a0e71f909d4c861056a284060af885ae7aa6242820f920d9d" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "impl-trait-for-tuples" version = "0.2.2" @@ -3665,7 +4020,7 @@ dependencies = [ "rand 0.8.5", "ring", "rw-stream-sink", - "sha2 0.10.2", + "sha2 0.10.5", "smallvec", "thiserror", "unsigned-varint", @@ -3739,7 +4094,7 @@ dependencies = [ "prost-build", "rand 0.7.3", "regex", - "sha2 0.10.2", + "sha2 0.10.5", "smallvec", "unsigned-varint", "wasm-timer", @@ -3786,7 +4141,7 @@ dependencies = [ "prost", "prost-build", "rand 0.7.3", - "sha2 0.10.2", + "sha2 0.10.5", "smallvec", "thiserror", "uint", @@ -3864,7 +4219,7 @@ dependencies = [ "prost", "prost-build", "rand 0.8.5", - "sha2 0.10.2", + "sha2 0.10.5", "snow", "static_assertions", "x25519-dalek", @@ -3961,7 +4316,7 @@ dependencies = [ "prost", "prost-build", "rand 0.8.5", - "sha2 0.10.2", + "sha2 0.10.5", "thiserror", "unsigned-varint", "void", @@ -4203,9 +4558,9 @@ checksum = "d4d2456c373231a208ad294c33dc5bff30051eafd954cd4caae83a712b12854d" [[package]] name = "lock_api" -version = "0.4.7" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "327fa5b6a6940e4699ec49a9beae1ea4845c6bab9314e4f84ac68742139d8c53" +checksum = "9f80bf5aacaf25cbfc8210d1cfb718f2bf3b11c4c54e5afe36c236853a8ec390" dependencies = [ "autocfg", "scopeguard", @@ -4250,9 +4605,9 @@ dependencies = [ [[package]] name = "lz4" -version = "1.23.3" +version = "1.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4edcb94251b1c375c459e5abe9fb0168c1c826c3370172684844f8f3f8d1a885" +checksum = "7e9e2dd86df36ce760a60f6ff6ad526f7ba1f14ba0356f8254fb6905e6494df1" dependencies = [ "libc", "lz4-sys", @@ -4260,9 +4615,9 @@ dependencies = [ [[package]] name = "lz4-sys" -version = "1.9.3" +version = "1.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7be8908e2ed6f31c02db8a9fa962f03e36c53fbfde437363eae3306b85d7e17" +checksum = "57d27b317e207b10f69f5e75494119e391a96f48861ae870d1da6edac98ca900" dependencies = [ "cc", "libc", @@ -4322,15 +4677,6 @@ dependencies = [ "libc", ] -[[package]] -name = "memmap2" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "723e3ebdcdc5c023db1df315364573789f8857c11b631a2fdfad7c00f5c046b4" -dependencies = [ - "libc", -] - [[package]] name = "memmap2" version = "0.5.7" @@ -4406,9 +4752,9 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] name = "miniz_oxide" -version = "0.5.3" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f5c75688da582b8ffc1f1799e9db273f32133c49e048f614d22ec3256773ccc" +checksum = "96590ba8f175222643a85693f33d26e9c8a015f599c216509b1a6894af675d34" dependencies = [ "adler", ] @@ -4472,8 +4818,8 @@ dependencies = [ "core2", "digest 0.10.3", "multihash-derive", - "sha2 0.10.2", - "sha3 0.10.2", + "sha2 0.10.5", + "sha3 0.10.4", "unsigned-varint", ] @@ -4654,6 +5000,20 @@ dependencies = [ "minimal-lexical", ] +[[package]] +name = "num" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43db66d1170d347f9a065114077f7dccb00c1b9478c89384490a3425279a4606" +dependencies = [ + "num-bigint 0.4.3", + "num-complex", + "num-integer", + "num-iter", + "num-rational 0.4.1", + "num-traits", +] + [[package]] name = "num-bigint" version = "0.2.6" @@ -4665,6 +5025,17 @@ dependencies = [ "num-traits", ] +[[package]] +name = "num-bigint" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f93ab6289c7b344a8a9f60f88d80aa20032336fe78da341afc91c8a2341fc75f" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + [[package]] name = "num-complex" version = "0.4.2" @@ -4694,6 +5065,17 @@ dependencies = [ "num-traits", ] +[[package]] +name = "num-iter" +version = "0.1.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d03e6c028c5dc5cac6e2dec0efda81fc887605bb3d884578bb6d6bf7514e252" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + [[package]] name = "num-rational" version = "0.2.4" @@ -4701,7 +5083,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5c000134b5dbf44adc5cb772486d335293351644b801551abe8f75c84cfa4aef" dependencies = [ "autocfg", - "num-bigint", + "num-bigint 0.2.6", "num-integer", "num-traits", ] @@ -4713,6 +5095,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0638a1c9d0a3c0914158145bc76cff373a75a627e6ecbfb71cbe6f453a5a19b0" dependencies = [ "autocfg", + "num-bigint 0.4.3", "num-integer", "num-traits", ] @@ -4760,9 +5143,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.13.1" +version = "1.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "074864da206b4973b84eb91683020dbefd6a8c3f0f38e054d93954e891935e4e" +checksum = "2f7254b99e31cad77da24b08ebf628882739a608578bb1bcdfc1f9c21260d7c0" [[package]] name = "opaque-debug" @@ -4823,7 +5206,7 @@ dependencies = [ [[package]] name = "origintrail-parachain-node" -version = "1.0.3" +version = "1.0.4" dependencies = [ "clap", "cumulus-client-cli", @@ -4838,8 +5221,15 @@ dependencies = [ "cumulus-relay-chain-interface", "cumulus-relay-chain-rpc-interface", "derive_more", + "fc-db", + "fc-mapping-sync", + "fc-rpc", + "fc-rpc-core", + "fp-evm", + "fp-rpc", "frame-benchmarking", "frame-benchmarking-cli", + "futures", "hex-literal", "jsonrpsee", "log", @@ -4889,7 +5279,7 @@ dependencies = [ [[package]] name = "origintrail-parachain-runtime" -version = "1.0.3" +version = "1.0.4" dependencies = [ "cumulus-pallet-aura-ext", "cumulus-pallet-dmp-queue", @@ -4900,6 +5290,8 @@ dependencies = [ "cumulus-primitives-core", "cumulus-primitives-timestamp", "cumulus-primitives-utility", + "fp-rpc", + "fp-self-contained", "frame-benchmarking", "frame-executive", "frame-support", @@ -4912,7 +5304,14 @@ dependencies = [ "pallet-aura", "pallet-authorship", "pallet-balances", + "pallet-base-fee", "pallet-collator-selection", + "pallet-ethereum", + "pallet-evm", + "pallet-evm-accounts", + "pallet-evm-precompile-modexp", + "pallet-evm-precompile-sha3fips", + "pallet-evm-precompile-simple", "pallet-scheduler", "pallet-session", "pallet-sudo", @@ -5002,7 +5401,7 @@ source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.27#8e dependencies = [ "frame-support", "frame-system", - "impl-trait-for-tuples", + "impl-trait-for-tuples 0.2.2", "parity-scale-codec", "scale-info", "sp-authorship", @@ -5069,6 +5468,21 @@ dependencies = [ "sp-std", ] +[[package]] +name = "pallet-base-fee" +version = "1.0.0" +source = "git+https://github.com/OriginTrail/frontier?branch=polkadot-v0.9.27#1eba12c48e28ba334c53ea90d837e0a1f64cd95e" +dependencies = [ + "fp-evm", + "frame-support", + "frame-system", + "parity-scale-codec", + "scale-info", + "serde", + "sp-core", + "sp-runtime", +] + [[package]] name = "pallet-beefy" version = "4.0.0-dev" @@ -5252,6 +5666,128 @@ dependencies = [ "sp-std", ] +[[package]] +name = "pallet-ethereum" +version = "4.0.0-dev" +source = "git+https://github.com/OriginTrail/frontier?branch=polkadot-v0.9.27#1eba12c48e28ba334c53ea90d837e0a1f64cd95e" +dependencies = [ + "ethereum", + "ethereum-types", + "evm 0.35.0 (git+https://github.com/rust-blockchain/evm?rev=01bcbd2205a212c34451d3b4fabc962793b057d3)", + "fp-consensus", + "fp-ethereum", + "fp-evm", + "fp-rpc", + "fp-self-contained", + "fp-storage", + "frame-support", + "frame-system", + "pallet-evm", + "pallet-timestamp", + "parity-scale-codec", + "rlp", + "scale-info", + "serde", + "sp-io", + "sp-runtime", + "sp-std", +] + +[[package]] +name = "pallet-evm" +version = "6.0.0-dev" +source = "git+https://github.com/OriginTrail/frontier?branch=polkadot-v0.9.27#1eba12c48e28ba334c53ea90d837e0a1f64cd95e" +dependencies = [ + "evm 0.35.0 (git+https://github.com/rust-blockchain/evm?rev=01bcbd2205a212c34451d3b4fabc962793b057d3)", + "fp-evm", + "frame-benchmarking", + "frame-support", + "frame-system", + "hex", + "log", + "pallet-timestamp", + "parity-scale-codec", + "primitive-types", + "rlp", + "scale-info", + "serde", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", +] + +[[package]] +name = "pallet-evm-accounts" +version = "1.0.0" +dependencies = [ + "frame-support", + "frame-system", + "impl-trait-for-tuples 0.1.3", + "libsecp256k1", + "pallet-balances", + "pallet-evm", + "pallet-evm-utility-macro", + "parity-scale-codec", + "scale-info", + "serde", + "sha3 0.9.1", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", +] + +[[package]] +name = "pallet-evm-precompile-modexp" +version = "2.0.0-dev" +source = "git+https://github.com/OriginTrail/frontier?branch=polkadot-v0.9.27#1eba12c48e28ba334c53ea90d837e0a1f64cd95e" +dependencies = [ + "fp-evm", + "num", +] + +[[package]] +name = "pallet-evm-precompile-sha3fips" +version = "2.0.0-dev" +source = "git+https://github.com/OriginTrail/frontier?branch=polkadot-v0.9.27#1eba12c48e28ba334c53ea90d837e0a1f64cd95e" +dependencies = [ + "fp-evm", + "tiny-keccak", +] + +[[package]] +name = "pallet-evm-precompile-simple" +version = "2.0.0-dev" +source = "git+https://github.com/OriginTrail/frontier?branch=polkadot-v0.9.27#1eba12c48e28ba334c53ea90d837e0a1f64cd95e" +dependencies = [ + "fp-evm", + "ripemd", + "sp-io", +] + +[[package]] +name = "pallet-evm-utility" +version = "1.0.0" +dependencies = [ + "ethereum", + "evm 0.35.0 (git+https://github.com/rust-blockchain/evm?rev=0b686f8c2c83a52638917caa649dc23302fda80d)", + "evm-gasometer 0.35.0 (git+https://github.com/rust-blockchain/evm?rev=0b686f8c2c83a52638917caa649dc23302fda80d)", + "evm-runtime 0.35.0 (git+https://github.com/rust-blockchain/evm?rev=0b686f8c2c83a52638917caa649dc23302fda80d)", + "sha3 0.9.1", + "sp-std", +] + +[[package]] +name = "pallet-evm-utility-macro" +version = "1.0.0" +dependencies = [ + "pallet-evm-utility", + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "pallet-gilt" version = "4.0.0-dev" @@ -5563,7 +6099,7 @@ source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.27#8e dependencies = [ "frame-support", "frame-system", - "impl-trait-for-tuples", + "impl-trait-for-tuples 0.2.2", "log", "pallet-timestamp", "parity-scale-codec", @@ -5766,7 +6302,7 @@ dependencies = [ "frame-benchmarking", "frame-support", "frame-system", - "impl-trait-for-tuples", + "impl-trait-for-tuples 0.2.2", "pallet-balances", "parity-scale-codec", "scale-info", @@ -5856,9 +6392,9 @@ dependencies = [ [[package]] name = "parity-db" -version = "0.3.16" +version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bb474d0ed0836e185cb998a6b140ed1073d1fbf27d690ecf9ede8030289382c" +checksum = "2c8fdb726a43661fa54b43e7114e6b88b2289cae388eb3ad766d9d1754d83fce" dependencies = [ "blake2-rfc", "crc32fast", @@ -5867,8 +6403,8 @@ dependencies = [ "libc", "log", "lz4", - "memmap2 0.2.3", - "parking_lot 0.11.2", + "memmap2", + "parking_lot 0.12.1", "rand 0.8.5", "snap", ] @@ -5882,7 +6418,7 @@ dependencies = [ "arrayvec 0.7.2", "bitvec", "byte-slice-cast", - "impl-trait-for-tuples", + "impl-trait-for-tuples 0.2.2", "parity-scale-codec-derive", "serde", ] @@ -5912,8 +6448,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c32561d248d352148124f036cac253a644685a21dc9fea383eb4907d7bd35a8f" dependencies = [ "cfg-if 1.0.0", + "ethereum-types", "hashbrown 0.12.3", - "impl-trait-for-tuples", + "impl-trait-for-tuples 0.2.2", + "lru 0.7.8", "parity-util-mem-derive", "parking_lot 0.12.1", "primitive-types", @@ -6003,9 +6541,9 @@ dependencies = [ [[package]] name = "paste" -version = "1.0.8" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9423e2b32f7a043629287a536f21951e8c6a82482d0acb1eeebfc90bc2225b22" +checksum = "b1de2e551fb905ac83f73f7aedf2f0cb4a0da7e35efa24a202a936269f1f18e1" [[package]] name = "pbkdf2" @@ -7022,7 +7560,7 @@ dependencies = [ "frame-election-provider-support", "frame-support", "frame-system", - "impl-trait-for-tuples", + "impl-trait-for-tuples 0.2.2", "libsecp256k1", "log", "pallet-authorship", @@ -7310,6 +7848,7 @@ checksum = "e28720988bff275df1f51b171e1b2a18c30d194c4d2b61defdacecd625a5d94a" dependencies = [ "fixed-hash", "impl-codec", + "impl-rlp", "impl-serde", "scale-info", "uint", @@ -7821,6 +8360,36 @@ dependencies = [ "winapi", ] +[[package]] +name = "ripemd" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1facec54cb5e0dc08553501fa740091086d0259ad0067e0d4103448e4cb22ed3" +dependencies = [ + "digest 0.10.3", +] + +[[package]] +name = "rlp" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "999508abb0ae792aabed2460c45b89106d97fe4adac593bdaef433c2605847b5" +dependencies = [ + "bytes", + "rustc-hex", +] + +[[package]] +name = "rlp-derive" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e33d7b2abe0c340d8797fe2907d3f20d3b5ea5908683618bfe80df7f621f672a" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "rocksdb" version = "0.18.0" @@ -8148,8 +8717,8 @@ name = "sc-chain-spec" version = "4.0.0-dev" source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.27#8eff668a42325aeb4433eace1604f4d286a6ec05" dependencies = [ - "impl-trait-for-tuples", - "memmap2 0.5.7", + "impl-trait-for-tuples 0.2.2", + "memmap2", "parity-scale-codec", "sc-chain-spec-derive", "sc-network", @@ -8326,7 +8895,7 @@ dependencies = [ "futures", "log", "merlin", - "num-bigint", + "num-bigint 0.2.6", "num-rational 0.2.4", "num-traits", "parity-scale-codec", @@ -9329,9 +9898,9 @@ dependencies = [ [[package]] name = "sha2" -version = "0.10.2" +version = "0.10.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55deaec60f81eefe3cce0dc50bda92d6d8e88f2a27df7c5033b42afeb1ed2676" +checksum = "cf9db03534dff993187064c4e0c05a5708d2a9728ace9a8959b77bedf415dac5" dependencies = [ "cfg-if 1.0.0", "cpufeatures", @@ -9352,9 +9921,9 @@ dependencies = [ [[package]] name = "sha3" -version = "0.10.2" +version = "0.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a31480366ec990f395a61b7c08122d99bd40544fdb5abcfc1b06bb29994312c" +checksum = "eaedf34ed289ea47c2b741bb72e5357a209512d67bcd4bda44359e5bf0470f56" dependencies = [ "digest 0.10.3", "keccak", @@ -9477,15 +10046,15 @@ dependencies = [ "rand_core 0.6.3", "ring", "rustc_version", - "sha2 0.10.2", + "sha2 0.10.5", "subtle", ] [[package]] name = "socket2" -version = "0.4.4" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "66d72b759436ae32898a2af0a14218dbf55efde3feeb170eb623637db85ee1e0" +checksum = "02e2d2db9033d13a1567121ddd7a095ee144db4e1ca1b1bda3419bc0da294ebd" dependencies = [ "libc", "winapi", @@ -9760,8 +10329,8 @@ dependencies = [ "blake2", "byteorder", "digest 0.10.3", - "sha2 0.10.2", - "sha3 0.10.2", + "sha2 0.10.5", + "sha3 0.10.4", "sp-std", "twox-hash", ] @@ -9831,7 +10400,7 @@ version = "4.0.0-dev" source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.27#8eff668a42325aeb4433eace1604f4d286a6ec05" dependencies = [ "async-trait", - "impl-trait-for-tuples", + "impl-trait-for-tuples 0.2.2", "parity-scale-codec", "sp-core", "sp-runtime", @@ -9967,7 +10536,7 @@ source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.27#8e dependencies = [ "either", "hash256-std-hasher", - "impl-trait-for-tuples", + "impl-trait-for-tuples 0.2.2", "log", "parity-scale-codec", "parity-util-mem", @@ -9987,7 +10556,7 @@ name = "sp-runtime-interface" version = "6.0.0" source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.27#8eff668a42325aeb4433eace1604f4d286a6ec05" dependencies = [ - "impl-trait-for-tuples", + "impl-trait-for-tuples 0.2.2", "parity-scale-codec", "primitive-types", "sp-externalities", @@ -10214,7 +10783,7 @@ name = "sp-wasm-interface" version = "6.0.0" source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.27#8eff668a42325aeb4433eace1604f4d286a6ec05" dependencies = [ - "impl-trait-for-tuples", + "impl-trait-for-tuples 0.2.2", "log", "parity-scale-codec", "sp-std", @@ -10230,9 +10799,9 @@ checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" [[package]] name = "ss58-registry" -version = "1.27.0" +version = "1.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d04c6bfb58842576a5ea01b2ba9852d3d74d212d2ad5403f2789017f7db7848" +checksum = "1c8a1e645fa0bd3e81a90e592a677f7ada3182ac338c4a71cd9ec0ba911f6abb" dependencies = [ "Inflector", "num-format", @@ -10507,18 +11076,18 @@ checksum = "b1141d4d61095b28419e22cb0bbf02755f5e54e0526f97f1e3d1d160e60885fb" [[package]] name = "thiserror" -version = "1.0.32" +version = "1.0.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5f6586b7f764adc0231f4c79be7b920e766bb2f3e51b3661cdb263828f19994" +checksum = "8c1b05ca9d106ba7d2e31a9dab4a64e7be2cce415321966ea3132c49a656e252" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.32" +version = "1.0.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12bafc5b54507e0149cdf1b145a5d80ab80a90bcd9275df43d4fff68460f6c21" +checksum = "e8f2591983642de85c921015f3f070c665a197ed69e417af436115e3a1407487" dependencies = [ "proc-macro2", "quote", @@ -10603,6 +11172,15 @@ dependencies = [ "zeroize", ] +[[package]] +name = "tiny-keccak" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237" +dependencies = [ + "crunchy", +] + [[package]] name = "tinyvec" version = "1.6.0" @@ -10620,9 +11198,9 @@ checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" [[package]] name = "tokio" -version = "1.20.1" +version = "1.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a8325f63a7d4774dd041e363b2409ed1c5cbbd0f867795e661df066b2b0a581" +checksum = "89797afd69d206ccd11fb0ea560a44bbb87731d020670e79416d442919257d42" dependencies = [ "autocfg", "bytes", @@ -10834,6 +11412,16 @@ dependencies = [ "hash-db", ] +[[package]] +name = "triehash" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1631b201eb031b563d2e85ca18ec8092508e262a3196ce9bd10a67ec87b9f5c" +dependencies = [ + "hash-db", + "rlp", +] + [[package]] name = "trust-dns-proto" version = "0.21.2" @@ -10934,9 +11522,9 @@ checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987" [[package]] name = "ucd-trie" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89570599c4fe5585de2b388aab47e99f7fa4e9238a1399f707a02e356058141c" +checksum = "9e79c4d996edb816c91e4308506774452e55e95c3c9de07b6729e17e15a5ef81" [[package]] name = "uint" @@ -11555,13 +12143,13 @@ dependencies = [ [[package]] name = "which" -version = "4.2.5" +version = "4.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c4fb54e6113b6a8772ee41c3404fb0301ac79604489467e0a9ce1f3e97c24ae" +checksum = "1c831fbbee9e129a8cf93e7747a82da9d95ba8e16621cae60ec2cdc849bacb7b" dependencies = [ "either", - "lazy_static", "libc", + "once_cell", ] [[package]] @@ -11722,7 +12310,7 @@ version = "0.9.27" source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.27#b017bad50d360a1c6e3cdf9652bdb85e5f479fea" dependencies = [ "derivative", - "impl-trait-for-tuples", + "impl-trait-for-tuples 0.2.2", "log", "parity-scale-codec", "scale-info", @@ -11757,7 +12345,7 @@ source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.27#b017 dependencies = [ "frame-benchmarking", "frame-support", - "impl-trait-for-tuples", + "impl-trait-for-tuples 0.2.2", "log", "parity-scale-codec", "sp-arithmetic", diff --git a/node/Cargo.toml b/node/Cargo.toml index ed20c27..3adec7c 100644 --- a/node/Cargo.toml +++ b/node/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "origintrail-parachain-node" -version = "1.0.3" +version = "1.0.4" authors = ["TraceLabs"] description = "OriginTrail Parachain - Cumulus FRAME-based Substrate Node" license = "GPL-3.0-only" @@ -16,6 +16,7 @@ path = "src/main.rs" [dependencies] clap = { version = "3.2.15", features = ["derive"] } derive_more = "0.99.2" +futures = "0.3" log = "0.4.17" codec = { package = "parity-scale-codec", version = "3.0.0" } serde = { version = "1.0.140", features = ["derive"] } @@ -88,6 +89,14 @@ cumulus-relay-chain-inprocess-interface = { git = "https://github.com/paritytech cumulus-relay-chain-interface = { git = "https://github.com/paritytech/cumulus", branch = "polkadot-v0.9.27" } cumulus-relay-chain-rpc-interface = { git = "https://github.com/paritytech/cumulus", branch = "polkadot-v0.9.27" } +# Frontier +fp-evm = { git = "https://github.com/OriginTrail/frontier", branch = "polkadot-v0.9.27" } +fp-rpc = { git = "https://github.com/OriginTrail/frontier", branch = "polkadot-v0.9.27" } +fc-db = { git = "https://github.com/OriginTrail/frontier", branch = "polkadot-v0.9.27" } +fc-rpc = { git = "https://github.com/OriginTrail/frontier", branch = "polkadot-v0.9.27" } +fc-rpc-core = { git = "https://github.com/OriginTrail/frontier", branch = "polkadot-v0.9.27" } +fc-mapping-sync = { git = "https://github.com/OriginTrail/frontier", branch = "polkadot-v0.9.27" } + [build-dependencies] substrate-build-script-utils = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" } diff --git a/node/src/chain_spec.rs b/node/src/chain_spec.rs index 7043ce1..633f568 100644 --- a/node/src/chain_spec.rs +++ b/node/src/chain_spec.rs @@ -1,10 +1,12 @@ use cumulus_primitives_core::ParaId; -use origintrail_parachain_runtime::{AccountId, AuraId, Signature, SudoConfig, EXISTENTIAL_DEPOSIT}; +use origintrail_parachain_runtime::{AccountId, AuraId, + EVMConfig, EthereumConfig, Signature, SudoConfig, EXISTENTIAL_DEPOSIT}; use sc_chain_spec::{ChainSpecExtension, ChainSpecGroup}; use sc_service::ChainType; use serde::{Deserialize, Serialize}; -use sp_core::{sr25519, Pair, Public}; +use sp_core::{sr25519, Pair, Public, H160, U256}; use sp_runtime::traits::{IdentifyAccount, Verify}; +use std::{collections::BTreeMap, str::FromStr}; /// Specialized `ChainSpec` for the normal parachain runtime. pub type ChainSpec = @@ -224,5 +226,41 @@ fn testnet_genesis( }, vesting: Default::default(), treasury: Default::default(), + evm: EVMConfig { + accounts: { + let mut map = BTreeMap::new(); + map.insert( + // H160 address of Alice dev account + // Derived from SS58 (42 prefix) address + // SS58: 5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY + // hex: 0xd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d + // Using the full hex key, truncating to the first 20 bytes (the first 40 hex chars) + H160::from_str("d43593c715fdd31c61141abd04a99fd6822c8558") + .expect("internal H160 is valid; qed"), + fp_evm::GenesisAccount { + balance: U256::from_str("0xffffffffffffffffffffffffffffffff") + .expect("internal U256 is valid; qed"), + code: Default::default(), + nonce: Default::default(), + storage: Default::default(), + }, + ); + map.insert( + // H160 address of CI test runner account + H160::from_str("6be02d1d3665660d22ff9624b7be0551ee1ac91b") + .expect("internal H160 is valid; qed"), + fp_evm::GenesisAccount { + balance: U256::from_str("0xffffffffffffffffffffffffffffffff") + .expect("internal U256 is valid; qed"), + code: Default::default(), + nonce: Default::default(), + storage: Default::default(), + }, + ); + map + }, + }, + ethereum: EthereumConfig {}, + base_fee: Default::default(), } } diff --git a/node/src/rpc.rs b/node/src/rpc.rs index 342bfdc..486bacc 100644 --- a/node/src/rpc.rs +++ b/node/src/rpc.rs @@ -7,33 +7,61 @@ use std::sync::Arc; -use origintrail_parachain_runtime::{opaque::Block, AccountId, Balance, Index as Nonce}; +use origintrail_parachain_runtime::{opaque::Block, AccountId, Balance, Hash, Index as Nonce}; -use sc_client_api::AuxStore; +use sc_client_api::{ + backend::{AuxStore, Backend, StateBackend, StorageProvider}, +}; pub use sc_rpc::{DenyUnsafe, SubscriptionTaskExecutor}; +use fc_rpc::{ + EthBlockDataCacheTask, OverrideHandle, +}; +use sp_runtime::traits::BlakeTwo256; +use fc_rpc_core::types::{FeeHistoryCache}; +use sc_transaction_pool::{ChainApi, Pool}; use sc_transaction_pool_api::TransactionPool; use sp_api::ProvideRuntimeApi; use sp_block_builder::BlockBuilder; use sp_blockchain::{Error as BlockChainError, HeaderBackend, HeaderMetadata}; +use sc_network::NetworkService; /// A type representing all RPC extensions. pub type RpcExtension = jsonrpsee::RpcModule<()>; /// Full client dependencies -pub struct FullDeps { +pub struct FullDeps { /// The client instance to use. pub client: Arc, /// Transaction pool instance. pub pool: Arc

, + /// Graph pool instance. + pub graph: Arc>, /// Whether to deny unsafe calls pub deny_unsafe: DenyUnsafe, + /// The Node authority flag + pub is_authority: bool, + /// Network service + pub network: Arc>, + /// Backend. + pub backend: Arc>, + /// Maximum fee history cache size. + pub fee_history_cache_limit: u64, + /// Fee history cache. + pub fee_history_cache: FeeHistoryCache, + /// Ethereum data access overrides. + pub overrides: Arc>, + /// Cache for Ethereum block data. + pub block_data_cache: Arc>, } /// Instantiate all RPC extensions. -pub fn create_full( - deps: FullDeps, +pub fn create_full( + deps: FullDeps, + _subscription_task_executor: SubscriptionTaskExecutor, ) -> Result> where + BE: Backend + 'static, + BE::State: StateBackend, C: ProvideRuntimeApi + HeaderBackend + AuxStore @@ -41,19 +69,56 @@ where + Send + Sync + 'static, + C: StorageProvider, C::Api: pallet_transaction_payment_rpc::TransactionPaymentRuntimeApi, C::Api: substrate_frame_rpc_system::AccountNonceApi, C::Api: BlockBuilder, + C::Api: fp_rpc::EthereumRuntimeRPCApi, + C::Api: fp_rpc::ConvertTransactionRuntimeApi, + P: TransactionPool + Sync + Send + 'static, P: TransactionPool + Sync + Send + 'static, + A: ChainApi + 'static, { use pallet_transaction_payment_rpc::{TransactionPayment, TransactionPaymentApiServer}; use substrate_frame_rpc_system::{System, SystemApiServer}; + use fc_rpc::{Eth, EthApiServer, Net, NetApiServer}; let mut module = RpcExtension::new(()); - let FullDeps { client, pool, deny_unsafe } = deps; + let FullDeps { client, pool, graph, deny_unsafe, network, backend, is_authority, fee_history_cache, + fee_history_cache_limit, overrides, block_data_cache + } = deps; - module.merge(System::new(client.clone(), pool, deny_unsafe).into_rpc())?; - module.merge(TransactionPayment::new(client).into_rpc())?; + module.merge(System::new(client.clone(), pool.clone(), deny_unsafe).into_rpc())?; + module.merge(TransactionPayment::new(client.clone()).into_rpc())?; + + let signers = Vec::new(); + + module.merge( + Eth::<_, _, _, fp_rpc::NoTransactionConverter, _, _, _>::new( + client.clone(), + pool.clone(), + graph, + None, + network.clone(), + signers, + overrides.clone(), + backend.clone(), + is_authority, + block_data_cache.clone(), + fee_history_cache, + fee_history_cache_limit, + ).into_rpc() + )?; + + module.merge( + Net::new( + client.clone(), + network.clone(), + // Whether to format the `peer_count` response as Hex (default) or not. + true, + ) + .into_rpc(), + )?; Ok(module) } diff --git a/node/src/service.rs b/node/src/service.rs index b0c2d0d..6622323 100644 --- a/node/src/service.rs +++ b/node/src/service.rs @@ -1,7 +1,7 @@ //! Service and ServiceFactory implementation. Specialized wrapper over substrate service. // std -use std::{sync::Arc, time::Duration}; +use std::{sync::Arc, path::PathBuf, time::Duration, collections::BTreeMap}; // rpc use jsonrpsee::RpcModule; @@ -25,15 +25,23 @@ use cumulus_relay_chain_interface::{RelayChainError, RelayChainInterface, RelayC use cumulus_relay_chain_rpc_interface::RelayChainRPCInterface; // Substrate Imports -use sc_client_api::ExecutorProvider; +use sc_client_api::{BlockchainEvents, ExecutorProvider}; use sc_executor::NativeElseWasmExecutor; use sc_network::NetworkService; -use sc_service::{Configuration, PartialComponents, TFullBackend, TFullClient, TaskManager}; +use sc_service::{BasePath, Configuration, PartialComponents, TFullBackend, TFullClient, TaskManager}; use sc_telemetry::{Telemetry, TelemetryHandle, TelemetryWorker, TelemetryWorkerHandle}; use sp_api::ConstructRuntimeApi; use sp_keystore::SyncCryptoStorePtr; use sp_runtime::traits::BlakeTwo256; use substrate_prometheus_endpoint::Registry; +use futures::StreamExt; +use sc_cli::SubstrateCli; +use fc_rpc_core::types::{FeeHistoryCache}; +use fc_rpc::{ + OverrideHandle, RuntimeApiStorageOverride, +}; + +use crate::cli::Cli; use polkadot_service::CollatorPair; @@ -52,6 +60,17 @@ impl sc_executor::NativeExecutionDispatch for TemplateRuntimeExecutor { } } +pub(crate) fn db_config_dir(config: &Configuration) -> PathBuf { + config + .base_path + .as_ref() + .map(|base_path| base_path.config_dir(config.chain_spec.id())) + .unwrap_or_else(|| { + BasePath::from_project("", "", &Cli::executable_name()) + .config_dir(config.chain_spec.id()) + }) +} + /// Starts a `ServiceBuilder` for a full service. /// /// Use this macro if you don't actually need the full service, but just the builder in order to @@ -73,7 +92,11 @@ pub fn new_partial( Block, TFullClient>, >, - (Option, Option), + ( + Option, + Option, + Arc>, + ), >, sc_service::Error, > @@ -89,7 +112,8 @@ where Block, StateBackend = sc_client_api::StateBackendFor, Block>, > + sp_offchain::OffchainWorkerApi - + sp_block_builder::BlockBuilder, + + sp_block_builder::BlockBuilder + + fp_rpc::EthereumRuntimeRPCApi, sc_client_api::StateBackendFor, Block>: sp_api::StateBackend, Executor: sc_executor::NativeExecutionDispatch + 'static, BIQ: FnOnce( @@ -146,6 +170,11 @@ where client.clone(), ); + let frontier_backend = Arc::new(fc_db::Backend::open( + &config.database, + &db_config_dir(config), + )?); + let import_queue = build_import_queue( client.clone(), config, @@ -161,7 +190,7 @@ where task_manager, transaction_pool, select_chain: (), - other: (telemetry, telemetry_worker_handle), + other: (telemetry, telemetry_worker_handle, frontier_backend), }; Ok(params) @@ -219,6 +248,8 @@ where > + sp_offchain::OffchainWorkerApi + sp_block_builder::BlockBuilder + cumulus_primitives_core::CollectCollationInfo + + fp_rpc::EthereumRuntimeRPCApi + + fp_rpc::ConvertTransactionRuntimeApi + pallet_transaction_payment_rpc::TransactionPaymentRuntimeApi + substrate_frame_rpc_system::AccountNonceApi, sc_client_api::StateBackendFor, Block>: sp_api::StateBackend, @@ -261,7 +292,7 @@ where let parachain_config = prepare_node_config(parachain_config); let params = new_partial::(¶chain_config, build_import_queue)?; - let (mut telemetry, telemetry_worker_handle) = params.other; + let (mut telemetry, telemetry_worker_handle, frontier_backend) = params.other; let client = params.client.clone(); let backend = params.backend.clone(); @@ -286,6 +317,7 @@ where let force_authoring = parachain_config.force_authoring; let validator = parachain_config.role.is_authority(); let prometheus_registry = parachain_config.prometheus_registry().cloned(); + let is_authority = parachain_config.role.is_authority(); let transaction_pool = params.transaction_pool.clone(); let import_queue = cumulus_client_service::SharedImportQueue::new(params.import_queue); let (network, system_rpc_tx, start_network) = @@ -299,20 +331,75 @@ where Box::new(block_announce_validator) })), warp_sync: None, - })?; + } + )?; + let fee_history_cache: FeeHistoryCache = Arc::new(std::sync::Mutex::new(BTreeMap::new())); + + // Frontier offchain DB task. Essential. + // Maps emulated ethereum data to substrate native data. + task_manager.spawn_essential_handle().spawn( + "frontier-mapping-sync-worker", + Some("frontier"), + fc_mapping_sync::MappingSyncWorker::new( + client.import_notification_stream(), + Duration::new(6, 0), + client.clone(), + backend.clone(), + frontier_backend.clone(), + 3, + 0, + fc_mapping_sync::SyncStrategy::Parachain, + ) + .for_each(|()| futures::future::ready(())), + ); + + let overrides = Arc::new(OverrideHandle { + schemas: BTreeMap::new(), + fallback: Box::new(RuntimeApiStorageOverride::new(client.clone())), + }); + + const FEE_HISTORY_LIMIT: u64 = 2048; + task_manager.spawn_essential_handle().spawn( + "frontier-fee-history", + Some("frontier"), + fc_rpc::EthTask::fee_history_task( + client.clone(), + overrides.clone(), + fee_history_cache.clone(), + FEE_HISTORY_LIMIT, + ), + ); + + let block_data_cache = Arc::new(fc_rpc::EthBlockDataCacheTask::new( + task_manager.spawn_handle(), + overrides.clone(), + 50, + 50, + prometheus_registry.clone(), + )); let rpc_builder = { let client = client.clone(); let transaction_pool = transaction_pool.clone(); + let network = network.clone(); + let frontier_backend = frontier_backend.clone(); - Box::new(move |deny_unsafe, _| { + Box::new(move |deny_unsafe, subscription_task_executor| { let deps = crate::rpc::FullDeps { client: client.clone(), pool: transaction_pool.clone(), + graph: transaction_pool.pool().clone(), deny_unsafe, + is_authority, + network: network.clone(), + backend: frontier_backend.clone(), + fee_history_cache_limit: FEE_HISTORY_LIMIT, + fee_history_cache: fee_history_cache.clone(), + overrides: overrides.clone(), + block_data_cache: block_data_cache.clone(), }; - crate::rpc::create_full(deps).map_err(Into::into) + crate::rpc::create_full(deps, subscription_task_executor).map_err(Into::into) }) }; diff --git a/pallets/evm-accounts/Cargo.toml b/pallets/evm-accounts/Cargo.toml new file mode 100644 index 0000000..01c4ebc --- /dev/null +++ b/pallets/evm-accounts/Cargo.toml @@ -0,0 +1,53 @@ +[package] +name = "pallet-evm-accounts" +version = "1.0.0" +authors = ["TraceLabs"] +edition = "2021" + +[dependencies] +serde = { version = "1.0.136", optional = true } +codec = { package = "parity-scale-codec", version = "3.0.0", default-features = false } +libsecp256k1 = { version = "0.7", default-features = false, features = [ + "hmac", + "static-context", +], optional = true } +scale-info = { version = "2.1", default-features = false, features = [ + "derive", +] } +sha3 = { version = "0.9.1", default-features = false } + +frame-support = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27", default-features = false } +frame-system = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27", default-features = false } +sp-core = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27", default-features = false } +sp-io = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27", default-features = false } +sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27", default-features = false } +sp-std = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27", default-features = false } +pallet-evm = { default-features = false, git = "https://github.com/OriginTrail/frontier.git", branch = "polkadot-v0.9.27" } +impl-trait-for-tuples = "0.1.3" +pallet-evm-utility-macro = { path = "../evm-utility/macro" } + +[dev-dependencies] +pallet-balances = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" } + +[features] +default = ["std"] +std = [ + "serde", + "codec/std", + "libsecp256k1", + "libsecp256k1/std", + "scale-info/std", + "sp-core/std", + "sp-runtime/std", + "sp-io/std", + "sp-std/std", + "frame-support/std", + "frame-system/std", + "pallet-evm/std", +] +runtime-benchmarks = [ + "libsecp256k1", + "frame-support/runtime-benchmarks", + "frame-system/runtime-benchmarks", +] +try-runtime = ["frame-support/try-runtime"] diff --git a/pallets/evm-accounts/README.md b/pallets/evm-accounts/README.md new file mode 100644 index 0000000..5a64612 --- /dev/null +++ b/pallets/evm-accounts/README.md @@ -0,0 +1 @@ +License: Unlicense diff --git a/pallets/evm-accounts/src/lib.rs b/pallets/evm-accounts/src/lib.rs new file mode 100644 index 0000000..167fe58 --- /dev/null +++ b/pallets/evm-accounts/src/lib.rs @@ -0,0 +1,469 @@ +// This program 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. + +// This program 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 this program. If not, see . + +//! # Evm Accounts pallet +//! +//! ## Overview +//! +//! Evm Accounts pallet provide a two way mapping between Substrate accounts and +//! EVM accounts so user only have deal with one account / private key. + +#![cfg_attr(not(feature = "std"), no_std)] +#![allow(clippy::unused_unit)] + +use codec::Encode; +use frame_support::{ + ensure, + pallet_prelude::*, + traits::{Currency, IsType, OnKilledAccount}, + transactional, + storage::{with_transaction, TransactionOutcome}, +}; +use frame_system::{ensure_signed, pallet_prelude::*}; +use pallet_evm_utility_macro::keccak256; +use pallet_evm::{AddressMapping as EvmPalletAddressMappingTrait}; + +use sp_core::crypto::AccountId32; +use sp_core::{H160, H256, U256}; +use sp_io::{ + crypto::secp256k1_ecdsa_recover, + hashing::{blake2_256, keccak_256}, +}; +use sp_runtime::{ + traits::{LookupError, StaticLookup, Zero}, + MultiAddress, +}; +use sp_std::{marker::PhantomData, vec::Vec}; +use impl_trait_for_tuples::impl_for_tuples; + +pub use pallet::*; + +mod mock; +mod tests; +pub mod weights; + +pub use weights::WeightInfo; + +/// The type for looking up accounts. We don't expect more than 4 billion of +/// them. +pub type AccountIndex = u32; + +/// A signature (a 512-bit value, plus 8 bits for recovery ID). +pub type Eip712Signature = [u8; 65]; + +/// Evm Address. +pub type EvmAddress = sp_core::H160; + +/// A mapping between `AccountId` and `EvmAddress`. +pub trait AddressMapping { + /// Returns the AccountId used go generate the given EvmAddress. + fn get_account_id(evm: &EvmAddress) -> AccountId32; + /// Returns the EvmAddress associated with a given AccountId or the + /// underlying EvmAddress of the AccountId. + /// Returns None if there is no EvmAddress associated with the AccountId + /// and there is no underlying EvmAddress in the AccountId. + fn get_evm_address(account_id: &AccountId32) -> Option; + /// Returns the EVM address associated with an account ID and generates an + /// account mapping if no association exists. + fn get_or_create_evm_address(account_id: &AccountId32) -> EvmAddress; + /// Returns the default EVM address associated with an account ID. + fn get_default_evm_address(account_id: &AccountId32) -> EvmAddress; + /// Returns true if a given AccountId is associated with a given EvmAddress + /// and false if is not. + fn is_linked(account_id: &AccountId32, evm: &EvmAddress) -> bool; +} + +pub trait EVMAccountsManager { + /// Returns the AccountId used to generate the given EvmAddress. + fn get_account_id(address: &EvmAddress) -> AccountId; + /// Returns the EvmAddress associated with a given AccountId or the underlying EvmAddress of the + /// AccountId. + fn get_evm_address(account_id: &AccountId) -> Option; + /// Claim account mapping between AccountId and a generated EvmAddress based off of the + /// AccountId. + fn claim_default_evm_address(account_id: &AccountId) -> Result; +} + +/// Convert any type that implements Into into byte representation ([u8, 32]) +pub fn to_bytes>(value: T) -> [u8; 32] { + Into::<[u8; 32]>::into(value.into()) +} + +pub fn with_transaction_result( + f: impl FnOnce() -> Result, +) -> Result { + with_transaction(|| { + let res = f(); + if res.is_ok() { + TransactionOutcome::Commit(res) + } else { + TransactionOutcome::Rollback(res) + } + }) +} + +pub trait MergeAccount { + fn merge_account(source: &AccountId, dest: &AccountId) -> DispatchResult; +} + +#[impl_for_tuples(5)] +impl MergeAccount for Tuple { + fn merge_account(source: &AccountId, dest: &AccountId) -> DispatchResult { + with_transaction_result(|| { + for_tuples!( #( { + Tuple::merge_account(source, dest)?; + } )* ); + Ok(()) + }) + } +} + +#[frame_support::pallet] +pub mod pallet { + use super::*; + + #[pallet::config] + pub trait Config: frame_system::Config { + type Event: From> + IsType<::Event>; + + /// The Currency for managing Evm account assets. + type Currency: Currency; + + /// Mapping from address to account id. + type AddressMapping: AddressMapping; + + /// Chain ID of EVM. + #[pallet::constant] + type ChainId: Get; + + /// Merge free balance from source to dest. + type MergeAccount: MergeAccount; + + /// Weight information for the extrinsics in this pallet. + type WeightInfo: WeightInfo; + } + + #[pallet::event] + #[pallet::generate_deposit(pub(crate) fn deposit_event)] + pub enum Event { + /// Mapping between Substrate accounts and EVM accounts + /// claim account. + ClaimAccount { + account_id: T::AccountId, + evm_address: EvmAddress, + }, + } + + /// Error for evm accounts pallet. + #[pallet::error] + pub enum Error { + /// AccountId has mapped + AccountIdHasMapped, + /// Eth address has mapped + EthAddressHasMapped, + /// Bad signature + BadSignature, + /// Invalid signature + InvalidSignature, + /// Account ref count is not zero + NonZeroRefCount, + } + + /// The Substrate Account for EvmAddresses + /// + /// Accounts: map EvmAddress => Option + #[pallet::storage] + #[pallet::getter(fn accounts)] + pub type Accounts = StorageMap<_, Twox64Concat, EvmAddress, T::AccountId, OptionQuery>; + + /// The EvmAddress for Substrate Accounts + /// + /// EvmAddresses: map AccountId => Option + #[pallet::storage] + #[pallet::getter(fn evm_addresses)] + pub type EvmAddresses = StorageMap<_, Twox64Concat, T::AccountId, EvmAddress, OptionQuery>; + + #[pallet::pallet] + pub struct Pallet(_); + + #[pallet::hooks] + impl Hooks for Pallet {} + + #[pallet::call] + impl Pallet { + /// Claim account mapping between Substrate accounts and EVM accounts. + /// Ensure eth_address has not been mapped. + /// + /// - `eth_address`: The address to bind to the caller's account + /// - `eth_signature`: A signature generated by the address to prove ownership + #[pallet::weight(T::WeightInfo::claim_account())] + #[transactional] + pub fn claim_account( + origin: OriginFor, + eth_address: EvmAddress, + eth_signature: Eip712Signature, + ) -> DispatchResult { + let who = ensure_signed(origin)?; + + // ensure account_id and eth_address has not been mapped + ensure!(!EvmAddresses::::contains_key(&who), Error::::AccountIdHasMapped); + ensure!( + !Accounts::::contains_key(eth_address), + Error::::EthAddressHasMapped + ); + + // recover evm address from signature + let address = Self::verify_eip712_signature(&who, ð_signature).ok_or(Error::::BadSignature)?; + ensure!(eth_address == address, Error::::InvalidSignature); + + // check if the evm padded address already exists + let account_id = T::AddressMapping::get_account_id(ð_address); + if frame_system::Pallet::::account_exists(&account_id) { + // merge balance from `evm padded address` to `origin` + T::MergeAccount::merge_account(&account_id, &who)?; + } + + Accounts::::insert(eth_address, &who); + EvmAddresses::::insert(&who, eth_address); + + Self::deposit_event(Event::ClaimAccount { + account_id: who, + evm_address: eth_address, + }); + + Ok(()) + } + + /// Claim account mapping between Substrate accounts and a generated EVM + /// address based off of those accounts. + /// Ensure eth_address has not been mapped + #[pallet::weight(T::WeightInfo::claim_default_account())] + pub fn claim_default_account(origin: OriginFor) -> DispatchResult { + let who = ensure_signed(origin)?; + let _ = Self::do_claim_default_evm_address(who)?; + Ok(()) + } + } +} + +impl Pallet { + #[cfg(any(feature = "runtime-benchmarks", feature = "std"))] + // Returns an Etherum public key derived from an Ethereum secret key. + pub fn eth_public(secret: &libsecp256k1::SecretKey) -> libsecp256k1::PublicKey { + libsecp256k1::PublicKey::from_secret_key(secret) + } + + #[cfg(any(feature = "runtime-benchmarks", feature = "std"))] + // Returns an Etherum address derived from an Ethereum secret key. + // Only for tests + pub fn eth_address(secret: &libsecp256k1::SecretKey) -> EvmAddress { + EvmAddress::from_slice(&keccak_256(&Self::eth_public(secret).serialize()[1..65])[12..]) + } + + #[cfg(any(feature = "runtime-benchmarks", feature = "std"))] + // Constructs a message and signs it. + pub fn eth_sign(secret: &libsecp256k1::SecretKey, who: &T::AccountId) -> Eip712Signature { + let msg = keccak_256(&Self::eip712_signable_message(who)); + let (sig, recovery_id) = libsecp256k1::sign(&libsecp256k1::Message::parse(&msg), secret); + let mut r = [0u8; 65]; + r[0..64].copy_from_slice(&sig.serialize()[..]); + r[64] = recovery_id.serialize(); + r + } + + fn verify_eip712_signature(who: &T::AccountId, sig: &[u8; 65]) -> Option { + let msg = Self::eip712_signable_message(who); + let msg_hash = keccak_256(msg.as_slice()); + + recover_signer(sig, &msg_hash) + } + + // Eip-712 message to be signed + fn eip712_signable_message(who: &T::AccountId) -> Vec { + let domain_separator = Self::evm_account_domain_separator(); + let payload_hash = Self::evm_account_payload_hash(who); + + let mut msg = b"\x19\x01".to_vec(); + msg.extend_from_slice(&domain_separator); + msg.extend_from_slice(&payload_hash); + msg + } + + fn evm_account_payload_hash(who: &T::AccountId) -> [u8; 32] { + let tx_type_hash = keccak256!("Transaction(bytes substrateAddress)"); + let mut tx_msg = tx_type_hash.to_vec(); + tx_msg.extend_from_slice(&keccak_256(&who.encode())); + keccak_256(tx_msg.as_slice()) + } + + fn evm_account_domain_separator() -> [u8; 32] { + let domain_hash = keccak256!("EIP712Domain(string name,string version,uint256 chainId,bytes32 salt)"); + let mut domain_seperator_msg = domain_hash.to_vec(); + domain_seperator_msg.extend_from_slice(keccak256!("OTP EVM claim")); // name + domain_seperator_msg.extend_from_slice(keccak256!("1")); // version + domain_seperator_msg.extend_from_slice(&to_bytes(T::ChainId::get())); // chain id + domain_seperator_msg.extend_from_slice(frame_system::Pallet::::block_hash(T::BlockNumber::zero()).as_ref()); // genesis block hash + keccak_256(domain_seperator_msg.as_slice()) + } + + fn do_claim_default_evm_address(who: T::AccountId) -> Result { + // ensure account_id has not been mapped + ensure!(!EvmAddresses::::contains_key(&who), Error::::AccountIdHasMapped); + + let eth_address = T::AddressMapping::get_or_create_evm_address(&who); + + Ok(eth_address) + } +} + +fn recover_signer(sig: &[u8; 65], msg_hash: &[u8; 32]) -> Option { + secp256k1_ecdsa_recover(sig, msg_hash) + .map(|pubkey| H160::from(H256::from_slice(&keccak_256(&pubkey)))) + .ok() +} + +// Creates a an EvmAddress from an AccountId by appending the bytes "evm:" to +// the account_id and hashing it. +fn account_to_default_evm_address(account_id: &impl Encode) -> EvmAddress { + let payload = (b"evm:", account_id); + EvmAddress::from_slice(&payload.using_encoded(blake2_256)[0..20]) +} + +pub struct EvmAddressMapping(sp_std::marker::PhantomData); + +impl AddressMapping for EvmAddressMapping +where + T::AccountId: IsType, +{ + // Returns the AccountId used to generate the given EvmAddress. + fn get_account_id(address: &EvmAddress) -> T::AccountId { + if let Some(acc) = Accounts::::get(address) { + acc + } else { + let mut data: [u8; 32] = [0u8; 32]; + data[0..4].copy_from_slice(b"evm:"); + data[4..24].copy_from_slice(&address[..]); + AccountId32::from(data).into() + } + } + + // Returns the EvmAddress associated with a given AccountId or the + // underlying EvmAddress of the AccountId. + // Returns None if there is no EvmAddress associated with the AccountId + // and there is no underlying EvmAddress in the AccountId. + fn get_evm_address(account_id: &T::AccountId) -> Option { + // Return the EvmAddress if a mapping to account_id exists + EvmAddresses::::get(account_id).or_else(|| { + let data: &[u8] = account_id.into_ref().as_ref(); + // Return the underlying EVM address if it exists otherwise return None + if data.starts_with(b"evm:") { + Some(EvmAddress::from_slice(&data[4..24])) + } else { + None + } + }) + } + + // Returns the EVM address associated with an account ID and generates an + // account mapping if no association exists. + fn get_or_create_evm_address(account_id: &T::AccountId) -> EvmAddress { + Self::get_evm_address(account_id).unwrap_or_else(|| { + let addr = account_to_default_evm_address(account_id); + + // create reverse mapping + Accounts::::insert(&addr, &account_id); + EvmAddresses::::insert(&account_id, &addr); + + Pallet::::deposit_event(Event::ClaimAccount { + account_id: account_id.clone(), + evm_address: addr, + }); + + addr + }) + } + + // Returns the default EVM address associated with an account ID. + fn get_default_evm_address(account_id: &T::AccountId) -> EvmAddress { + account_to_default_evm_address(account_id) + } + + // Returns true if a given AccountId is associated with a given EvmAddress + // and false if is not. + fn is_linked(account_id: &T::AccountId, evm: &EvmAddress) -> bool { + Self::get_evm_address(account_id).as_ref() == Some(evm) + || &account_to_default_evm_address(account_id.into_ref()) == evm + } +} + +pub struct CallKillAccount(PhantomData); +impl OnKilledAccount for CallKillAccount { + fn on_killed_account(who: &T::AccountId) { + // remove mapping created by `claim_account` or `get_or_create_evm_address` + if let Some(evm_addr) = Pallet::::evm_addresses(who) { + Accounts::::remove(evm_addr); + EvmAddresses::::remove(who); + } + } +} + +impl StaticLookup for Pallet { + type Source = MultiAddress; + type Target = T::AccountId; + + fn lookup(a: Self::Source) -> Result { + match a { + MultiAddress::Address20(i) => Ok(T::AddressMapping::get_account_id(&EvmAddress::from_slice(&i))), + _ => Err(LookupError), + } + } + + fn unlookup(a: Self::Target) -> Self::Source { + MultiAddress::Id(a) + } +} + +impl EVMAccountsManager for Pallet { + /// Returns the AccountId used to generate the given EvmAddress. + fn get_account_id(address: &EvmAddress) -> T::AccountId { + T::AddressMapping::get_account_id(address) + } + + /// Returns the EvmAddress associated with a given AccountId or the underlying EvmAddress of the + /// AccountId. + fn get_evm_address(account_id: &T::AccountId) -> Option { + T::AddressMapping::get_evm_address(account_id) + } + + /// Claim account mapping between AccountId and a generated EvmAddress based off of the + /// AccountId. + fn claim_default_evm_address(account_id: &T::AccountId) -> Result { + Self::do_claim_default_evm_address(account_id.clone()) + } +} + +impl EvmPalletAddressMappingTrait for EvmAddressMapping +where + T::AccountId: From + Into, +{ + fn into_account_id(address: H160) -> T::AccountId { + if let Some(acc) = Accounts::::get(address) { + acc + } else { + let mut data: [u8; 32] = [0u8; 32]; + data[0..4].copy_from_slice(b"evm:"); + data[4..24].copy_from_slice(&address[..]); + AccountId32::from(data).into() + } + } +} \ No newline at end of file diff --git a/pallets/evm-accounts/src/mock.rs b/pallets/evm-accounts/src/mock.rs new file mode 100644 index 0000000..403110c --- /dev/null +++ b/pallets/evm-accounts/src/mock.rs @@ -0,0 +1,140 @@ +// This program 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. + +// This program 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 this program. If not, see . + +//! Mocks for the evm-accounts module. + +#![cfg(test)] + +use super::*; +use frame_support::{ + construct_runtime, + traits::{ConstU128, ConstU64, Everything}, +}; +use sp_core::{crypto::AccountId32, H256}; +use sp_io::hashing::keccak_256; +use sp_runtime::{testing::Header, traits::IdentityLookup}; + +pub type AccountId = AccountId32; +pub type BlockNumber = u64; +pub type Balance = u128; + +pub const ALICE: AccountId = AccountId32::new([0u8; 32]); +pub const BOB: AccountId = AccountId32::new([1u8; 32]); + +mod evm_accounts { + pub use super::super::*; +} +impl frame_system::Config for Runtime { + type Origin = Origin; + type Index = u64; + type BlockNumber = BlockNumber; + type Call = Call; + type Hash = H256; + type Hashing = ::sp_runtime::traits::BlakeTwo256; + type AccountId = AccountId; + type Lookup = IdentityLookup; + type Header = Header; + type Event = Event; + type BlockHashCount = ConstU64<250>; + type BlockWeights = (); + type BlockLength = (); + type Version = (); + type PalletInfo = PalletInfo; + type AccountData = pallet_balances::AccountData; + type OnNewAccount = (); + type OnKilledAccount = (); + type DbWeight = (); + type BaseCallFilter = Everything; + type SystemWeightInfo = (); + type SS58Prefix = (); + type OnSetCode = (); + type MaxConsumers = ConstU32<16>; +} + +impl pallet_balances::Config for Runtime { + type Balance = Balance; + type Event = Event; + type DustRemoval = (); + type ExistentialDeposit = ConstU128<1>; + type AccountStore = frame_system::Pallet; + type MaxLocks = (); + type MaxReserves = (); + type ReserveIdentifier = [u8; 8]; + type WeightInfo = (); +} + +impl Config for Runtime { + type Event = Event; + type Currency = Balances; + type ChainId = (); + type MergeAccount = (); + type AddressMapping = EvmAddressMapping; + type WeightInfo = (); +} + +type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic; +type Block = frame_system::mocking::MockBlock; + +construct_runtime!( + pub enum Runtime where + Block = Block, + NodeBlock = Block, + UncheckedExtrinsic = UncheckedExtrinsic, + { + System: frame_system::{Pallet, Call, Storage, Config, Event}, + EvmAccountsModule: evm_accounts::{Pallet, Call, Storage, Event}, + Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, + } +); + +pub struct ExtBuilder(); + +impl Default for ExtBuilder { + fn default() -> Self { + Self() + } +} + +impl ExtBuilder { + pub fn build(self) -> sp_io::TestExternalities { + let mut t = frame_system::GenesisConfig::default() + .build_storage::() + .unwrap(); + + pallet_balances::GenesisConfig:: { + balances: vec![(bob_account_id(), 100000)], + } + .assimilate_storage(&mut t) + .unwrap(); + + let mut ext = sp_io::TestExternalities::new(t); + ext.execute_with(|| System::set_block_number(1)); + ext + } +} + +pub fn alice() -> libsecp256k1::SecretKey { + libsecp256k1::SecretKey::parse(&keccak_256(b"Alice")).unwrap() +} + +pub fn bob() -> libsecp256k1::SecretKey { + libsecp256k1::SecretKey::parse(&keccak_256(b"Bob")).unwrap() +} + +pub fn bob_account_id() -> AccountId { + let address = EvmAccountsModule::eth_address(&bob()); + let mut data = [0u8; 32]; + data[0..4].copy_from_slice(b"evm:"); + data[4..24].copy_from_slice(&address[..]); + AccountId32::from(Into::<[u8; 32]>::into(data)) +} diff --git a/pallets/evm-accounts/src/tests.rs b/pallets/evm-accounts/src/tests.rs new file mode 100644 index 0000000..e5427ba --- /dev/null +++ b/pallets/evm-accounts/src/tests.rs @@ -0,0 +1,184 @@ +// This program 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. + +// This program 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 this program. If not, see . + +//! Unit tests for the evm-accounts module. + +#![cfg(test)] + +use super::*; +use frame_support::{assert_noop, assert_ok}; +use mock::{alice, bob, Event, EvmAccountsModule, ExtBuilder, Origin, Runtime, System, ALICE, BOB}; +use std::str::FromStr; + +#[test] +fn claim_account_work() { + ExtBuilder::default().build().execute_with(|| { + assert_ok!(EvmAccountsModule::claim_account( + Origin::signed(ALICE), + EvmAccountsModule::eth_address(&alice()), + EvmAccountsModule::eth_sign(&alice(), &ALICE) + )); + System::assert_last_event(Event::EvmAccountsModule(crate::Event::ClaimAccount { + account_id: ALICE, + evm_address: EvmAccountsModule::eth_address(&alice()), + })); + assert!( + Accounts::::contains_key(EvmAccountsModule::eth_address(&alice())) + && EvmAddresses::::contains_key(ALICE) + ); + }); +} + +#[test] +fn claim_account_should_not_work() { + ExtBuilder::default().build().execute_with(|| { + assert_noop!( + EvmAccountsModule::claim_account( + Origin::signed(ALICE), + EvmAccountsModule::eth_address(&bob()), + EvmAccountsModule::eth_sign(&bob(), &BOB) + ), + Error::::InvalidSignature + ); + assert_noop!( + EvmAccountsModule::claim_account( + Origin::signed(ALICE), + EvmAccountsModule::eth_address(&bob()), + EvmAccountsModule::eth_sign(&alice(), &ALICE) + ), + Error::::InvalidSignature + ); + assert_ok!(EvmAccountsModule::claim_account( + Origin::signed(ALICE), + EvmAccountsModule::eth_address(&alice()), + EvmAccountsModule::eth_sign(&alice(), &ALICE) + )); + assert_noop!( + EvmAccountsModule::claim_account( + Origin::signed(ALICE), + EvmAccountsModule::eth_address(&alice()), + EvmAccountsModule::eth_sign(&alice(), &ALICE) + ), + Error::::AccountIdHasMapped + ); + assert_noop!( + EvmAccountsModule::claim_account( + Origin::signed(BOB), + EvmAccountsModule::eth_address(&alice()), + EvmAccountsModule::eth_sign(&alice(), &BOB) + ), + Error::::EthAddressHasMapped + ); + }); +} + +#[test] +fn evm_get_account_id() { + ExtBuilder::default().build().execute_with(|| { + let evm_account = EvmAccountsModule::eth_address(&alice()); + let evm_account_to_default = { + let mut bytes = *b"evm:aaaaaaaaaaaaaaaaaaaa\0\0\0\0\0\0\0\0"; + bytes[4..24].copy_from_slice(&evm_account[..]); + AccountId32::from(bytes) + }; + assert_eq!( + EvmAddressMapping::::get_account_id(&evm_account), + evm_account_to_default + ); + + assert_ok!(EvmAccountsModule::claim_account( + Origin::signed(ALICE), + EvmAccountsModule::eth_address(&alice()), + EvmAccountsModule::eth_sign(&alice(), &ALICE) + )); + + assert_eq!(EvmAddressMapping::::get_account_id(&evm_account), ALICE); + assert_eq!( + EvmAddressMapping::::get_evm_address(&ALICE).unwrap(), + evm_account + ); + + assert!(EvmAddressMapping::::is_linked( + &evm_account_to_default, + &evm_account + )); + assert!(EvmAddressMapping::::is_linked(&ALICE, &evm_account)); + }); +} + +#[test] +fn account_to_evm() { + ExtBuilder::default().build().execute_with(|| { + let default_evm_account = EvmAddress::from_str("f0bd9ffde7f9f4394d8cc1d86bf24d87e5d5a9a9").unwrap(); + assert_eq!(EvmAddressMapping::::get_evm_address(&ALICE), None); + + let alice_evm_account = EvmAccountsModule::eth_address(&alice()); + + assert_ok!(EvmAccountsModule::claim_account( + Origin::signed(ALICE), + alice_evm_account, + EvmAccountsModule::eth_sign(&alice(), &ALICE) + )); + + assert_eq!(EvmAddressMapping::::get_account_id(&alice_evm_account), ALICE); + assert_eq!( + EvmAddressMapping::::get_evm_address(&ALICE).unwrap(), + alice_evm_account + ); + + assert_eq!( + EvmAddressMapping::::get_or_create_evm_address(&ALICE), + alice_evm_account + ); + + assert!(EvmAddressMapping::::is_linked(&ALICE, &alice_evm_account)); + assert!(EvmAddressMapping::::is_linked(&ALICE, &default_evm_account)); + }); +} + +#[test] +fn account_to_evm_with_create_default() { + ExtBuilder::default().build().execute_with(|| { + let default_evm_account = EvmAddress::from_str("f0bd9ffde7f9f4394d8cc1d86bf24d87e5d5a9a9").unwrap(); + assert_eq!( + EvmAddressMapping::::get_or_create_evm_address(&ALICE), + default_evm_account + ); + System::assert_last_event(Event::EvmAccountsModule(crate::Event::ClaimAccount { + account_id: ALICE, + evm_address: default_evm_account, + })); + assert_eq!( + EvmAddressMapping::::get_evm_address(&ALICE), + Some(default_evm_account) + ); + + assert_eq!( + EvmAddressMapping::::get_account_id(&default_evm_account), + ALICE + ); + + assert!(EvmAddressMapping::::is_linked(&ALICE, &default_evm_account)); + + let alice_evm_account = EvmAccountsModule::eth_address(&alice()); + + assert_noop!( + EvmAccountsModule::claim_account( + Origin::signed(ALICE), + alice_evm_account, + EvmAccountsModule::eth_sign(&alice(), &ALICE) + ), + Error::::AccountIdHasMapped + ); + }); +} diff --git a/pallets/evm-accounts/src/weights.rs b/pallets/evm-accounts/src/weights.rs new file mode 100644 index 0000000..1d49b70 --- /dev/null +++ b/pallets/evm-accounts/src/weights.rs @@ -0,0 +1,48 @@ +// This program 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. + +// This program 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 this program. If not, see . + + +//! Autogenerated weights for pallet_evm_accounts +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 3.0.0 +//! DATE: 2021-02-26, STEPS: [50, ], REPEAT: 20, LOW RANGE: [], HIGH RANGE: [] +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 128 + + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(clippy::unnecessary_cast)] + +use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; +use sp_std::marker::PhantomData; + +/// Weight functions needed for module_evm_accounts. +pub trait WeightInfo { + fn claim_account() -> Weight; + fn claim_default_account() -> Weight; +} + +// For backwards compatibility and tests +impl WeightInfo for () { + fn claim_account() -> Weight { + (340_000_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(3 as Weight)) + .saturating_add(RocksDbWeight::get().writes(2 as Weight)) + } + fn claim_default_account() -> Weight { + (19_000_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(1 as Weight)) + .saturating_add(RocksDbWeight::get().writes(2 as Weight)) + } +} \ No newline at end of file diff --git a/pallets/evm-utility/Cargo.toml b/pallets/evm-utility/Cargo.toml new file mode 100644 index 0000000..4b2e3e8 --- /dev/null +++ b/pallets/evm-utility/Cargo.toml @@ -0,0 +1,32 @@ +[package] +name = "pallet-evm-utility" +version = "1.0.0" +authors = ["TraceLabs"] +edition = "2021" + +[dependencies] +sha3 = { version = "0.9.1", default-features = false } + +sp-std = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27", default-features = false } + +evm = { git = "https://github.com/rust-blockchain/evm", rev = "0b686f8c2c83a52638917caa649dc23302fda80d", default-features = false, features = [ + "with-codec", +] } +evm-gasometer = { git = "https://github.com/rust-blockchain/evm", rev = "0b686f8c2c83a52638917caa649dc23302fda80d", default-features = false } +evm-runtime = { git = "https://github.com/rust-blockchain/evm", rev = "0b686f8c2c83a52638917caa649dc23302fda80d", default-features = false } +ethereum = { version = "0.12.0", default-features = false, features = [ + "with-codec", +] } + +[features] +default = ["std"] +std = [ + "sha3/std", + "sp-std/std", + "evm/std", + "evm/with-serde", + "evm-runtime/std", + "evm-gasometer/std", + "ethereum/with-serde", +] +tracing = ["evm/tracing", "evm-gasometer/tracing", "evm-runtime/tracing"] diff --git a/pallets/evm-utility/macro/Cargo.toml b/pallets/evm-utility/macro/Cargo.toml new file mode 100644 index 0000000..83ec5b2 --- /dev/null +++ b/pallets/evm-utility/macro/Cargo.toml @@ -0,0 +1,19 @@ +[package] +name = "pallet-evm-utility-macro" +version = "1.0.0" +authors = ["TraceLabs"] +edition = "2021" + +[lib] +proc-macro = true + +[dependencies] +quote = "1.0.20" +syn = { version = "1.0.96", features = [ + "full", + "fold", + "extra-traits", + "visit", +] } +proc-macro2 = "1.0.40" +pallet-evm-utility = { path = ".." } diff --git a/pallets/evm-utility/macro/src/lib.rs b/pallets/evm-utility/macro/src/lib.rs new file mode 100644 index 0000000..644adf3 --- /dev/null +++ b/pallets/evm-utility/macro/src/lib.rs @@ -0,0 +1,72 @@ +// This program 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. + +// This program 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 this program. If not, see . + +use proc_macro::TokenStream; +use proc_macro2::Literal; +use quote::quote; +use syn::{parse_macro_input, Expr, ExprLit, Ident, ItemEnum, Lit, LitByteStr, LitStr}; + +#[proc_macro_attribute] +pub fn generate_function_selector(_: TokenStream, input: TokenStream) -> TokenStream { + let item = parse_macro_input!(input as ItemEnum); + + let ItemEnum { + attrs, + vis, + enum_token, + ident, + variants, + .. + } = item; + + let mut ident_expressions: Vec = vec![]; + let mut variant_expressions: Vec = vec![]; + for variant in variants { + if let Some((_, Expr::Lit(ExprLit { lit, .. }))) = variant.discriminant { + if let Lit::Str(token) = lit { + let selector = pallet_evm_utility::get_function_selector(&token.value()); + // println!("method: {:?}, selector: {:?}", token.value(), selector); + ident_expressions.push(variant.ident); + variant_expressions.push(Expr::Lit(ExprLit { + lit: Lit::Verbatim(Literal::u32_suffixed(selector)), + attrs: Default::default(), + })); + } else { + panic!("Not method string: `{:?}`", lit); + } + } else { + panic!("Not enum: `{:?}`", variant); + } + } + + (quote! { + #(#attrs)* + #vis #enum_token #ident { + #( + #ident_expressions = #variant_expressions, + )* + } + }) + .into() +} + +#[proc_macro] +pub fn keccak256(input: TokenStream) -> TokenStream { + let lit_str = parse_macro_input!(input as LitStr); + + let result = pallet_evm_utility::sha3_256(&lit_str.value()); + + let eval = Lit::ByteStr(LitByteStr::new(result.as_ref(), proc_macro2::Span::call_site())); + + quote!(#eval).into() +} \ No newline at end of file diff --git a/pallets/evm-utility/src/lib.rs b/pallets/evm-utility/src/lib.rs new file mode 100644 index 0000000..ba1c14e --- /dev/null +++ b/pallets/evm-utility/src/lib.rs @@ -0,0 +1,43 @@ +// This program 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. + +// This program 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 this program. If not, see . + +//! # Evm utiltity pallet +//! +//! A pallet provides some utility methods. + +#![cfg_attr(not(feature = "std"), no_std)] + +use sha3::{Digest, Keccak256}; + +pub use ethereum; +pub use evm::{self, backend::Basic as Account}; +pub use evm_gasometer; +pub use evm_runtime; + +pub fn sha3_256(s: &str) -> [u8; 32] { + let mut result = [0u8; 32]; + + // create a SHA3-256 object + let mut hasher = Keccak256::new(); + // write input message + hasher.update(s); + // read hash digest + result.copy_from_slice(&hasher.finalize()[..32]); + + result +} + +pub fn get_function_selector(s: &str) -> u32 { + let result = sha3_256(s); + u32::from_be_bytes(result[..4].try_into().unwrap()) +} \ No newline at end of file diff --git a/runtime/Cargo.toml b/runtime/Cargo.toml index 5dfc102..8a1f40f 100644 --- a/runtime/Cargo.toml +++ b/runtime/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "origintrail-parachain-runtime" -version = "1.0.3" +version = "1.0.4" authors = ["TraceLabs"] description = "OriginTrail Parachain Runtime - Cumulus FRAME-based Substrate Runtime" license = "GPL-3.0-only" @@ -82,6 +82,17 @@ cumulus-primitives-utility = { git = "https://github.com/paritytech/cumulus", de pallet-collator-selection = { git = "https://github.com/paritytech/cumulus", default-features = false, branch = "polkadot-v0.9.27" } parachain-info = { git = "https://github.com/paritytech/cumulus", default-features = false, branch = "polkadot-v0.9.27" } +# Frontier +pallet-base-fee = { git = "https://github.com/OriginTrail/frontier", default-features = false, branch = "polkadot-v0.9.27" } +pallet-evm = { git = "https://github.com/OriginTrail/frontier", default-features = false, branch = "polkadot-v0.9.27" } +pallet-evm-accounts = { path = "../pallets/evm-accounts", default-features = false } +pallet-evm-precompile-simple = { git = "https://github.com/OriginTrail/frontier", default-features = false, branch = "polkadot-v0.9.27" } +pallet-evm-precompile-modexp = { git = "https://github.com/OriginTrail/frontier", default-features = false, branch = "polkadot-v0.9.27" } +pallet-evm-precompile-sha3fips = { git = "https://github.com/OriginTrail/frontier", default-features = false, branch = "polkadot-v0.9.27" } +pallet-ethereum = { git = "https://github.com/OriginTrail/frontier", default-features = false, branch = "polkadot-v0.9.27" } +fp-rpc = { git = "https://github.com/OriginTrail/frontier", default-features = false, branch = "polkadot-v0.9.27" } +fp-self-contained = { git = "https://github.com/OriginTrail/frontier", default-features = false, branch = "polkadot-v0.9.27" } + [features] default = ["std"] std = [ @@ -97,6 +108,8 @@ std = [ "cumulus-primitives-core/std", "cumulus-primitives-timestamp/std", "cumulus-primitives-utility/std", + "fp-rpc/std", + "fp-self-contained/std", "frame-executive/std", "frame-support/std", "frame-system-rpc-runtime-api/std", @@ -104,7 +117,13 @@ std = [ "pallet-aura/std", "pallet-authorship/std", "pallet-balances/std", + "pallet-base-fee/std", "pallet-collator-selection/std", + "pallet-evm/std", + "pallet-evm-accounts/std", + "pallet-evm-precompile-simple/std", + "pallet-evm-precompile-sha3fips/std", + "pallet-ethereum/std", "pallet-scheduler/std", "pallet-session/std", "pallet-sudo/std", @@ -143,6 +162,8 @@ runtime-benchmarks = [ "frame-system/runtime-benchmarks", "pallet-balances/runtime-benchmarks", "pallet-collator-selection/runtime-benchmarks", + "pallet-evm/runtime-benchmarks", + "pallet-ethereum/runtime-benchmarks", "pallet-template/runtime-benchmarks", "pallet-timestamp/runtime-benchmarks", "pallet-treasury/runtime-benchmarks", diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs index dadb3a7..aeae305 100644 --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -12,14 +12,17 @@ pub mod xcm_config; use cumulus_pallet_parachain_system::RelayNumberStrictlyIncreases; use smallvec::smallvec; use sp_api::impl_runtime_apis; -use sp_core::{crypto::KeyTypeId, OpaqueMetadata}; +use sp_core::{crypto::KeyTypeId, OpaqueMetadata, H160, H256, U256}; use sp_runtime::{ - create_runtime_str, generic, impl_opaque_keys, + create_runtime_str, generic, impl_opaque_keys, DispatchResult, traits::{ AccountIdConversion, AccountIdLookup, BlakeTwo256, Block as BlockT, - ConvertInto, IdentifyAccount, Verify, + ConvertInto, DispatchInfoOf, Dispatchable, IdentifyAccount, + PostDispatchInfoOf, UniqueSaturatedInto, Verify, + }, + transaction_validity::{ + TransactionSource, TransactionValidity, TransactionValidityError }, - transaction_validity::{TransactionSource, TransactionValidity}, ApplyExtrinsicResult, MultiSignature, }; @@ -28,16 +31,18 @@ use sp_std::prelude::*; use sp_version::NativeVersion; use sp_version::RuntimeVersion; +use codec::{Encode}; pub use frame_support::traits::EqualPrivilegeOnly; use frame_support::{ - construct_runtime, parameter_types, - traits::{Currency as PalletCurrency, Everything, Imbalance, OnUnbalanced}, + construct_runtime, parameter_types, transactional, + traits::{Currency as PalletCurrency, Everything, FindAuthor, + ReservableCurrency, Imbalance, OnUnbalanced}, weights::{ constants::WEIGHT_PER_SECOND, ConstantMultiplier, DispatchClass, Weight, WeightToFeeCoefficient, WeightToFeeCoefficients, WeightToFeePolynomial, }, - PalletId, + ConsensusEngineId, PalletId, }; use frame_system::{ limits::{BlockLength, BlockWeights}, @@ -58,6 +63,18 @@ use polkadot_runtime_common::{BlockHashCount, SlowAdjustingFeeUpdate}; use xcm::latest::prelude::BodyId; use xcm_executor::XcmExecutor; +// Frontier +use pallet_evm::{ + EnsureAddressRoot, EnsureAddressNever, Account as EVMAccount, EVMCurrencyAdapter, + FeeCalculator, OnChargeEVMTransaction as OnChargeEVMTransactionT, Runner +}; +use pallet_ethereum::{Call::transact, EthereumBlockHashMapping, Transaction as EthereumTransaction}; +use fp_rpc::TransactionStatus; +use pallet_evm_accounts::{EvmAddressMapping, MergeAccount}; + +mod precompiles; +use precompiles::FrontierPrecompiles; + /// Import the template pallet. pub use pallet_template; @@ -108,7 +125,7 @@ pub type SignedExtra = ( ); /// Unchecked extrinsic type as expected by this runtime. -pub type UncheckedExtrinsic = generic::UncheckedExtrinsic; +pub type UncheckedExtrinsic = fp_self_contained::UncheckedExtrinsic; /// Extrinsic type that has already been checked. pub type CheckedExtrinsic = generic::CheckedExtrinsic; @@ -122,6 +139,60 @@ pub type Executive = frame_executive::Executive< AllPalletsWithSystem, >; +impl fp_self_contained::SelfContainedCall for Call { + type SignedInfo = H160; + + fn is_self_contained(&self) -> bool { + match self { + Call::Ethereum(call) => call.is_self_contained(), + _ => false, + } + } + + fn check_self_contained(&self) -> Option> { + match self { + Call::Ethereum(call) => call.check_self_contained(), + _ => None, + } + } + + fn validate_self_contained( + &self, + info: &Self::SignedInfo, + dispatch_info: &DispatchInfoOf, + len: usize, + ) -> Option { + match self { + Call::Ethereum(call) => call.validate_self_contained(info, dispatch_info, len), + _ => None, + } + } + + fn pre_dispatch_self_contained( + &self, + info: &Self::SignedInfo, + dispatch_info: &DispatchInfoOf, + len: usize, + ) -> Option> { + match self { + Call::Ethereum(call) => call.pre_dispatch_self_contained(info, dispatch_info, len), + _ => None, + } + } + + fn apply_self_contained( + self, + info: Self::SignedInfo, + ) -> Option>> { + match self { + call @ Call::Ethereum(pallet_ethereum::Call::transact { .. }) => Some(call.dispatch( + Origin::from(pallet_ethereum::RawOrigin::EthereumTransaction(info)), + )), + _ => None, + } + } +} + /// Handles converting a weight scalar to a fee value, based on the scale and granularity of the /// node's balance type. /// @@ -177,7 +248,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { spec_name: create_runtime_str!("origintrail-parachain"), impl_name: create_runtime_str!("origintrail-parachain"), authoring_version: 1, - spec_version: 103, + spec_version: 104, impl_version: 0, apis: RUNTIME_API_VERSIONS, transaction_version: 1, @@ -587,6 +658,167 @@ impl pallet_treasury::Config for Runtime { type SpendOrigin = frame_support::traits::NeverEnsureOrigin; } +pub struct MergeAccountEvm; +impl MergeAccount for MergeAccountEvm { +#[transactional] +fn merge_account(source: &AccountId, dest: &AccountId) -> DispatchResult { + // unreserve all reserved currency + >::unreserve(source, Balances::reserved_balance(source)); + + // transfer all free to dest + match Balances::transfer(Some(source.clone()).into(), dest.clone().into(), Balances::free_balance(source)) { + Ok(_) => Ok(()), + Err(e) => Err(e.error), + } + } +} + +impl pallet_evm_accounts::Config for Runtime { + type Event = Event; + type Currency = Balances; + type ChainId = ChainId; + type AddressMapping = EvmAddressMapping; + type MergeAccount = MergeAccountEvm; + type WeightInfo = weights::evm_accounts_weights::WeightInfo; +} + +parameter_types! { + pub IsActive: bool = true; + pub DefaultBaseFeePerGas: U256 = U256::from(1_000_000_000); +} + +pub struct BaseFeeThreshold; +impl pallet_base_fee::BaseFeeThreshold for BaseFeeThreshold { + fn lower() -> Permill { + Permill::zero() + } + fn ideal() -> Permill { + Permill::from_parts(500_000) + } + fn upper() -> Permill { + Permill::from_parts(1_000_000) + } +} + +impl pallet_base_fee::Config for Runtime { + type Event = Event; + type Threshold = BaseFeeThreshold; + type IsActive = IsActive; + type DefaultBaseFeePerGas = DefaultBaseFeePerGas; +} + +type CurrencyAccountId = ::AccountId; + +type BalanceFor = + <::Currency as PalletCurrency>>::Balance; + +type PositiveImbalanceFor = + <::Currency as PalletCurrency>>::PositiveImbalance; + +type NegativeImbalanceFor = + <::Currency as PalletCurrency>>::NegativeImbalance; + +pub struct OnChargeEVMTransaction(sp_std::marker::PhantomData); +impl OnChargeEVMTransactionT for OnChargeEVMTransaction +where + T: pallet_evm::Config, + PositiveImbalanceFor: Imbalance, Opposite = NegativeImbalanceFor>, + NegativeImbalanceFor: Imbalance, Opposite = PositiveImbalanceFor>, + OU: OnUnbalanced>, + U256: UniqueSaturatedInto> +{ + type LiquidityInfo = Option>; + + fn withdraw_fee(who: &H160, fee: U256) -> Result> { + EVMCurrencyAdapter::<::Currency, ()>::withdraw_fee(who, fee) + } + + fn correct_and_deposit_fee( + who: &H160, + corrected_fee: U256, + base_fee: U256, + already_withdrawn: Self::LiquidityInfo, + ) -> Self::LiquidityInfo { + ::Currency, OU> as OnChargeEVMTransactionT< + T, + >>::correct_and_deposit_fee(who, corrected_fee, base_fee, already_withdrawn) + } + + fn pay_priority_fee(tip: Self::LiquidityInfo) { + if let Some(tip) = tip { + OU::on_unbalanced(tip); + } + } +} + +/// Current approximation of the gas/s consumption considering +/// EVM execution over compiled WASM (on 4.4Ghz CPU). +/// Given the 500ms Weight, from which 75% only are used for transactions, +/// the total EVM execution gas limit is: GAS_PER_SECOND * 0.500 * 0.75 ~= 15_000_000. +pub const GAS_PER_SECOND: u64 = 40_000_000; + +/// Approximate ratio of the amount of Weight per Gas. +/// u64 works for approximations because Weight is a very small unit compared to gas. +pub const WEIGHT_PER_GAS: u64 = WEIGHT_PER_SECOND / GAS_PER_SECOND; + +pub struct GasWeightMapping; +impl pallet_evm::GasWeightMapping for GasWeightMapping { + fn gas_to_weight(gas: u64) -> Weight { + gas.saturating_mul(WEIGHT_PER_GAS) + } + + fn weight_to_gas(weight: Weight) -> u64 { + weight.wrapping_div(WEIGHT_PER_GAS) + } +} + +pub struct FindAuthorTruncated(sp_std::marker::PhantomData); +impl> FindAuthor for FindAuthorTruncated { + fn find_author<'a, I>(digests: I) -> Option + where + I: 'a + IntoIterator, + { + if let Some(author_index) = F::find_author(digests) { + let authority_id = Aura::authorities()[author_index as usize].clone(); + return Some(H160::from_slice(&authority_id.encode()[4..24])); + } + + None + } +} + +parameter_types! { + pub const ChainId: u64 = 2043; + pub BlockGasLimit: U256 = U256::from(NORMAL_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT / WEIGHT_PER_GAS); + pub PrecompilesValue: FrontierPrecompiles = FrontierPrecompiles::<_>::new(); +} + +impl pallet_evm::Config for Runtime { + type Currency = Balances; + type Event = Event; + + type BlockGasLimit = BlockGasLimit; + type ChainId = ChainId; + type BlockHashMapping = EthereumBlockHashMapping; + type Runner = pallet_evm::runner::stack::Runner; + + type CallOrigin = EnsureAddressRoot; + type WithdrawOrigin = EnsureAddressNever; + type AddressMapping = EvmAddressMapping; + + type FeeCalculator = BaseFee; + type GasWeightMapping = GasWeightMapping; + type OnChargeTransaction = OnChargeEVMTransaction; + type FindAuthor = FindAuthorTruncated; + type PrecompilesType = FrontierPrecompiles; + type PrecompilesValue = PrecompilesValue; +} + +impl pallet_ethereum::Config for Runtime { + type Event = Event; + type StateRoot = pallet_ethereum::IntermediateStateRoot; +} + /// Configure the pallet template in pallets/template. impl pallet_template::Config for Runtime { type Event = Event; @@ -629,6 +861,12 @@ construct_runtime!( // Template. TemplatePallet: pallet_template::{Pallet, Call, Storage, Event} = 40, + // Frontier + EVM: pallet_evm::{Pallet, Config, Call, Storage, Event} = 50, + Ethereum: pallet_ethereum::{Pallet, Call, Storage, Event, Config, Origin} = 51, + EvmAccounts: pallet_evm_accounts::{Pallet, Call, Storage, Event} = 52, + BaseFee: pallet_base_fee::{Pallet, Call, Storage, Config, Event} = 53, + // Governance stuff. Scheduler: pallet_scheduler::{Pallet, Storage, Event, Call} = 60, @@ -721,6 +959,155 @@ impl_runtime_apis! { } } + impl fp_rpc::EthereumRuntimeRPCApi for Runtime { + fn chain_id() -> u64 { + ::ChainId::get() + } + + fn account_basic(address: H160) -> EVMAccount { + let (account, _) = EVM::account_basic(&address); + account + } + + fn gas_price() -> U256 { + let (gas_price, _) = ::FeeCalculator::min_gas_price(); + gas_price + } + + fn account_code_at(address: H160) -> Vec { + EVM::account_codes(address) + } + + fn author() -> H160 { + >::find_author() + } + + fn storage_at(address: H160, index: U256) -> H256 { + let mut tmp = [0u8; 32]; + index.to_big_endian(&mut tmp); + EVM::account_storages(address, H256::from_slice(&tmp[..])) + } + + fn call( + from: H160, + to: H160, + data: Vec, + value: U256, + gas_limit: U256, + max_fee_per_gas: Option, + max_priority_fee_per_gas: Option, + nonce: Option, + estimate: bool, + access_list: Option)>>, + ) -> Result { + let config = if estimate { + let mut config = ::config().clone(); + config.estimate = true; + Some(config) + } else { + None + }; + + let is_transactional = false; + let validate = true; + ::Runner::call( + from, + to, + data, + value, + gas_limit.unique_saturated_into(), + max_fee_per_gas, + max_priority_fee_per_gas, + nonce, + access_list.unwrap_or_default(), + is_transactional, + validate, + config.as_ref().unwrap_or_else(|| ::config()), + ).map_err(|err| err.error.into()) + } + + fn create( + from: H160, + data: Vec, + value: U256, + gas_limit: U256, + max_fee_per_gas: Option, + max_priority_fee_per_gas: Option, + nonce: Option, + estimate: bool, + access_list: Option)>>, + ) -> Result { + let config = if estimate { + let mut config = ::config().clone(); + config.estimate = true; + Some(config) + } else { + None + }; + + let is_transactional = false; + let validate = true; + ::Runner::create( + from, + data, + value, + gas_limit.unique_saturated_into(), + max_fee_per_gas, + max_priority_fee_per_gas, + nonce, + access_list.unwrap_or_default(), + is_transactional, + validate, + config.as_ref().unwrap_or_else(|| ::config()), + ).map_err(|err| err.error.into()) + } + + fn current_transaction_statuses() -> Option> { + Ethereum::current_transaction_statuses() + } + + fn current_block() -> Option { + Ethereum::current_block() + } + + fn current_receipts() -> Option> { + Ethereum::current_receipts() + } + + fn current_all() -> ( + Option, + Option>, + Option> + ) { + ( + Ethereum::current_block(), + Ethereum::current_receipts(), + Ethereum::current_transaction_statuses() + ) + } + + fn extrinsic_filter( + xts: Vec<::Extrinsic>, + ) -> Vec { + xts.into_iter().filter_map(|xt| match xt.0.function { + Call::Ethereum(transact { transaction }) => Some(transaction), + _ => None + }).collect::>() + } + + fn elasticity() -> Option { + Some(BaseFee::elasticity()) + } + } + + impl fp_rpc::ConvertTransactionRuntimeApi for Runtime { + fn convert_transaction(transaction: EthereumTransaction) -> ::Extrinsic { + UncheckedExtrinsic::new_unsigned( + pallet_ethereum::Call::::transact { transaction }.into(), + ) + } + } + impl sp_session::SessionKeys for Runtime { fn generate_session_keys(seed: Option>) -> Vec { SessionKeys::generate(seed) diff --git a/runtime/src/precompiles.rs b/runtime/src/precompiles.rs new file mode 100644 index 0000000..75f2451 --- /dev/null +++ b/runtime/src/precompiles.rs @@ -0,0 +1,51 @@ +use pallet_evm::{Precompile, PrecompileHandle, PrecompileResult, PrecompileSet}; +use sp_core::H160; +use sp_std::marker::PhantomData; + +use pallet_evm_precompile_modexp::Modexp; +use pallet_evm_precompile_sha3fips::Sha3FIPS256; +use pallet_evm_precompile_simple::{ECRecover, ECRecoverPublicKey, Identity, Ripemd160, Sha256}; + +pub struct FrontierPrecompiles(PhantomData); + +impl FrontierPrecompiles +where + R: pallet_evm::Config, +{ + pub fn new() -> Self { + Self(Default::default()) + } + pub fn used_addresses() -> sp_std::vec::Vec { + sp_std::vec![1, 2, 3, 4, 5, 1024, 1025] + .into_iter() + .map(hash) + .collect() + } +} +impl PrecompileSet for FrontierPrecompiles +where + R: pallet_evm::Config, +{ + fn execute(&self, handle: &mut impl PrecompileHandle) -> Option { + match handle.code_address() { + // Ethereum precompiles : + a if a == hash(1) => Some(ECRecover::execute(handle)), + a if a == hash(2) => Some(Sha256::execute(handle)), + a if a == hash(3) => Some(Ripemd160::execute(handle)), + a if a == hash(4) => Some(Identity::execute(handle)), + a if a == hash(5) => Some(Modexp::execute(handle)), + // Non-Frontier specific nor Ethereum precompiles : + a if a == hash(1024) => Some(Sha3FIPS256::execute(handle)), + a if a == hash(1025) => Some(ECRecoverPublicKey::execute(handle)), + _ => None, + } + } + + fn is_precompile(&self, address: H160) -> bool { + Self::used_addresses().contains(&address) + } +} + +fn hash(a: u64) -> H160 { + H160::from_low_u64_be(a) +} \ No newline at end of file diff --git a/runtime/src/weights/evm_accounts_weights.rs b/runtime/src/weights/evm_accounts_weights.rs new file mode 100644 index 0000000..6266315 --- /dev/null +++ b/runtime/src/weights/evm_accounts_weights.rs @@ -0,0 +1,50 @@ +// This program 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. + +// This program 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 this program. If not, see . + +//! Autogenerated weights for pallet_evm_accounts +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2022-08-12, STEPS: `50`, REPEAT: 20, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, DB CACHE: 1024 + + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] + +use frame_support::{traits::Get, weights::Weight}; +use sp_std::marker::PhantomData; + +/// Weight functions for pallet_evm_accounts. +pub struct WeightInfo(PhantomData); +impl pallet_evm_accounts::WeightInfo for WeightInfo { + // Storage: unknown [0x3a7472616e73616374696f6e5f6c6576656c3a] (r:1 w:1) + // Storage: EvmAccounts EvmAddresses (r:1 w:1) + // Storage: EvmAccounts Accounts (r:1 w:1) + // Storage: EVM ChainId (r:1 w:0) + // Storage: System BlockHash (r:1 w:0) + // Storage: System Account (r:1 w:0) + fn claim_account() -> Weight { + (74_709_000 as Weight) + .saturating_add(T::DbWeight::get().reads(6 as Weight)) + .saturating_add(T::DbWeight::get().writes(3 as Weight)) + } + // Storage: unknown [0x3a7472616e73616374696f6e5f6c6576656c3a] (r:1 w:1) + // Storage: EvmAccounts EvmAddresses (r:1 w:1) + // Storage: EvmAccounts Accounts (r:0 w:1) + fn claim_default_account() -> Weight { + (16_405_000 as Weight) + .saturating_add(T::DbWeight::get().reads(2 as Weight)) + .saturating_add(T::DbWeight::get().writes(3 as Weight)) + } +} \ No newline at end of file diff --git a/runtime/src/weights/mod.rs b/runtime/src/weights/mod.rs index ed0b4db..9f0cdfb 100644 --- a/runtime/src/weights/mod.rs +++ b/runtime/src/weights/mod.rs @@ -21,6 +21,7 @@ pub mod block_weights; pub mod extrinsic_weights; pub mod paritydb_weights; pub mod rocksdb_weights; +pub mod evm_accounts_weights; pub use block_weights::constants::BlockExecutionWeight; pub use extrinsic_weights::constants::ExtrinsicBaseWeight;