diff --git a/evm-template/Cargo.lock b/evm-template/Cargo.lock index 6d9c163..5a293a6 100644 --- a/evm-template/Cargo.lock +++ b/evm-template/Cargo.lock @@ -789,6 +789,15 @@ dependencies = [ "pin-project-lite 0.2.14", ] +[[package]] +name = "atoi" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f28d99ec8bfea296261ca1af174f24225171fea9664ba9003cbebee704810528" +dependencies = [ + "num-traits", +] + [[package]] name = "atomic-take" version = "1.1.0" @@ -1709,6 +1718,21 @@ dependencies = [ "wasmtime-types", ] +[[package]] +name = "crc" +version = "3.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69e6e4d7b33a94f0991c26729976b10ebde1d34c3ee82408fb536164fa10d636" +dependencies = [ + "crc-catalog", +] + +[[package]] +name = "crc-catalog" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5" + [[package]] name = "crc32fast" version = "1.4.0" @@ -2719,6 +2743,12 @@ dependencies = [ "walkdir", ] +[[package]] +name = "dotenvy" +version = "0.15.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b" + [[package]] name = "downcast" version = "0.11.0" @@ -2837,6 +2867,9 @@ name = "either" version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a47c1c47d2f5964e29c61246e81db715514cd532db6b5116a25ea3c03d6780a2" +dependencies = [ + "serde", +] [[package]] name = "elliptic-curve" @@ -3188,6 +3221,176 @@ dependencies = [ "thiserror", ] +[[package]] +name = "fc-api" +version = "1.0.0-dev" +source = "git+https://github.com/OpenZeppelin/frontier?branch=polkadot-v1.7.0#8037bf8d7401357d321d837c9b92729519c81e45" +dependencies = [ + "async-trait", + "fp-storage", + "parity-scale-codec", + "sp-core", + "sp-runtime", +] + +[[package]] +name = "fc-consensus" +version = "2.0.0-dev" +source = "git+https://github.com/OpenZeppelin/frontier?branch=polkadot-v1.7.0#8037bf8d7401357d321d837c9b92729519c81e45" +dependencies = [ + "async-trait", + "fp-consensus", + "fp-rpc", + "sc-consensus", + "sp-api", + "sp-block-builder", + "sp-consensus", + "sp-runtime", + "thiserror", +] + +[[package]] +name = "fc-db" +version = "2.0.0-dev" +source = "git+https://github.com/OpenZeppelin/frontier?branch=polkadot-v1.7.0#8037bf8d7401357d321d837c9b92729519c81e45" +dependencies = [ + "async-trait", + "ethereum", + "fc-api", + "fc-storage", + "fp-consensus", + "fp-rpc", + "fp-storage", + "futures", + "kvdb-rocksdb", + "log", + "parity-db", + "parity-scale-codec", + "parking_lot 0.12.1", + "sc-client-api", + "sc-client-db", + "smallvec", + "sp-api", + "sp-blockchain", + "sp-core", + "sp-database", + "sp-runtime", + "sp-storage 19.0.0 (git+https://github.com/paritytech/polkadot-sdk?tag=polkadot-v1.7.0)", + "sqlx", + "tokio", +] + +[[package]] +name = "fc-mapping-sync" +version = "2.0.0-dev" +source = "git+https://github.com/OpenZeppelin/frontier?branch=polkadot-v1.7.0#8037bf8d7401357d321d837c9b92729519c81e45" +dependencies = [ + "fc-db", + "fc-storage", + "fp-consensus", + "fp-rpc", + "futures", + "futures-timer", + "log", + "parking_lot 0.12.1", + "sc-client-api", + "sc-utils", + "sp-api", + "sp-blockchain", + "sp-consensus", + "sp-core", + "sp-runtime", + "tokio", +] + +[[package]] +name = "fc-rpc" +version = "2.0.0-dev" +source = "git+https://github.com/OpenZeppelin/frontier?branch=polkadot-v1.7.0#8037bf8d7401357d321d837c9b92729519c81e45" +dependencies = [ + "ethereum", + "ethereum-types", + "evm", + "fc-api", + "fc-mapping-sync", + "fc-rpc-core", + "fc-storage", + "fp-evm", + "fp-rpc", + "fp-storage", + "futures", + "hex", + "jsonrpsee", + "libsecp256k1", + "log", + "pallet-evm", + "parity-scale-codec", + "prometheus", + "rand", + "rlp", + "sc-client-api", + "sc-consensus-aura", + "sc-network", + "sc-network-common", + "sc-network-sync", + "sc-rpc", + "sc-service", + "sc-transaction-pool", + "sc-transaction-pool-api", + "sc-utils", + "schnellru", + "serde", + "sp-api", + "sp-block-builder", + "sp-blockchain", + "sp-consensus", + "sp-consensus-aura", + "sp-core", + "sp-externalities 0.25.0 (git+https://github.com/paritytech/polkadot-sdk?tag=polkadot-v1.7.0)", + "sp-inherents", + "sp-io", + "sp-runtime", + "sp-state-machine", + "sp-storage 19.0.0 (git+https://github.com/paritytech/polkadot-sdk?tag=polkadot-v1.7.0)", + "sp-timestamp", + "substrate-prometheus-endpoint", + "thiserror", + "tokio", +] + +[[package]] +name = "fc-rpc-core" +version = "1.1.0-dev" +source = "git+https://github.com/OpenZeppelin/frontier?branch=polkadot-v1.7.0#8037bf8d7401357d321d837c9b92729519c81e45" +dependencies = [ + "ethereum", + "ethereum-types", + "jsonrpsee", + "rlp", + "rustc-hex", + "serde", + "serde_json", + "sp-core-hashing", +] + +[[package]] +name = "fc-storage" +version = "1.0.0-dev" +source = "git+https://github.com/OpenZeppelin/frontier?branch=polkadot-v1.7.0#8037bf8d7401357d321d837c9b92729519c81e45" +dependencies = [ + "ethereum", + "ethereum-types", + "fp-rpc", + "fp-storage", + "parity-scale-codec", + "sc-client-api", + "sp-api", + "sp-blockchain", + "sp-io", + "sp-runtime", + "sp-storage 19.0.0 (git+https://github.com/paritytech/polkadot-sdk?tag=polkadot-v1.7.0)", +] + [[package]] name = "fdlimit" version = "0.3.0" @@ -3303,12 +3506,38 @@ dependencies = [ "num-traits", ] +[[package]] +name = "flume" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55ac459de2512911e4b674ce33cf20befaba382d05b62b008afc1c8b57cbf181" +dependencies = [ + "futures-core", + "futures-sink", + "spin 0.9.8", +] + [[package]] name = "fnv" version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +dependencies = [ + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + [[package]] name = "fork-tree" version = "12.0.0" @@ -3357,6 +3586,16 @@ dependencies = [ "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk?tag=polkadot-v1.7.0)", ] +[[package]] +name = "fp-dynamic-fee" +version = "1.0.0" +source = "git+https://github.com/OpenZeppelin/frontier?branch=polkadot-v1.7.0#8037bf8d7401357d321d837c9b92729519c81e45" +dependencies = [ + "async-trait", + "sp-core", + "sp-inherents", +] + [[package]] name = "fp-ethereum" version = "1.0.0-dev" @@ -3403,6 +3642,18 @@ dependencies = [ "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk?tag=polkadot-v1.7.0)", ] +[[package]] +name = "fp-self-contained" +version = "1.0.0-dev" +source = "git+https://github.com/OpenZeppelin/frontier?branch=polkadot-v1.7.0#8037bf8d7401357d321d837c9b92729519c81e45" +dependencies = [ + "frame-support", + "parity-scale-codec", + "scale-info", + "serde", + "sp-runtime", +] + [[package]] name = "fp-storage" version = "2.0.0" @@ -3787,6 +4038,17 @@ dependencies = [ "num_cpus", ] +[[package]] +name = "futures-intrusive" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d930c203dd0b6ff06e0201a4a2fe9149b43c684fd4420555b26d21b1a02956f" +dependencies = [ + "futures-core", + "lock_api", + "parking_lot 0.12.1", +] + [[package]] name = "futures-io" version = "0.3.30" @@ -4085,6 +4347,9 @@ name = "heck" version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" +dependencies = [ + "unicode-segmentation", +] [[package]] name = "heck" @@ -5290,6 +5555,17 @@ dependencies = [ "libsecp256k1-core", ] +[[package]] +name = "libsqlite3-sys" +version = "0.27.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf4e226dcd58b4be396f7bd3c20da8fdee2911400705297ba7d2d7cc2c30f716" +dependencies = [ + "cc", + "pkg-config", + "vcpkg", +] + [[package]] name = "libz-sys" version = "1.1.16" @@ -5904,6 +6180,24 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a51313c5820b0b02bd422f4b44776fbf47961755c74ce64afc73bfad10226c3" +[[package]] +name = "native-tls" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e" +dependencies = [ + "lazy_static", + "libc", + "log", + "openssl", + "openssl-probe", + "openssl-sys", + "schannel", + "security-framework", + "security-framework-sys", + "tempfile", +] + [[package]] name = "netlink-packet-core" version = "0.4.2" @@ -6188,12 +6482,50 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" +[[package]] +name = "openssl" +version = "0.10.64" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95a0481286a310808298130d22dd1fef0fa571e05a8f44ec801801e84b216b1f" +dependencies = [ + "bitflags 2.5.0", + "cfg-if", + "foreign-types", + "libc", + "once_cell", + "openssl-macros", + "openssl-sys", +] + +[[package]] +name = "openssl-macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.59", +] + [[package]] name = "openssl-probe" version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" +[[package]] +name = "openssl-sys" +version = "0.9.102" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c597637d56fbc83893a35eb0dd04b2b8e7a50c91e64e9493e398b5df4fb45fa2" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + [[package]] name = "option-ext" version = "0.2.0" @@ -7464,6 +7796,15 @@ dependencies = [ "cumulus-primitives-core", "cumulus-primitives-parachain-inherent", "cumulus-relay-chain-interface", + "fc-api", + "fc-consensus", + "fc-db", + "fc-mapping-sync", + "fc-rpc", + "fc-rpc-core", + "fc-storage", + "fp-dynamic-fee", + "fp-rpc", "frame-benchmarking", "frame-benchmarking-cli", "futures", @@ -7479,6 +7820,7 @@ dependencies = [ "sc-cli", "sc-client-api", "sc-consensus", + "sc-consensus-aura", "sc-executor", "sc-network", "sc-network-sync", @@ -7497,6 +7839,7 @@ dependencies = [ "sp-blockchain", "sp-consensus-aura", "sp-core", + "sp-inherents", "sp-io", "sp-keystore", "sp-runtime", @@ -7523,6 +7866,7 @@ dependencies = [ "fp-account", "fp-evm", "fp-rpc", + "fp-self-contained", "frame-benchmarking", "frame-executive", "frame-support", @@ -12097,10 +12441,18 @@ dependencies = [ "zeroize", ] +[[package]] +name = "sp-core-hashing" +version = "15.0.0" +source = "git+https://github.com/paritytech/polkadot-sdk?tag=polkadot-v1.7.0#2fe3145ab9bd26ceb5a26baf2a64105b0035a5a6" +dependencies = [ + "sp-crypto-hashing", +] + [[package]] name = "sp-crypto-ec-utils" version = "0.10.0" -source = "git+https://github.com/paritytech/polkadot-sdk#c594b10a803e218f63c1bd97d2b27454efb4e852" +source = "git+https://github.com/paritytech/polkadot-sdk#115c2477eb287df55107cd95594100ba395ed239" dependencies = [ "ark-bls12-377", "ark-bls12-377-ext", @@ -12162,7 +12514,7 @@ dependencies = [ [[package]] name = "sp-debug-derive" version = "14.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk#c594b10a803e218f63c1bd97d2b27454efb4e852" +source = "git+https://github.com/paritytech/polkadot-sdk#115c2477eb287df55107cd95594100ba395ed239" dependencies = [ "proc-macro2", "quote", @@ -12183,7 +12535,7 @@ dependencies = [ [[package]] name = "sp-externalities" version = "0.25.0" -source = "git+https://github.com/paritytech/polkadot-sdk#c594b10a803e218f63c1bd97d2b27454efb4e852" +source = "git+https://github.com/paritytech/polkadot-sdk#115c2477eb287df55107cd95594100ba395ed239" dependencies = [ "environmental", "parity-scale-codec", @@ -12401,7 +12753,7 @@ dependencies = [ [[package]] name = "sp-runtime-interface" version = "24.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk#c594b10a803e218f63c1bd97d2b27454efb4e852" +source = "git+https://github.com/paritytech/polkadot-sdk#115c2477eb287df55107cd95594100ba395ed239" dependencies = [ "bytes", "impl-trait-for-tuples", @@ -12433,7 +12785,7 @@ dependencies = [ [[package]] name = "sp-runtime-interface-proc-macro" version = "17.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk#c594b10a803e218f63c1bd97d2b27454efb4e852" +source = "git+https://github.com/paritytech/polkadot-sdk#115c2477eb287df55107cd95594100ba395ed239" dependencies = [ "Inflector", "expander 2.1.0", @@ -12526,7 +12878,7 @@ source = "git+https://github.com/paritytech/polkadot-sdk?tag=polkadot-v1.7.0#2fe [[package]] name = "sp-std" version = "14.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk#c594b10a803e218f63c1bd97d2b27454efb4e852" +source = "git+https://github.com/paritytech/polkadot-sdk#115c2477eb287df55107cd95594100ba395ed239" [[package]] name = "sp-storage" @@ -12544,7 +12896,7 @@ dependencies = [ [[package]] name = "sp-storage" version = "19.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk#c594b10a803e218f63c1bd97d2b27454efb4e852" +source = "git+https://github.com/paritytech/polkadot-sdk#115c2477eb287df55107cd95594100ba395ed239" dependencies = [ "impl-serde", "parity-scale-codec", @@ -12581,7 +12933,7 @@ dependencies = [ [[package]] name = "sp-tracing" version = "16.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk#c594b10a803e218f63c1bd97d2b27454efb4e852" +source = "git+https://github.com/paritytech/polkadot-sdk#115c2477eb287df55107cd95594100ba395ed239" dependencies = [ "parity-scale-codec", "tracing", @@ -12681,7 +13033,7 @@ dependencies = [ [[package]] name = "sp-wasm-interface" version = "20.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk#c594b10a803e218f63c1bd97d2b27454efb4e852" +source = "git+https://github.com/paritytech/polkadot-sdk#115c2477eb287df55107cd95594100ba395ed239" dependencies = [ "impl-trait-for-tuples", "log", @@ -12714,6 +13066,9 @@ name = "spin" version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +dependencies = [ + "lock_api", +] [[package]] name = "spinners" @@ -12736,6 +13091,127 @@ dependencies = [ "der", ] +[[package]] +name = "sqlformat" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce81b7bd7c4493975347ef60d8c7e8b742d4694f4c49f93e0a12ea263938176c" +dependencies = [ + "itertools 0.12.1", + "nom", + "unicode_categories", +] + +[[package]] +name = "sqlx" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9a2ccff1a000a5a59cd33da541d9f2fdcd9e6e8229cc200565942bff36d0aaa" +dependencies = [ + "sqlx-core", + "sqlx-macros", + "sqlx-sqlite", +] + +[[package]] +name = "sqlx-core" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24ba59a9342a3d9bab6c56c118be528b27c9b60e490080e9711a04dccac83ef6" +dependencies = [ + "ahash 0.8.11", + "atoi", + "byteorder", + "bytes", + "crc", + "crossbeam-queue", + "either", + "event-listener 2.5.3", + "futures-channel", + "futures-core", + "futures-intrusive", + "futures-io", + "futures-util", + "hashlink", + "hex", + "indexmap 2.2.6", + "log", + "memchr", + "native-tls", + "once_cell", + "paste", + "percent-encoding", + "serde", + "sha2 0.10.8", + "smallvec", + "sqlformat", + "thiserror", + "tokio", + "tokio-stream", + "tracing", + "url", +] + +[[package]] +name = "sqlx-macros" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ea40e2345eb2faa9e1e5e326db8c34711317d2b5e08d0d5741619048a803127" +dependencies = [ + "proc-macro2", + "quote", + "sqlx-core", + "sqlx-macros-core", + "syn 1.0.109", +] + +[[package]] +name = "sqlx-macros-core" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5833ef53aaa16d860e92123292f1f6a3d53c34ba8b1969f152ef1a7bb803f3c8" +dependencies = [ + "dotenvy", + "either", + "heck 0.4.1", + "hex", + "once_cell", + "proc-macro2", + "quote", + "serde", + "serde_json", + "sha2 0.10.8", + "sqlx-core", + "sqlx-sqlite", + "syn 1.0.109", + "tempfile", + "tokio", + "url", +] + +[[package]] +name = "sqlx-sqlite" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b244ef0a8414da0bed4bb1910426e890b19e5e9bccc27ada6b797d05c55ae0aa" +dependencies = [ + "atoi", + "flume", + "futures-channel", + "futures-core", + "futures-executor", + "futures-intrusive", + "futures-util", + "libsqlite3-sys", + "log", + "percent-encoding", + "serde", + "sqlx-core", + "tracing", + "url", + "urlencoding", +] + [[package]] name = "ss58-registry" version = "1.47.0" @@ -13840,6 +14316,12 @@ dependencies = [ "tinyvec", ] +[[package]] +name = "unicode-segmentation" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202" + [[package]] name = "unicode-width" version = "0.1.11" @@ -13852,6 +14334,12 @@ version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" +[[package]] +name = "unicode_categories" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39ec24b3121d976906ece63c9daad25b85969647682eee313cb5779fdd69e14e" + [[package]] name = "universal-hash" version = "0.5.1" @@ -13897,6 +14385,12 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "urlencoding" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da" + [[package]] name = "utf8parse" version = "0.2.1" diff --git a/evm-template/Cargo.toml b/evm-template/Cargo.toml index f15f023..bba4032 100644 --- a/evm-template/Cargo.toml +++ b/evm-template/Cargo.toml @@ -59,6 +59,7 @@ sc-chain-spec = { git = "https://github.com/paritytech/polkadot-sdk", default-fe sc-cli = { git = "https://github.com/paritytech/polkadot-sdk", default-features = false, tag = "polkadot-v1.7.0" } sc-client-api = { git = "https://github.com/paritytech/polkadot-sdk", default-features = false, tag = "polkadot-v1.7.0" } sc-consensus = { git = "https://github.com/paritytech/polkadot-sdk", default-features = false, tag = "polkadot-v1.7.0" } +sc-consensus-aura = { git = "https://github.com/paritytech/polkadot-sdk", default-features = false, tag = "polkadot-v1.7.0" } sc-executor = { git = "https://github.com/paritytech/polkadot-sdk", default-features = false, tag = "polkadot-v1.7.0" } sc-network = { git = "https://github.com/paritytech/polkadot-sdk", default-features = false, tag = "polkadot-v1.7.0" } sc-network-sync = { git = "https://github.com/paritytech/polkadot-sdk", default-features = false, tag = "polkadot-v1.7.0" } @@ -129,9 +130,18 @@ parachain-info = { package = "staging-parachain-info", git = "https://github.com parachains-common = { git = "https://github.com/paritytech/polkadot-sdk", default-features = false, tag = "polkadot-v1.7.0" } # EVM +fc-api = { git = "https://github.com/OpenZeppelin/frontier", branch = "polkadot-v1.7.0", default-features = false } +fc-consensus = { git = "https://github.com/OpenZeppelin/frontier", branch = "polkadot-v1.7.0", default-features = false } +fc-db = { git = "https://github.com/OpenZeppelin/frontier", branch = "polkadot-v1.7.0", default-features = false } +fc-mapping-sync = { git = "https://github.com/OpenZeppelin/frontier", branch = "polkadot-v1.7.0", default-features = false } +fc-rpc = { git = "https://github.com/OpenZeppelin/frontier", branch = "polkadot-v1.7.0", default-features = false } +fc-rpc-core = { git = "https://github.com/OpenZeppelin/frontier", branch = "polkadot-v1.7.0", default-features = false } +fc-storage = { git = "https://github.com/OpenZeppelin/frontier", branch = "polkadot-v1.7.0", default-features = false } fp-account = { git = "https://github.com/OpenZeppelin/frontier", branch = "polkadot-v1.7.0", default-features = false, features = [ "serde" ] } +fp-dynamic-fee = { git = "https://github.com/OpenZeppelin/frontier", branch = "polkadot-v1.7.0", default-features = false } fp-evm = { git = "https://github.com/OpenZeppelin/frontier", branch = "polkadot-v1.7.0", default-features = false } fp-rpc = { git = "https://github.com/OpenZeppelin/frontier", branch = "polkadot-v1.7.0", default-features = false } +fp-self-contained = { git = "https://github.com/OpenZeppelin/frontier", branch = "polkadot-v1.7.0", default-features = false } pallet-base-fee = { git = "https://github.com/OpenZeppelin/frontier", branch = "polkadot-v1.7.0", default-features = false } pallet-ethereum = { git = "https://github.com/OpenZeppelin/frontier", branch = "polkadot-v1.7.0", default-features = false, features = [ "forbid-evm-reentrancy", diff --git a/evm-template/node/Cargo.toml b/evm-template/node/Cargo.toml index 5f0a36f..844a425 100644 --- a/evm-template/node/Cargo.toml +++ b/evm-template/node/Cargo.toml @@ -30,6 +30,7 @@ sc-chain-spec = { workspace = true } sc-cli = { workspace = true } sc-client-api = { workspace = true } sc-consensus = { workspace = true } +sc-consensus-aura = { workspace = true } sc-executor = { workspace = true } sc-network = { workspace = true } sc-network-sync = { workspace = true } @@ -46,6 +47,7 @@ sp-block-builder = { workspace = true } sp-blockchain = { workspace = true } sp-consensus-aura = { workspace = true } sp-core = { workspace = true } +sp-inherents = { workspace = true } sp-io = { workspace = true } sp-keystore = { workspace = true } sp-runtime = { workspace = true } @@ -70,6 +72,17 @@ cumulus-primitives-core = { workspace = true } cumulus-primitives-parachain-inherent = { workspace = true } cumulus-relay-chain-interface = { workspace = true } +# Frontier +fc-api = { workspace = true } +fc-consensus = { workspace = true } +fc-db = { workspace = true, features = [ "rocksdb" ] } +fc-mapping-sync = { workspace = true, features = [ "sql" ] } +fc-rpc = { workspace = true } +fc-rpc-core = { workspace = true } +fc-storage = { workspace = true } +fp-dynamic-fee = { workspace = true, features = [ "std" ] } +fp-rpc = { workspace = true } + [build-dependencies] substrate-build-script-utils = { workspace = true } diff --git a/evm-template/node/src/chain_spec.rs b/evm-template/node/src/chain_spec.rs index d4eb150..82e2db8 100644 --- a/evm-template/node/src/chain_spec.rs +++ b/evm-template/node/src/chain_spec.rs @@ -194,6 +194,9 @@ fn testnet_genesis( .collect::>(), }, "treasury": {}, + "evmChainId": { + "chainId": 9999 + }, "polkadotXcm": { "safeXcmVersion": Some(SAFE_XCM_VERSION), }, diff --git a/evm-template/node/src/cli.rs b/evm-template/node/src/cli.rs index e756900..2d5c8bf 100644 --- a/evm-template/node/src/cli.rs +++ b/evm-template/node/src/cli.rs @@ -1,5 +1,7 @@ use std::path::PathBuf; +use crate::eth::EthConfiguration; + /// Sub-commands supported by the collator. #[derive(Debug, clap::Subcommand)] pub enum Subcommand { @@ -84,6 +86,9 @@ pub struct Cli { /// Relay chain arguments #[arg(raw = true)] pub relay_chain_args: Vec, + + #[command(flatten)] + pub eth: EthConfiguration, } #[derive(Debug)] diff --git a/evm-template/node/src/command.rs b/evm-template/node/src/command.rs index e25b16d..deceaa4 100644 --- a/evm-template/node/src/command.rs +++ b/evm-template/node/src/command.rs @@ -99,8 +99,9 @@ impl SubstrateCli for RelayChainCli { macro_rules! construct_async_run { (|$components:ident, $cli:ident, $cmd:ident, $config:ident| $( $code:tt )* ) => {{ let runner = $cli.create_runner($cmd)?; + let eth = $cli.eth.clone(); runner.async_run(|$config| { - let $components = new_partial(&$config)?; + let $components = new_partial(&$config, ð)?; let task_manager = $components.task_manager; { $( $code )* }.map(|v| (v, task_manager)) }) @@ -163,7 +164,7 @@ pub fn run() -> Result<()> { Some(Subcommand::ExportGenesisHead(cmd)) => { let runner = cli.create_runner(cmd)?; runner.sync_run(|config| { - let partials = new_partial(&config)?; + let partials = new_partial(&config, &cli.eth)?; cmd.run(partials.client) }) @@ -188,7 +189,7 @@ pub fn run() -> Result<()> { .into()) }, BenchmarkCmd::Block(cmd) => runner.sync_run(|config| { - let partials = new_partial(&config)?; + let partials = new_partial(&config, &cli.eth)?; cmd.run(partials.client) }), #[cfg(not(feature = "runtime-benchmarks"))] @@ -200,7 +201,7 @@ pub fn run() -> Result<()> { )), #[cfg(feature = "runtime-benchmarks")] BenchmarkCmd::Storage(cmd) => runner.sync_run(|config| { - let partials = new_partial(&config)?; + let partials = new_partial(&config, &cli.eth)?; let db = partials.backend.expose_db(); let storage = partials.backend.expose_storage(); cmd.run(config, partials.client.clone(), db, storage) @@ -254,6 +255,7 @@ pub fn run() -> Result<()> { config, polkadot_config, collator_options, + &cli.eth, id, hwbench, ) diff --git a/evm-template/node/src/eth.rs b/evm-template/node/src/eth.rs new file mode 100644 index 0000000..87f4943 --- /dev/null +++ b/evm-template/node/src/eth.rs @@ -0,0 +1,208 @@ +use std::{ + collections::BTreeMap, + path::PathBuf, + sync::{Arc, Mutex}, + time::Duration, +}; + +use fc_rpc::{EthTask, OverrideHandle}; +pub use fc_rpc_core::types::{FeeHistoryCache, FeeHistoryCacheLimit, FilterPool}; +use futures::{future, prelude::*}; +// Local +use parachain_template_runtime::opaque::Block; +// Substrate +use sc_client_api::BlockchainEvents; +use sc_executor::{NativeElseWasmExecutor, NativeExecutionDispatch}; +use sc_network_sync::SyncingService; +use sc_service::{error::Error as ServiceError, Configuration, TaskManager}; +use sp_api::ConstructRuntimeApi; + +/// Full backend. +pub type FullBackend = sc_service::TFullBackend; +/// Full client. +pub type FullClient = + sc_service::TFullClient>; + +/// Frontier DB backend type. +pub type FrontierBackend = fc_db::Backend; + +pub fn db_config_dir(config: &Configuration) -> PathBuf { + config.base_path.config_dir(config.chain_spec.id()) +} + +/// Avalailable frontier backend types. +#[derive(Debug, Copy, Clone, Default, clap::ValueEnum)] +pub enum BackendType { + /// Either RocksDb or ParityDb as per inherited from the global backend settings. + #[default] + KeyValue, + /// Sql database with custom log indexing. + Sql, +} + +/// The ethereum-compatibility configuration used to run a node. +#[derive(Clone, Debug, clap::Parser)] +pub struct EthConfiguration { + /// Maximum number of logs in a query. + #[arg(long, default_value = "10000")] + pub max_past_logs: u32, + + /// Maximum fee history cache size. + #[arg(long, default_value = "2048")] + pub fee_history_limit: u64, + + #[arg(long)] + pub enable_dev_signer: bool, + + /// The dynamic-fee pallet target gas price set by block author + #[arg(long, default_value = "1")] + pub target_gas_price: u64, + + /// Maximum allowed gas limit will be `block.gas_limit * execute_gas_limit_multiplier` + /// when using eth_call/eth_estimateGas. + #[arg(long, default_value = "10")] + pub execute_gas_limit_multiplier: u64, + + /// Size in bytes of the LRU cache for block data. + #[arg(long, default_value = "50")] + pub eth_log_block_cache: usize, + + /// Size in bytes of the LRU cache for transactions statuses data. + #[arg(long, default_value = "50")] + pub eth_statuses_cache: usize, + + /// Sets the frontier backend type (KeyValue or Sql) + #[arg(long, value_enum, ignore_case = true, default_value_t = BackendType::default())] + pub frontier_backend_type: BackendType, + + // Sets the SQL backend's pool size. + #[arg(long, default_value = "100")] + pub frontier_sql_backend_pool_size: u32, + + /// Sets the SQL backend's query timeout in number of VM ops. + #[arg(long, default_value = "10000000")] + pub frontier_sql_backend_num_ops_timeout: u32, + + /// Sets the SQL backend's auxiliary thread limit. + #[arg(long, default_value = "4")] + pub frontier_sql_backend_thread_count: u32, + + /// Sets the SQL backend's query timeout in number of VM ops. + /// Default value is 200MB. + #[arg(long, default_value = "209715200")] + pub frontier_sql_backend_cache_size: u64, +} + +pub struct FrontierPartialComponents { + pub filter_pool: Option, + pub fee_history_cache: FeeHistoryCache, + pub fee_history_cache_limit: FeeHistoryCacheLimit, +} + +pub fn new_frontier_partial( + config: &EthConfiguration, +) -> Result { + Ok(FrontierPartialComponents { + filter_pool: Some(Arc::new(Mutex::new(BTreeMap::new()))), + fee_history_cache: Arc::new(Mutex::new(BTreeMap::new())), + fee_history_cache_limit: config.fee_history_limit, + }) +} + +/// A set of APIs that ethereum-compatible runtimes must implement. +pub trait EthCompatRuntimeApiCollection: + sp_api::ApiExt + + fp_rpc::ConvertTransactionRuntimeApi + + fp_rpc::EthereumRuntimeRPCApi +{ +} + +impl EthCompatRuntimeApiCollection for Api where + Api: sp_api::ApiExt + + fp_rpc::ConvertTransactionRuntimeApi + + fp_rpc::EthereumRuntimeRPCApi +{ +} + +pub async fn spawn_frontier_tasks( + task_manager: &TaskManager, + client: Arc>, + backend: Arc, + frontier_backend: FrontierBackend, + filter_pool: Option, + overrides: Arc>, + fee_history_cache: FeeHistoryCache, + fee_history_cache_limit: FeeHistoryCacheLimit, + sync: Arc>, + pubsub_notification_sinks: Arc< + fc_mapping_sync::EthereumBlockNotificationSinks< + fc_mapping_sync::EthereumBlockNotification, + >, + >, +) where + RuntimeApi: ConstructRuntimeApi>, + RuntimeApi: Send + Sync + 'static, + RuntimeApi::RuntimeApi: EthCompatRuntimeApiCollection, + Executor: NativeExecutionDispatch + 'static, +{ + // Spawn main mapping sync worker background task. + match frontier_backend { + fc_db::Backend::KeyValue(b) => { + task_manager.spawn_essential_handle().spawn( + "frontier-mapping-sync-worker", + Some("frontier"), + fc_mapping_sync::kv::MappingSyncWorker::new( + client.import_notification_stream(), + Duration::new(6, 0), + client.clone(), + backend, + overrides.clone(), + Arc::new(b), + 3, + 0, + fc_mapping_sync::SyncStrategy::Normal, + sync, + pubsub_notification_sinks, + ) + .for_each(|()| future::ready(())), + ); + } + fc_db::Backend::Sql(b) => { + task_manager.spawn_essential_handle().spawn_blocking( + "frontier-mapping-sync-worker", + Some("frontier"), + fc_mapping_sync::sql::SyncWorker::run( + client.clone(), + backend, + Arc::new(b), + client.import_notification_stream(), + fc_mapping_sync::sql::SyncWorkerConfig { + read_notification_timeout: Duration::from_secs(10), + check_indexed_blocks_interval: Duration::from_secs(60), + }, + fc_mapping_sync::SyncStrategy::Parachain, + sync, + pubsub_notification_sinks, + ), + ); + } + } + + // Spawn Frontier EthFilterApi maintenance task. + if let Some(filter_pool) = filter_pool { + // Each filter is allowed to stay in the pool for 100 blocks. + const FILTER_RETAIN_THRESHOLD: u64 = 100; + task_manager.spawn_essential_handle().spawn( + "frontier-filter-pool", + Some("frontier"), + EthTask::filter_pool_task(client.clone(), filter_pool, FILTER_RETAIN_THRESHOLD), + ); + } + + // Spawn Frontier FeeHistory cache maintenance task. + task_manager.spawn_essential_handle().spawn( + "frontier-fee-history", + Some("frontier"), + EthTask::fee_history_task(client, overrides, fee_history_cache, fee_history_cache_limit), + ); +} diff --git a/evm-template/node/src/main.rs b/evm-template/node/src/main.rs index fd65f2c..ec52427 100644 --- a/evm-template/node/src/main.rs +++ b/evm-template/node/src/main.rs @@ -7,6 +7,7 @@ mod chain_spec; mod service; mod cli; mod command; +mod eth; mod rpc; fn main() -> sc_cli::Result<()> { diff --git a/evm-template/node/src/rpc.rs b/evm-template/node/src/rpc.rs deleted file mode 100644 index d5a4755..0000000 --- a/evm-template/node/src/rpc.rs +++ /dev/null @@ -1,57 +0,0 @@ -//! A collection of node-specific RPC methods. -//! Substrate provides the `sc-rpc` crate, which defines the core RPC layer -//! used by Substrate nodes. This file extends those RPC definitions with -//! capabilities that are specific to this project's runtime configuration. - -#![warn(missing_docs)] - -use std::sync::Arc; - -use parachain_template_runtime::{opaque::Block, AccountId, Balance, Nonce}; -use sc_client_api::AuxStore; -pub use sc_rpc::DenyUnsafe; -use sc_transaction_pool_api::TransactionPool; -use sp_api::ProvideRuntimeApi; -use sp_block_builder::BlockBuilder; -use sp_blockchain::{Error as BlockChainError, HeaderBackend, HeaderMetadata}; - -/// A type representing all RPC extensions. -pub type RpcExtension = jsonrpsee::RpcModule<()>; - -/// Full client dependencies -pub struct FullDeps { - /// The client instance to use. - pub client: Arc, - /// Transaction pool instance. - pub pool: Arc

, - /// Whether to deny unsafe calls - pub deny_unsafe: DenyUnsafe, -} - -/// Instantiate all RPC extensions. -pub fn create_full( - deps: FullDeps, -) -> Result> -where - C: ProvideRuntimeApi - + HeaderBackend - + AuxStore - + HeaderMetadata - + Send - + Sync - + 'static, - C::Api: pallet_transaction_payment_rpc::TransactionPaymentRuntimeApi, - C::Api: substrate_frame_rpc_system::AccountNonceApi, - C::Api: BlockBuilder, - P: TransactionPool + Sync + Send + 'static, -{ - use pallet_transaction_payment_rpc::{TransactionPayment, TransactionPaymentApiServer}; - use substrate_frame_rpc_system::{System, SystemApiServer}; - - let mut module = RpcExtension::new(()); - let FullDeps { client, pool, deny_unsafe } = deps; - - module.merge(System::new(client.clone(), pool, deny_unsafe).into_rpc())?; - module.merge(TransactionPayment::new(client).into_rpc())?; - Ok(module) -} diff --git a/evm-template/node/src/rpc/eth.rs b/evm-template/node/src/rpc/eth.rs new file mode 100644 index 0000000..4360956 --- /dev/null +++ b/evm-template/node/src/rpc/eth.rs @@ -0,0 +1,198 @@ +use std::{collections::BTreeMap, sync::Arc}; + +// Frontier +pub use fc_rpc::{EthBlockDataCacheTask, EthConfig, OverrideHandle}; +pub use fc_rpc_core::types::{FeeHistoryCache, FeeHistoryCacheLimit, FilterPool}; +pub use fc_storage::overrides_handle; +use fp_rpc::{ConvertTransaction, ConvertTransactionRuntimeApi, EthereumRuntimeRPCApi}; +use jsonrpsee::RpcModule; +// Substrate +use sc_client_api::{ + backend::{Backend, StorageProvider}, + client::BlockchainEvents, + AuxStore, UsageProvider, +}; +use sc_network::NetworkService; +use sc_network_sync::SyncingService; +use sc_rpc::SubscriptionTaskExecutor; +use sc_transaction_pool::{ChainApi, Pool}; +use sc_transaction_pool_api::TransactionPool; +use sp_api::{CallApiAt, ProvideRuntimeApi}; +use sp_block_builder::BlockBuilder as BlockBuilderApi; +use sp_blockchain::{Error as BlockChainError, HeaderBackend, HeaderMetadata}; +use sp_consensus_aura::{sr25519::AuthorityId as AuraId, AuraApi}; +use sp_core::H256; +use sp_inherents::CreateInherentDataProviders; +use sp_runtime::traits::Block as BlockT; + +/// Extra dependencies for Ethereum compatibility. +pub struct EthDeps { + /// The client instance to use. + pub client: Arc, + /// Transaction pool instance. + pub pool: Arc

, + /// Graph pool instance. + pub graph: Arc>, + /// Ethereum transaction converter. + pub converter: Option, + /// The Node authority flag + pub is_authority: bool, + /// Whether to enable dev signer + pub enable_dev_signer: bool, + /// Network service + pub network: Arc>, + /// Chain syncing service + pub sync: Arc>, + /// Frontier Backend. + pub frontier_backend: Arc>, + /// Ethereum data access overrides. + pub overrides: Arc>, + /// Cache for Ethereum block data. + pub block_data_cache: Arc>, + /// EthFilterApi pool. + pub filter_pool: Option, + /// Maximum number of logs in a query. + pub max_past_logs: u32, + /// Fee history cache. + pub fee_history_cache: FeeHistoryCache, + /// Maximum fee history cache size. + pub fee_history_cache_limit: FeeHistoryCacheLimit, + /// Maximum allowed gas limit will be ` block.gas_limit * execute_gas_limit_multiplier` when + /// using eth_call/eth_estimateGas. + pub execute_gas_limit_multiplier: u64, + /// Mandated parent hashes for a given block hash. + pub forced_parent_hashes: Option>, + /// Something that can create the inherent data providers for pending state + pub pending_create_inherent_data_providers: CIDP, +} + +/// Instantiate Ethereum-compatible RPC extensions. +pub fn create_eth( + mut io: RpcModule<()>, + deps: EthDeps, + subscription_task_executor: SubscriptionTaskExecutor, + pubsub_notification_sinks: Arc< + fc_mapping_sync::EthereumBlockNotificationSinks< + fc_mapping_sync::EthereumBlockNotification, + >, + >, +) -> Result, Box> +where + B: BlockT, + C: CallApiAt + ProvideRuntimeApi, + C::Api: AuraApi + + BlockBuilderApi + + ConvertTransactionRuntimeApi + + EthereumRuntimeRPCApi, + C: HeaderBackend + HeaderMetadata, + C: BlockchainEvents + AuxStore + UsageProvider + StorageProvider + 'static, + BE: Backend + 'static, + P: TransactionPool + 'static, + A: ChainApi + 'static, + CT: ConvertTransaction<::Extrinsic> + Send + Sync + 'static, + CIDP: CreateInherentDataProviders + Send + 'static, + EC: EthConfig, +{ + use fc_rpc::{ + pending::AuraConsensusDataProvider, Debug, DebugApiServer, Eth, EthApiServer, EthDevSigner, + EthFilter, EthFilterApiServer, EthPubSub, EthPubSubApiServer, EthSigner, Net, NetApiServer, + Web3, Web3ApiServer, + }; + #[cfg(feature = "txpool")] + use fc_rpc::{TxPool, TxPoolApiServer}; + + let EthDeps { + client, + pool, + graph, + converter, + is_authority, + enable_dev_signer, + network, + sync, + frontier_backend, + overrides, + block_data_cache, + filter_pool, + max_past_logs, + fee_history_cache, + fee_history_cache_limit, + execute_gas_limit_multiplier, + forced_parent_hashes, + pending_create_inherent_data_providers, + } = deps; + + let mut signers = Vec::new(); + if enable_dev_signer { + signers.push(Box::new(EthDevSigner::new()) as Box); + } + + io.merge( + Eth::::new( + client.clone(), + pool.clone(), + graph.clone(), + converter, + sync.clone(), + signers, + overrides.clone(), + frontier_backend.clone(), + is_authority, + block_data_cache.clone(), + fee_history_cache, + fee_history_cache_limit, + execute_gas_limit_multiplier, + forced_parent_hashes, + pending_create_inherent_data_providers, + Some(Box::new(AuraConsensusDataProvider::new(client.clone()))), + ) + .replace_config::() + .into_rpc(), + )?; + + if let Some(filter_pool) = filter_pool { + io.merge( + EthFilter::new( + client.clone(), + frontier_backend.clone(), + graph.clone(), + filter_pool, + 500_usize, // max stored filters + max_past_logs, + block_data_cache.clone(), + ) + .into_rpc(), + )?; + } + + io.merge( + EthPubSub::new( + pool, + client.clone(), + sync, + subscription_task_executor, + overrides.clone(), + pubsub_notification_sinks, + ) + .into_rpc(), + )?; + + io.merge( + Net::new( + client.clone(), + network, + // Whether to format the `peer_count` response as Hex (default) or not. + true, + ) + .into_rpc(), + )?; + + io.merge(Web3::new(client.clone()).into_rpc())?; + + io.merge(Debug::new(client.clone(), frontier_backend, overrides, block_data_cache).into_rpc())?; + + #[cfg(feature = "txpool")] + io.merge(TxPool::new(client, graph).into_rpc())?; + + Ok(io) +} diff --git a/evm-template/node/src/rpc/mod.rs b/evm-template/node/src/rpc/mod.rs new file mode 100644 index 0000000..664eec3 --- /dev/null +++ b/evm-template/node/src/rpc/mod.rs @@ -0,0 +1,102 @@ +//! A collection of node-specific RPC methods. +//! Substrate provides the `sc-rpc` crate, which defines the core RPC layer +//! used by Substrate nodes. This file extends those RPC definitions with +//! capabilities that are specific to this project's runtime configuration. + +#![warn(missing_docs)] +mod eth; +use std::sync::Arc; + +use parachain_template_runtime::{opaque::Block, AccountId, Balance, Nonce}; +use sc_client_api::{backend::Backend, AuxStore, BlockchainEvents, StorageProvider, UsageProvider}; +pub use sc_rpc::DenyUnsafe; +use sc_rpc::SubscriptionTaskExecutor; +use sc_transaction_pool::ChainApi; +use sc_transaction_pool_api::TransactionPool; +use sp_api::{CallApiAt, ProvideRuntimeApi}; +use sp_block_builder::BlockBuilder; +use sp_blockchain::{Error as BlockChainError, HeaderBackend, HeaderMetadata}; +use sp_consensus_aura::sr25519::AuthorityId as AuraId; +use sp_inherents::CreateInherentDataProviders; +use sp_runtime::traits::Block as BlockT; + +pub use self::eth::{overrides_handle, EthDeps}; +use crate::rpc::eth::create_eth; + +/// A type representing all RPC extensions. +pub type RpcExtension = jsonrpsee::RpcModule<()>; + +/// Full client dependencies +pub struct FullDeps { + /// The client instance to use. + pub client: Arc, + /// Transaction pool instance. + pub pool: Arc

, + /// Whether to deny unsafe calls + pub deny_unsafe: DenyUnsafe, + /// Ethereum-compatibility specific dependencies. + pub eth: EthDeps, +} + +pub struct DefaultEthConfig(std::marker::PhantomData<(C, BE)>); + +impl fc_rpc::EthConfig for DefaultEthConfig +where + C: StorageProvider + Sync + Send + 'static, + BE: Backend + 'static, +{ + type EstimateGasAdapter = (); + type RuntimeStorageOverride = + fc_rpc::frontier_backend_client::SystemAccountId20StorageOverride; +} + +/// Instantiate all RPC extensions. +pub fn create_full( + deps: FullDeps, + subscription_task_executor: SubscriptionTaskExecutor, + pubsub_notification_sinks: Arc< + fc_mapping_sync::EthereumBlockNotificationSinks< + fc_mapping_sync::EthereumBlockNotification, + >, + >, +) -> Result> +where + C: ProvideRuntimeApi + + HeaderBackend + + AuxStore + + HeaderMetadata + + Send + + Sync + + CallApiAt + + UsageProvider + + StorageProvider + + BlockchainEvents + + 'static, + C::Api: pallet_transaction_payment_rpc::TransactionPaymentRuntimeApi, + C::Api: substrate_frame_rpc_system::AccountNonceApi, + C::Api: sp_consensus_aura::AuraApi, + C::Api: BlockBuilder, + C::Api: fp_rpc::ConvertTransactionRuntimeApi, + C::Api: fp_rpc::EthereumRuntimeRPCApi, + P: TransactionPool + Sync + Send + 'static, + A: ChainApi + 'static, + CIDP: CreateInherentDataProviders + Send + 'static, + CT: fp_rpc::ConvertTransaction<::Extrinsic> + Send + Sync + 'static, + BE: Backend + 'static, +{ + use pallet_transaction_payment_rpc::{TransactionPayment, TransactionPaymentApiServer}; + use substrate_frame_rpc_system::{System, SystemApiServer}; + + let mut module = RpcExtension::new(()); + let FullDeps { client, pool, deny_unsafe, eth } = deps; + + module.merge(System::new(client.clone(), pool, deny_unsafe).into_rpc())?; + module.merge(TransactionPayment::new(client).into_rpc())?; + let module = create_eth::<_, _, _, _, _, _, _, DefaultEthConfig>( + module, + eth, + subscription_task_executor, + pubsub_notification_sinks, + )?; + Ok(module) +} diff --git a/evm-template/node/src/service.rs b/evm-template/node/src/service.rs index 1e2c096..12340c6 100644 --- a/evm-template/node/src/service.rs +++ b/evm-template/node/src/service.rs @@ -2,7 +2,7 @@ //! substrate service. // std -use std::{sync::Arc, time::Duration}; +use std::{path::Path, sync::Arc, time::Duration}; use cumulus_client_cli::CollatorOptions; // Cumulus Imports @@ -22,7 +22,7 @@ use frame_benchmarking_cli::SUBSTRATE_REFERENCE_HARDWARE; // Local Runtime Types use parachain_template_runtime::{ opaque::{Block, Hash}, - RuntimeApi, + RuntimeApi, TransactionConverter, }; use sc_client_api::Backend; use sc_consensus::ImportQueue; @@ -34,9 +34,15 @@ use sc_network_sync::SyncingService; use sc_service::{Configuration, PartialComponents, TFullBackend, TFullClient, TaskManager}; use sc_telemetry::{Telemetry, TelemetryHandle, TelemetryWorker, TelemetryWorkerHandle}; use sc_transaction_pool_api::OffchainTransactionPoolFactory; +use sp_core::U256; use sp_keystore::KeystorePtr; use substrate_prometheus_endpoint::Registry; +use crate::eth::{ + db_config_dir, new_frontier_partial, spawn_frontier_tasks, BackendType, EthConfiguration, + FrontierBackend, FrontierPartialComponents, +}; + /// Native executor type. pub struct ParachainNativeExecutor; @@ -66,6 +72,7 @@ type ParachainBlockImport = TParachainBlockImport, P /// builder in order to be able to perform chain operations. pub fn new_partial( config: &Configuration, + eth_config: &EthConfiguration, ) -> Result< PartialComponents< ParachainClient, @@ -73,7 +80,13 @@ pub fn new_partial( (), sc_consensus::DefaultImportQueue, sc_transaction_pool::FullPool, - (ParachainBlockImport, Option, Option), + ( + ParachainBlockImport, + Option, + Option, + FrontierBackend, + Arc>, + ), >, sc_service::Error, > { @@ -135,6 +148,37 @@ pub fn new_partial( &task_manager, )?; + let overrides = crate::rpc::overrides_handle(client.clone()); + + let frontier_backend = match eth_config.frontier_backend_type { + BackendType::KeyValue => FrontierBackend::KeyValue(fc_db::kv::Backend::open( + Arc::clone(&client), + &config.database, + &db_config_dir(config), + )?), + BackendType::Sql => { + let db_path = db_config_dir(config).join("sql"); + std::fs::create_dir_all(&db_path).expect("failed creating sql db directory"); + let backend = futures::executor::block_on(fc_db::sql::Backend::new( + fc_db::sql::BackendConfig::Sqlite(fc_db::sql::SqliteBackendConfig { + path: Path::new("sqlite:///") + .join(db_path) + .join("frontier.db3") + .to_str() + .unwrap(), + create_if_missing: true, + thread_count: eth_config.frontier_sql_backend_thread_count, + cache_size: eth_config.frontier_sql_backend_cache_size, + }), + eth_config.frontier_sql_backend_pool_size, + std::num::NonZeroU32::new(eth_config.frontier_sql_backend_num_ops_timeout), + overrides.clone(), + )) + .unwrap_or_else(|err| panic!("failed creating sql backend: {:?}", err)); + FrontierBackend::Sql(backend) + } + }; + Ok(PartialComponents { backend, client, @@ -143,7 +187,7 @@ pub fn new_partial( task_manager, transaction_pool, select_chain: (), - other: (block_import, telemetry, telemetry_worker_handle), + other: (block_import, telemetry, telemetry_worker_handle, frontier_backend, overrides), }) } @@ -157,13 +201,19 @@ async fn start_node_impl( parachain_config: Configuration, polkadot_config: Configuration, collator_options: CollatorOptions, + eth_config: &EthConfiguration, para_id: ParaId, hwbench: Option, ) -> sc_service::error::Result<(TaskManager, Arc)> { let parachain_config = prepare_node_config(parachain_config); - let params = new_partial(¶chain_config)?; - let (block_import, mut telemetry, telemetry_worker_handle) = params.other; + let params = new_partial(¶chain_config, eth_config)?; + + let FrontierPartialComponents { filter_pool, fee_history_cache, fee_history_cache_limit } = + new_frontier_partial(eth_config)?; + + let (block_import, mut telemetry, telemetry_worker_handle, frontier_backend, overrides) = + params.other; let net_config = sc_network::config::FullNetworkConfiguration::new(¶chain_config.network); let client = params.client.clone(); @@ -185,6 +235,7 @@ async fn start_node_impl( let prometheus_registry = parachain_config.prometheus_registry().cloned(); let transaction_pool = params.transaction_pool.clone(); let import_queue_service = params.import_queue.service(); + let slot_duration = sc_consensus_aura::slot_duration(&*client)?; let (network, system_rpc_tx, tx_handler_controller, start_network, sync_service) = build_network(BuildNetworkParams { @@ -223,18 +274,81 @@ async fn start_node_impl( ); } + let pubsub_notification_sinks: fc_mapping_sync::EthereumBlockNotificationSinks< + fc_mapping_sync::EthereumBlockNotification, + > = Default::default(); + let pubsub_notification_sinks = Arc::new(pubsub_notification_sinks); + let rpc_builder = { let client = client.clone(); let transaction_pool = transaction_pool.clone(); + let target_gas_price = eth_config.target_gas_price; + let enable_dev_signer = eth_config.enable_dev_signer; + let pending_create_inherent_data_providers = move |_, ()| async move { + let current = sp_timestamp::InherentDataProvider::from_system_time(); + let next_slot = current.timestamp().as_millis() + slot_duration.as_millis(); + let timestamp = sp_timestamp::InherentDataProvider::new(next_slot.into()); + let slot = sp_consensus_aura::inherents::InherentDataProvider::from_timestamp_and_slot_duration( + *timestamp, + slot_duration, + ); + let dynamic_fee = fp_dynamic_fee::InherentDataProvider(U256::from(target_gas_price)); + Ok((slot, timestamp, dynamic_fee)) + }; + let block_data_cache = Arc::new(fc_rpc::EthBlockDataCacheTask::new( + task_manager.spawn_handle(), + overrides.clone(), + eth_config.eth_log_block_cache, + eth_config.eth_statuses_cache, + prometheus_registry.clone(), + )); + let execute_gas_limit_multiplier = eth_config.execute_gas_limit_multiplier; + let max_past_logs = eth_config.max_past_logs; + let network = network.clone(); + let sync_service = sync_service.clone(); + let frontier_backend = frontier_backend.clone(); + let filter_pool = filter_pool.clone(); + let overrides = overrides.clone(); + let fee_history_cache = fee_history_cache.clone(); + let pubsub_notification_sinks = pubsub_notification_sinks.clone(); - Box::new(move |deny_unsafe, _| { + Box::new(move |deny_unsafe, subscription_task_executor| { + let eth = crate::rpc::EthDeps { + client: client.clone(), + pool: transaction_pool.clone(), + graph: transaction_pool.pool().clone(), + converter: Some(TransactionConverter), + is_authority: validator, + enable_dev_signer, + network: network.clone(), + sync: sync_service.clone(), + frontier_backend: match frontier_backend.clone() { + fc_db::Backend::KeyValue(b) => Arc::new(b), + fc_db::Backend::Sql(b) => Arc::new(b), + }, + overrides: overrides.clone(), + block_data_cache: block_data_cache.clone(), + filter_pool: filter_pool.clone(), + max_past_logs, + fee_history_cache: fee_history_cache.clone(), + fee_history_cache_limit, + execute_gas_limit_multiplier, + forced_parent_hashes: None, + pending_create_inherent_data_providers, + }; let deps = crate::rpc::FullDeps { client: client.clone(), pool: transaction_pool.clone(), deny_unsafe, + eth, }; - crate::rpc::create_full(deps).map_err(Into::into) + crate::rpc::create_full( + deps, + subscription_task_executor, + pubsub_notification_sinks.clone(), + ) + .map_err(Into::into) }) }; @@ -245,9 +359,6 @@ async fn start_node_impl( task_manager: &mut task_manager, config: parachain_config, keystore: params.keystore_container.keystore(), - #[cfg(not(feature = "async-backing"))] - backend, - #[cfg(feature = "async-backing")] backend: backend.clone(), network: network.clone(), sync_service: sync_service.clone(), @@ -311,6 +422,20 @@ async fn start_node_impl( sync_service: sync_service.clone(), })?; + spawn_frontier_tasks( + &task_manager, + client.clone(), + backend.clone(), + frontier_backend, + filter_pool, + overrides, + fee_history_cache, + fee_history_cache_limit, + sync_service.clone(), + pubsub_notification_sinks, + ) + .await; + if validator { start_consensus( client.clone(), @@ -464,8 +589,17 @@ pub async fn start_parachain_node( parachain_config: Configuration, polkadot_config: Configuration, collator_options: CollatorOptions, + eth_config: &EthConfiguration, para_id: ParaId, hwbench: Option, ) -> sc_service::error::Result<(TaskManager, Arc)> { - start_node_impl(parachain_config, polkadot_config, collator_options, para_id, hwbench).await + start_node_impl( + parachain_config, + polkadot_config, + collator_options, + eth_config, + para_id, + hwbench, + ) + .await } diff --git a/evm-template/runtime/Cargo.toml b/evm-template/runtime/Cargo.toml index c371f4d..4c1b056 100644 --- a/evm-template/runtime/Cargo.toml +++ b/evm-template/runtime/Cargo.toml @@ -86,6 +86,7 @@ parachains-common = { workspace = true } fp-account = { workspace = true } fp-evm = { workspace = true } fp-rpc = { workspace = true } +fp-self-contained = { workspace = true, features = [ "serde" ] } pallet-base-fee = { workspace = true } pallet-ethereum = { workspace = true } pallet-evm = { workspace = true } @@ -112,6 +113,7 @@ std = [ "fp-account/std", "fp-evm/std", "fp-rpc/std", + "fp-self-contained/std", "frame-benchmarking?/std", "frame-executive/std", "frame-support/std", @@ -211,6 +213,7 @@ try-runtime = [ "cumulus-pallet-parachain-system/try-runtime", "cumulus-pallet-xcm/try-runtime", "cumulus-pallet-xcmp-queue/try-runtime", + "fp-self-contained/try-runtime", "frame-executive/try-runtime", "frame-support/try-runtime", "frame-system/try-runtime", diff --git a/evm-template/runtime/src/lib.rs b/evm-template/runtime/src/lib.rs index 68acc6b..ca40b8d 100644 --- a/evm-template/runtime/src/lib.rs +++ b/evm-template/runtime/src/lib.rs @@ -66,10 +66,10 @@ pub use sp_runtime::BuildStorage; use sp_runtime::{ create_runtime_str, generic, impl_opaque_keys, traits::{ - AccountIdLookup, BlakeTwo256, Block as BlockT, Get, IdentifyAccount, IdentityLookup, - UniqueSaturatedInto, Verify, + AccountIdLookup, BlakeTwo256, Block as BlockT, DispatchInfoOf, Dispatchable, Get, + IdentifyAccount, IdentityLookup, PostDispatchInfoOf, UniqueSaturatedInto, Verify, }, - transaction_validity::{TransactionSource, TransactionValidity}, + transaction_validity::{TransactionSource, TransactionValidity, TransactionValidityError}, ApplyExtrinsicResult, ConsensusEngineId, RuntimeDebug, }; pub use sp_runtime::{MultiAddress, Perbill, Permill}; @@ -139,7 +139,63 @@ pub type SignedExtra = ( /// Unchecked extrinsic type as expected by this runtime. pub type UncheckedExtrinsic = - generic::UncheckedExtrinsic; + fp_self_contained::UncheckedExtrinsic; + +impl fp_self_contained::SelfContainedCall for RuntimeCall { + type SignedInfo = H160; + + fn is_self_contained(&self) -> bool { + match self { + RuntimeCall::Ethereum(call) => call.is_self_contained(), + _ => false, + } + } + + fn check_self_contained(&self) -> Option> { + match self { + RuntimeCall::Ethereum(call) => call.check_self_contained(), + _ => None, + } + } + + fn validate_self_contained( + &self, + info: &Self::SignedInfo, + dispatch_info: &DispatchInfoOf, + len: usize, + ) -> Option { + match self { + RuntimeCall::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 { + RuntimeCall::Ethereum(call) => + call.pre_dispatch_self_contained(info, dispatch_info, len), + _ => None, + } + } + + fn apply_self_contained( + self, + info: Self::SignedInfo, + ) -> Option>> { + match self { + call @ RuntimeCall::Ethereum(pallet_ethereum::Call::transact { .. }) => + Some(call.dispatch(RuntimeOrigin::from( + pallet_ethereum::RawOrigin::EthereumTransaction(info), + ))), + _ => None, + } + } +} /// Executive: handles dispatch to the various modules. pub type Executive = frame_executive::Executive< @@ -923,6 +979,31 @@ impl> FindAuthor for FindAuthorSession { } } +#[derive(Clone)] +pub struct TransactionConverter; + +impl fp_rpc::ConvertTransaction for TransactionConverter { + fn convert_transaction(&self, transaction: pallet_ethereum::Transaction) -> UncheckedExtrinsic { + UncheckedExtrinsic::new_unsigned( + pallet_ethereum::Call::::transact { transaction }.into(), + ) + } +} + +impl fp_rpc::ConvertTransaction for TransactionConverter { + fn convert_transaction( + &self, + transaction: pallet_ethereum::Transaction, + ) -> opaque::UncheckedExtrinsic { + let extrinsic = UncheckedExtrinsic::new_unsigned( + pallet_ethereum::Call::::transact { transaction }.into(), + ); + let encoded = extrinsic.encode(); + opaque::UncheckedExtrinsic::decode(&mut &encoded[..]) + .expect("Encoded extrinsic is always valid") + } +} + // Create the runtime by composing the FRAME pallets that were previously // configured. construct_runtime!( @@ -1288,7 +1369,7 @@ impl_runtime_apis! { fn extrinsic_filter( xts: Vec<::Extrinsic>, ) -> Vec { - xts.into_iter().filter_map(|xt| match xt.function { + xts.into_iter().filter_map(|xt| match xt.0.function { RuntimeCall::Ethereum(transact { transaction }) => Some(transaction), _ => None }).collect::>()