diff --git a/Cargo.lock b/Cargo.lock index 3a87e1394..d816c3dda 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -473,6 +473,18 @@ dependencies = [ "winapi", ] +[[package]] +name = "auto_impl" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fee3da8ef1276b0bee5dd1c7258010d8fffd31801447323115a25560e1327b89" +dependencies = [ + "proc-macro-error", + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "autocfg" version = "1.1.0" @@ -1561,7 +1573,7 @@ dependencies = [ [[package]] name = "cumulus-client-cli" version = "0.1.0" -source = "git+https://github.com/galacticcouncil/cumulus.git?branch=feat/xcmp-defer-xcm-v9-38#460647cc2ec988ee04370c1cdd9fd518ed4868eb" +source = "git+https://github.com/galacticcouncil/cumulus.git?rev=460647cc2ec988ee04370c1cdd9fd518ed4868eb#460647cc2ec988ee04370c1cdd9fd518ed4868eb" dependencies = [ "clap 4.3.9", "parity-scale-codec", @@ -1576,7 +1588,7 @@ dependencies = [ [[package]] name = "cumulus-client-collator" version = "0.1.0" -source = "git+https://github.com/galacticcouncil/cumulus.git?branch=feat/xcmp-defer-xcm-v9-38#460647cc2ec988ee04370c1cdd9fd518ed4868eb" +source = "git+https://github.com/galacticcouncil/cumulus.git?rev=460647cc2ec988ee04370c1cdd9fd518ed4868eb#460647cc2ec988ee04370c1cdd9fd518ed4868eb" dependencies = [ "cumulus-client-consensus-common", "cumulus-client-network", @@ -1599,7 +1611,7 @@ dependencies = [ [[package]] name = "cumulus-client-consensus-aura" version = "0.1.0" -source = "git+https://github.com/galacticcouncil/cumulus.git?branch=feat/xcmp-defer-xcm-v9-38#460647cc2ec988ee04370c1cdd9fd518ed4868eb" +source = "git+https://github.com/galacticcouncil/cumulus.git?rev=460647cc2ec988ee04370c1cdd9fd518ed4868eb#460647cc2ec988ee04370c1cdd9fd518ed4868eb" dependencies = [ "async-trait", "cumulus-client-consensus-common", @@ -1628,7 +1640,7 @@ dependencies = [ [[package]] name = "cumulus-client-consensus-common" version = "0.1.0" -source = "git+https://github.com/galacticcouncil/cumulus.git?branch=feat/xcmp-defer-xcm-v9-38#460647cc2ec988ee04370c1cdd9fd518ed4868eb" +source = "git+https://github.com/galacticcouncil/cumulus.git?rev=460647cc2ec988ee04370c1cdd9fd518ed4868eb#460647cc2ec988ee04370c1cdd9fd518ed4868eb" dependencies = [ "async-trait", "cumulus-client-pov-recovery", @@ -1651,7 +1663,7 @@ dependencies = [ [[package]] name = "cumulus-client-consensus-relay-chain" version = "0.1.0" -source = "git+https://github.com/galacticcouncil/cumulus.git?branch=feat/xcmp-defer-xcm-v9-38#460647cc2ec988ee04370c1cdd9fd518ed4868eb" +source = "git+https://github.com/galacticcouncil/cumulus.git?rev=460647cc2ec988ee04370c1cdd9fd518ed4868eb#460647cc2ec988ee04370c1cdd9fd518ed4868eb" dependencies = [ "async-trait", "cumulus-client-consensus-common", @@ -1674,7 +1686,7 @@ dependencies = [ [[package]] name = "cumulus-client-network" version = "0.1.0" -source = "git+https://github.com/galacticcouncil/cumulus.git?branch=feat/xcmp-defer-xcm-v9-38#460647cc2ec988ee04370c1cdd9fd518ed4868eb" +source = "git+https://github.com/galacticcouncil/cumulus.git?rev=460647cc2ec988ee04370c1cdd9fd518ed4868eb#460647cc2ec988ee04370c1cdd9fd518ed4868eb" dependencies = [ "async-trait", "cumulus-relay-chain-interface", @@ -1697,7 +1709,7 @@ dependencies = [ [[package]] name = "cumulus-client-pov-recovery" version = "0.1.0" -source = "git+https://github.com/galacticcouncil/cumulus.git?branch=feat/xcmp-defer-xcm-v9-38#460647cc2ec988ee04370c1cdd9fd518ed4868eb" +source = "git+https://github.com/galacticcouncil/cumulus.git?rev=460647cc2ec988ee04370c1cdd9fd518ed4868eb#460647cc2ec988ee04370c1cdd9fd518ed4868eb" dependencies = [ "cumulus-primitives-core", "cumulus-relay-chain-interface", @@ -1720,7 +1732,7 @@ dependencies = [ [[package]] name = "cumulus-client-service" version = "0.1.0" -source = "git+https://github.com/galacticcouncil/cumulus.git?branch=feat/xcmp-defer-xcm-v9-38#460647cc2ec988ee04370c1cdd9fd518ed4868eb" +source = "git+https://github.com/galacticcouncil/cumulus.git?rev=460647cc2ec988ee04370c1cdd9fd518ed4868eb#460647cc2ec988ee04370c1cdd9fd518ed4868eb" dependencies = [ "cumulus-client-cli", "cumulus-client-collator", @@ -1748,7 +1760,7 @@ dependencies = [ [[package]] name = "cumulus-pallet-aura-ext" version = "0.1.0" -source = "git+https://github.com/galacticcouncil/cumulus.git?branch=feat/xcmp-defer-xcm-v9-38#460647cc2ec988ee04370c1cdd9fd518ed4868eb" +source = "git+https://github.com/galacticcouncil/cumulus.git?rev=460647cc2ec988ee04370c1cdd9fd518ed4868eb#460647cc2ec988ee04370c1cdd9fd518ed4868eb" dependencies = [ "frame-support", "frame-system", @@ -1758,13 +1770,13 @@ dependencies = [ "sp-application-crypto", "sp-consensus-aura", "sp-runtime", - "sp-std", + "sp-std 5.0.0", ] [[package]] name = "cumulus-pallet-dmp-queue" version = "0.1.0" -source = "git+https://github.com/galacticcouncil/cumulus.git?branch=feat/xcmp-defer-xcm-v9-38#460647cc2ec988ee04370c1cdd9fd518ed4868eb" +source = "git+https://github.com/galacticcouncil/cumulus.git?rev=460647cc2ec988ee04370c1cdd9fd518ed4868eb#460647cc2ec988ee04370c1cdd9fd518ed4868eb" dependencies = [ "cumulus-primitives-core", "frame-support", @@ -1774,14 +1786,14 @@ dependencies = [ "scale-info", "sp-io", "sp-runtime", - "sp-std", + "sp-std 5.0.0", "xcm", ] [[package]] name = "cumulus-pallet-parachain-system" version = "0.1.0" -source = "git+https://github.com/galacticcouncil/cumulus.git?branch=feat/xcmp-defer-xcm-v9-38#460647cc2ec988ee04370c1cdd9fd518ed4868eb" +source = "git+https://github.com/galacticcouncil/cumulus.git?rev=460647cc2ec988ee04370c1cdd9fd518ed4868eb#460647cc2ec988ee04370c1cdd9fd518ed4868eb" dependencies = [ "bytes", "cumulus-pallet-parachain-system-proc-macro", @@ -1801,7 +1813,7 @@ dependencies = [ "sp-io", "sp-runtime", "sp-state-machine", - "sp-std", + "sp-std 5.0.0", "sp-trie", "sp-version", "xcm", @@ -1810,7 +1822,7 @@ dependencies = [ [[package]] name = "cumulus-pallet-parachain-system-proc-macro" version = "0.1.0" -source = "git+https://github.com/galacticcouncil/cumulus.git?branch=feat/xcmp-defer-xcm-v9-38#460647cc2ec988ee04370c1cdd9fd518ed4868eb" +source = "git+https://github.com/galacticcouncil/cumulus.git?rev=460647cc2ec988ee04370c1cdd9fd518ed4868eb#460647cc2ec988ee04370c1cdd9fd518ed4868eb" dependencies = [ "proc-macro-crate", "proc-macro2", @@ -1821,7 +1833,7 @@ dependencies = [ [[package]] name = "cumulus-pallet-xcm" version = "0.1.0" -source = "git+https://github.com/galacticcouncil/cumulus.git?branch=feat/xcmp-defer-xcm-v9-38#460647cc2ec988ee04370c1cdd9fd518ed4868eb" +source = "git+https://github.com/galacticcouncil/cumulus.git?rev=460647cc2ec988ee04370c1cdd9fd518ed4868eb#460647cc2ec988ee04370c1cdd9fd518ed4868eb" dependencies = [ "cumulus-primitives-core", "frame-support", @@ -1830,14 +1842,14 @@ dependencies = [ "scale-info", "sp-io", "sp-runtime", - "sp-std", + "sp-std 5.0.0", "xcm", ] [[package]] name = "cumulus-pallet-xcmp-queue" version = "0.2.0" -source = "git+https://github.com/galacticcouncil/cumulus.git?branch=feat/xcmp-defer-xcm-v9-38#460647cc2ec988ee04370c1cdd9fd518ed4868eb" +source = "git+https://github.com/galacticcouncil/cumulus.git?rev=460647cc2ec988ee04370c1cdd9fd518ed4868eb#460647cc2ec988ee04370c1cdd9fd518ed4868eb" dependencies = [ "cumulus-primitives-core", "frame-benchmarking", @@ -1851,7 +1863,7 @@ dependencies = [ "sp-core", "sp-io", "sp-runtime", - "sp-std", + "sp-std 5.0.0", "xcm", "xcm-executor", ] @@ -1859,7 +1871,7 @@ dependencies = [ [[package]] name = "cumulus-primitives-core" version = "0.1.0" -source = "git+https://github.com/galacticcouncil/cumulus.git?branch=feat/xcmp-defer-xcm-v9-38#460647cc2ec988ee04370c1cdd9fd518ed4868eb" +source = "git+https://github.com/galacticcouncil/cumulus.git?rev=460647cc2ec988ee04370c1cdd9fd518ed4868eb#460647cc2ec988ee04370c1cdd9fd518ed4868eb" dependencies = [ "parity-scale-codec", "polkadot-core-primitives", @@ -1867,7 +1879,7 @@ dependencies = [ "polkadot-primitives", "sp-api", "sp-runtime", - "sp-std", + "sp-std 5.0.0", "sp-trie", "xcm", ] @@ -1875,12 +1887,12 @@ dependencies = [ [[package]] name = "cumulus-primitives-parachain-inherent" version = "0.1.0" -source = "git+https://github.com/galacticcouncil/cumulus.git?branch=feat/xcmp-defer-xcm-v9-38#460647cc2ec988ee04370c1cdd9fd518ed4868eb" +source = "git+https://github.com/galacticcouncil/cumulus.git?rev=460647cc2ec988ee04370c1cdd9fd518ed4868eb#460647cc2ec988ee04370c1cdd9fd518ed4868eb" dependencies = [ "async-trait", "cumulus-primitives-core", "cumulus-relay-chain-interface", - "cumulus-test-relay-sproof-builder 0.1.0 (git+https://github.com/galacticcouncil/cumulus.git?branch=feat/xcmp-defer-xcm-v9-38)", + "cumulus-test-relay-sproof-builder", "parity-scale-codec", "sc-client-api", "scale-info", @@ -1889,7 +1901,7 @@ dependencies = [ "sp-inherents", "sp-runtime", "sp-state-machine", - "sp-std", + "sp-std 5.0.0", "sp-storage", "sp-trie", "tracing", @@ -1898,20 +1910,20 @@ dependencies = [ [[package]] name = "cumulus-primitives-timestamp" version = "0.1.0" -source = "git+https://github.com/galacticcouncil/cumulus.git?branch=feat/xcmp-defer-xcm-v9-38#460647cc2ec988ee04370c1cdd9fd518ed4868eb" +source = "git+https://github.com/galacticcouncil/cumulus.git?rev=460647cc2ec988ee04370c1cdd9fd518ed4868eb#460647cc2ec988ee04370c1cdd9fd518ed4868eb" dependencies = [ "cumulus-primitives-core", "futures", "parity-scale-codec", "sp-inherents", - "sp-std", + "sp-std 5.0.0", "sp-timestamp", ] [[package]] name = "cumulus-primitives-utility" version = "0.1.0" -source = "git+https://github.com/galacticcouncil/cumulus.git?branch=feat/xcmp-defer-xcm-v9-38#460647cc2ec988ee04370c1cdd9fd518ed4868eb" +source = "git+https://github.com/galacticcouncil/cumulus.git?rev=460647cc2ec988ee04370c1cdd9fd518ed4868eb#460647cc2ec988ee04370c1cdd9fd518ed4868eb" dependencies = [ "cumulus-primitives-core", "frame-support", @@ -1920,7 +1932,7 @@ dependencies = [ "polkadot-runtime-common", "sp-io", "sp-runtime", - "sp-std", + "sp-std 5.0.0", "xcm", "xcm-builder", "xcm-executor", @@ -1929,7 +1941,7 @@ dependencies = [ [[package]] name = "cumulus-relay-chain-inprocess-interface" version = "0.1.0" -source = "git+https://github.com/galacticcouncil/cumulus.git?branch=feat/xcmp-defer-xcm-v9-38#460647cc2ec988ee04370c1cdd9fd518ed4868eb" +source = "git+https://github.com/galacticcouncil/cumulus.git?rev=460647cc2ec988ee04370c1cdd9fd518ed4868eb#460647cc2ec988ee04370c1cdd9fd518ed4868eb" dependencies = [ "async-trait", "cumulus-primitives-core", @@ -1954,7 +1966,7 @@ dependencies = [ [[package]] name = "cumulus-relay-chain-interface" version = "0.1.0" -source = "git+https://github.com/galacticcouncil/cumulus.git?branch=feat/xcmp-defer-xcm-v9-38#460647cc2ec988ee04370c1cdd9fd518ed4868eb" +source = "git+https://github.com/galacticcouncil/cumulus.git?rev=460647cc2ec988ee04370c1cdd9fd518ed4868eb#460647cc2ec988ee04370c1cdd9fd518ed4868eb" dependencies = [ "async-trait", "cumulus-primitives-core", @@ -1973,7 +1985,7 @@ dependencies = [ [[package]] name = "cumulus-relay-chain-minimal-node" version = "0.1.0" -source = "git+https://github.com/galacticcouncil/cumulus.git?branch=feat/xcmp-defer-xcm-v9-38#460647cc2ec988ee04370c1cdd9fd518ed4868eb" +source = "git+https://github.com/galacticcouncil/cumulus.git?rev=460647cc2ec988ee04370c1cdd9fd518ed4868eb#460647cc2ec988ee04370c1cdd9fd518ed4868eb" dependencies = [ "array-bytes 6.1.0", "async-trait", @@ -2013,7 +2025,7 @@ dependencies = [ [[package]] name = "cumulus-relay-chain-rpc-interface" version = "0.1.0" -source = "git+https://github.com/galacticcouncil/cumulus.git?branch=feat/xcmp-defer-xcm-v9-38#460647cc2ec988ee04370c1cdd9fd518ed4868eb" +source = "git+https://github.com/galacticcouncil/cumulus.git?rev=460647cc2ec988ee04370c1cdd9fd518ed4868eb#460647cc2ec988ee04370c1cdd9fd518ed4868eb" dependencies = [ "async-trait", "cumulus-primitives-core", @@ -2042,27 +2054,14 @@ dependencies = [ [[package]] name = "cumulus-test-relay-sproof-builder" version = "0.1.0" -source = "git+https://github.com/galacticcouncil/cumulus.git?branch=feat/xcmp-defer-xcm-v9-38#460647cc2ec988ee04370c1cdd9fd518ed4868eb" +source = "git+https://github.com/galacticcouncil/cumulus.git?rev=460647cc2ec988ee04370c1cdd9fd518ed4868eb#460647cc2ec988ee04370c1cdd9fd518ed4868eb" dependencies = [ "cumulus-primitives-core", "parity-scale-codec", "polkadot-primitives", "sp-runtime", "sp-state-machine", - "sp-std", -] - -[[package]] -name = "cumulus-test-relay-sproof-builder" -version = "0.1.0" -source = "git+https://github.com/paritytech/cumulus.git?branch=polkadot-v0.9.38#9b4e0247137f158d1a35118197d34adfa58858b7" -dependencies = [ - "cumulus-primitives-core", - "parity-scale-codec", - "polkadot-primitives", - "sp-runtime", - "sp-state-machine", - "sp-std", + "sp-std 5.0.0", ] [[package]] @@ -2643,12 +2642,184 @@ dependencies = [ "libc", ] +[[package]] +name = "ethabi" +version = "18.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7413c5f74cc903ea37386a8965a936cbeb334bd270862fdece542c1b2dcbc898" +dependencies = [ + "ethereum-types", + "hex", + "sha3", +] + +[[package]] +name = "ethbloom" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c22d4b5885b6aa2fe5e8b9329fb8d232bf739e434e6b87347c63bdd00c120f60" +dependencies = [ + "crunchy", + "fixed-hash", + "impl-codec", + "impl-rlp", + "impl-serde", + "scale-info", + "tiny-keccak", +] + +[[package]] +name = "ethereum" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a89fb87a9e103f71b903b80b670200b54cc67a07578f070681f1fffb7396fb7" +dependencies = [ + "bytes", + "ethereum-types", + "hash-db", + "hash256-std-hasher", + "parity-scale-codec", + "rlp", + "scale-info", + "serde", + "sha3", + "triehash", +] + +[[package]] +name = "ethereum-types" +version = "0.14.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02d215cbf040552efcbe99a38372fe80ab9d00268e20012b79fcd0f073edd8ee" +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.36.0" +source = "git+https://github.com/rust-blockchain/evm?rev=13240a8a551586fdef0b5028ed73af80b248092a#13240a8a551586fdef0b5028ed73af80b248092a" +dependencies = [ + "auto_impl", + "environmental", + "ethereum", + "evm-core 0.36.0", + "evm-gasometer 0.36.0", + "evm-runtime 0.36.0", + "log", + "parity-scale-codec", + "primitive-types", + "rlp", + "scale-info", + "serde", + "sha3", +] + +[[package]] +name = "evm" +version = "0.37.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4448c65b71e8e2b9718232d84d09045eeaaccb2320494e6bd6dbf7e58fec8ff" +dependencies = [ + "auto_impl", + "environmental", + "ethereum", + "evm-core 0.37.0", + "evm-gasometer 0.37.0", + "evm-runtime 0.37.0", + "log", + "parity-scale-codec", + "primitive-types", + "rlp", + "scale-info", + "serde", + "sha3", +] + +[[package]] +name = "evm-core" +version = "0.36.0" +source = "git+https://github.com/rust-blockchain/evm?rev=13240a8a551586fdef0b5028ed73af80b248092a#13240a8a551586fdef0b5028ed73af80b248092a" +dependencies = [ + "parity-scale-codec", + "primitive-types", + "scale-info", + "serde", +] + +[[package]] +name = "evm-core" +version = "0.37.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64c51bec0eb68a891c2575c758eaaa1d61373fc51f7caaf216b1fb5c3fea3b5d" +dependencies = [ + "parity-scale-codec", + "primitive-types", + "scale-info", + "serde", +] + +[[package]] +name = "evm-gasometer" +version = "0.36.0" +source = "git+https://github.com/rust-blockchain/evm?rev=13240a8a551586fdef0b5028ed73af80b248092a#13240a8a551586fdef0b5028ed73af80b248092a" +dependencies = [ + "environmental", + "evm-core 0.36.0", + "evm-runtime 0.36.0", + "primitive-types", +] + +[[package]] +name = "evm-gasometer" +version = "0.37.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8b93c59c54fc26522d842f0e0d3f8e8be331c776df18ff3e540b53c2f64d509" +dependencies = [ + "environmental", + "evm-core 0.37.0", + "evm-runtime 0.37.0", + "primitive-types", +] + +[[package]] +name = "evm-runtime" +version = "0.36.0" +source = "git+https://github.com/rust-blockchain/evm?rev=13240a8a551586fdef0b5028ed73af80b248092a#13240a8a551586fdef0b5028ed73af80b248092a" +dependencies = [ + "auto_impl", + "environmental", + "evm-core 0.36.0", + "primitive-types", + "sha3", +] + +[[package]] +name = "evm-runtime" +version = "0.37.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c79b9459ce64f1a28688397c4013764ce53cd57bb84efc16b5187fa9b05b13ad" +dependencies = [ + "auto_impl", + "environmental", + "evm-core 0.37.0", + "primitive-types", + "sha3", +] + [[package]] name = "exit-future" version = "0.2.0" @@ -2729,6 +2900,137 @@ dependencies = [ "thiserror", ] +[[package]] +name = "fc-consensus" +version = "2.0.0-dev" +source = "git+https://github.com/PureStake/frontier?branch=moonbeam-polkadot-v0.9.38#df4e329ef9b1ef54d83114deff98124139f1dd6d" +dependencies = [ + "async-trait", + "fc-db", + "fp-consensus", + "fp-rpc", + "sc-consensus", + "sp-api", + "sp-block-builder", + "sp-blockchain", + "sp-consensus", + "sp-runtime", + "thiserror", +] + +[[package]] +name = "fc-db" +version = "2.0.0-dev" +source = "git+https://github.com/PureStake/frontier?branch=moonbeam-polkadot-v0.9.38#df4e329ef9b1ef54d83114deff98124139f1dd6d" +dependencies = [ + "fp-storage", + "kvdb-rocksdb", + "log", + "parity-db", + "parity-scale-codec", + "parking_lot 0.12.1", + "sc-client-db", + "smallvec", + "sp-blockchain", + "sp-core", + "sp-database", + "sp-runtime", +] + +[[package]] +name = "fc-mapping-sync" +version = "2.0.0-dev" +source = "git+https://github.com/PureStake/frontier?branch=moonbeam-polkadot-v0.9.38#df4e329ef9b1ef54d83114deff98124139f1dd6d" +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/PureStake/frontier?branch=moonbeam-polkadot-v0.9.38#df4e329ef9b1ef54d83114deff98124139f1dd6d" +dependencies = [ + "ethereum", + "ethereum-types", + "evm 0.37.0", + "fc-db", + "fc-rpc-core", + "fc-storage", + "fp-ethereum", + "fp-evm", + "fp-rpc", + "fp-storage", + "futures", + "hex", + "jsonrpsee 0.16.2", + "libsecp256k1", + "log", + "lru 0.8.1", + "pallet-evm", + "parity-scale-codec", + "prometheus", + "rand 0.8.5", + "rlp", + "sc-client-api", + "sc-network", + "sc-network-common", + "sc-rpc", + "sc-service", + "sc-transaction-pool", + "sc-transaction-pool-api", + "sp-api", + "sp-block-builder", + "sp-blockchain", + "sp-consensus", + "sp-core", + "sp-io", + "sp-runtime", + "sp-state-machine", + "sp-storage", + "substrate-prometheus-endpoint", + "tokio", +] + +[[package]] +name = "fc-rpc-core" +version = "1.1.0-dev" +source = "git+https://github.com/PureStake/frontier?branch=moonbeam-polkadot-v0.9.38#df4e329ef9b1ef54d83114deff98124139f1dd6d" +dependencies = [ + "ethereum", + "ethereum-types", + "jsonrpsee 0.16.2", + "rustc-hex", + "serde", + "serde_json", +] + +[[package]] +name = "fc-storage" +version = "1.0.0-dev" +source = "git+https://github.com/PureStake/frontier?branch=moonbeam-polkadot-v0.9.38#df4e329ef9b1ef54d83114deff98124139f1dd6d" +dependencies = [ + "ethereum", + "ethereum-types", + "fp-rpc", + "fp-storage", + "parity-scale-codec", + "sc-client-api", + "sp-api", + "sp-blockchain", + "sp-io", + "sp-runtime", + "sp-storage", +] + [[package]] name = "fdlimit" version = "0.2.1" @@ -2872,6 +3174,84 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "fp-consensus" +version = "2.0.0-dev" +source = "git+https://github.com/PureStake/frontier?branch=moonbeam-polkadot-v0.9.38#df4e329ef9b1ef54d83114deff98124139f1dd6d" +dependencies = [ + "ethereum", + "parity-scale-codec", + "sp-core", + "sp-runtime", + "sp-std 5.0.0", +] + +[[package]] +name = "fp-ethereum" +version = "1.0.0-dev" +source = "git+https://github.com/PureStake/frontier?branch=moonbeam-polkadot-v0.9.38#df4e329ef9b1ef54d83114deff98124139f1dd6d" +dependencies = [ + "ethereum", + "ethereum-types", + "fp-evm", + "frame-support", + "num_enum", + "parity-scale-codec", + "sp-std 5.0.0", +] + +[[package]] +name = "fp-evm" +version = "3.0.0-dev" +source = "git+https://github.com/PureStake/frontier?branch=moonbeam-polkadot-v0.9.38#df4e329ef9b1ef54d83114deff98124139f1dd6d" +dependencies = [ + "evm 0.37.0", + "frame-support", + "parity-scale-codec", + "serde", + "sp-core", + "sp-runtime", + "sp-std 5.0.0", +] + +[[package]] +name = "fp-rpc" +version = "3.0.0-dev" +source = "git+https://github.com/PureStake/frontier?branch=moonbeam-polkadot-v0.9.38#df4e329ef9b1ef54d83114deff98124139f1dd6d" +dependencies = [ + "ethereum", + "ethereum-types", + "fp-evm", + "parity-scale-codec", + "scale-info", + "sp-api", + "sp-core", + "sp-runtime", + "sp-state-machine", + "sp-std 5.0.0", +] + +[[package]] +name = "fp-self-contained" +version = "1.0.0-dev" +source = "git+https://github.com/PureStake/frontier?branch=moonbeam-polkadot-v0.9.38#df4e329ef9b1ef54d83114deff98124139f1dd6d" +dependencies = [ + "frame-support", + "parity-scale-codec", + "scale-info", + "serde", + "sp-runtime", +] + +[[package]] +name = "fp-storage" +version = "2.0.0" +source = "git+https://github.com/PureStake/frontier?branch=moonbeam-polkadot-v0.9.38#df4e329ef9b1ef54d83114deff98124139f1dd6d" +dependencies = [ + "parity-scale-codec", + "serde", +] + [[package]] name = "fragile" version = "2.0.0" @@ -2898,7 +3278,7 @@ dependencies = [ "sp-io", "sp-runtime", "sp-runtime-interface", - "sp-std", + "sp-std 5.0.0", "sp-storage", "static_assertions", ] @@ -2943,7 +3323,7 @@ dependencies = [ "sp-keystore", "sp-runtime", "sp-state-machine", - "sp-std", + "sp-std 5.0.0", "sp-storage", "sp-trie", "thiserror", @@ -2975,7 +3355,7 @@ dependencies = [ "sp-core", "sp-npos-elections", "sp-runtime", - "sp-std", + "sp-std 5.0.0", ] [[package]] @@ -2991,7 +3371,7 @@ dependencies = [ "sp-core", "sp-io", "sp-runtime", - "sp-std", + "sp-std 5.0.0", "sp-tracing", ] @@ -3049,7 +3429,7 @@ dependencies = [ "sp-runtime", "sp-staking", "sp-state-machine", - "sp-std", + "sp-std 5.0.0", "sp-tracing", "sp-weights", "tt-call", @@ -3105,7 +3485,7 @@ dependencies = [ "sp-core", "sp-io", "sp-runtime", - "sp-std", + "sp-std 5.0.0", "sp-version", "sp-weights", ] @@ -3122,7 +3502,7 @@ dependencies = [ "scale-info", "sp-core", "sp-runtime", - "sp-std", + "sp-std 5.0.0", ] [[package]] @@ -3143,7 +3523,7 @@ dependencies = [ "parity-scale-codec", "sp-api", "sp-runtime", - "sp-std", + "sp-std 5.0.0", ] [[package]] @@ -3704,14 +4084,15 @@ dependencies = [ "scale-info", "serde", "sp-arithmetic", - "sp-std", + "sp-std 5.0.0", "test-case 2.2.2", ] [[package]] name = "hydradx" -version = "10.0.1" +version = "11.0.0" dependencies = [ + "async-trait", "clap 4.3.9", "cumulus-client-cli", "cumulus-client-collator", @@ -3725,6 +4106,13 @@ dependencies = [ "cumulus-relay-chain-inprocess-interface", "cumulus-relay-chain-interface", "cumulus-relay-chain-minimal-node", + "fc-consensus", + "fc-db", + "fc-mapping-sync", + "fc-rpc", + "fc-rpc-core", + "fp-rpc", + "fp-storage", "frame-benchmarking", "frame-benchmarking-cli", "frame-system-rpc-runtime-api", @@ -3747,6 +4135,7 @@ dependencies = [ "sc-chain-spec", "sc-cli", "sc-client-api", + "sc-client-db", "sc-consensus", "sc-consensus-aura", "sc-executor", @@ -3823,7 +4212,7 @@ dependencies = [ "sp-core", "sp-io", "sp-runtime", - "sp-std", + "sp-std 5.0.0", "xcm", "xcm-builder", "xcm-executor", @@ -3842,6 +4231,9 @@ dependencies = [ "cumulus-primitives-parachain-inherent", "cumulus-primitives-timestamp", "cumulus-primitives-utility", + "ethabi", + "fp-rpc", + "fp-self-contained", "frame-benchmarking", "frame-executive", "frame-support", @@ -3853,6 +4245,8 @@ dependencies = [ "hydra-dx-math", "hydradx-adapters", "hydradx-traits", + "module-evm-utility-macro", + "num_enum", "orml-benchmarking", "orml-tokens", "orml-traits", @@ -3873,11 +4267,15 @@ dependencies = [ "pallet-collective", "pallet-currencies", "pallet-dca", - "pallet-democracy 4.0.1-dev", + "pallet-democracy 4.0.2-dev", "pallet-duster", "pallet-dynamic-fees", "pallet-elections-phragmen", "pallet-ema-oracle", + "pallet-ethereum", + "pallet-evm", + "pallet-evm-chain-id", + "pallet-evm-precompile-dispatch", "pallet-genesis-history", "pallet-identity", "pallet-lbp", @@ -3924,7 +4322,7 @@ dependencies = [ "sp-offchain", "sp-runtime", "sp-session", - "sp-std", + "sp-std 5.0.0", "sp-transaction-pool", "sp-trie", "sp-version", @@ -3937,7 +4335,7 @@ dependencies = [ [[package]] name = "hydradx-traits" -version = "2.7.1" +version = "2.8.0" dependencies = [ "frame-support", "impl-trait-for-tuples", @@ -3945,7 +4343,7 @@ dependencies = [ "scale-info", "serde", "sp-arithmetic", - "sp-std", + "sp-std 5.0.0", ] [[package]] @@ -4075,6 +4473,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.4.0" @@ -4593,7 +5000,7 @@ dependencies = [ "sp-runtime", "sp-session", "sp-staking", - "sp-std", + "sp-std 5.0.0", "sp-transaction-pool", "sp-version", "static_assertions", @@ -5565,6 +5972,30 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "module-evm-utility" +version = "2.22.0" +source = "git+https://github.com/AcalaNetwork/Acala?branch=release-acala-2.22.0#37d9e3604fb3f217869ccc49dcce8a7b632fb73a" +dependencies = [ + "ethereum", + "evm 0.36.0", + "evm-gasometer 0.36.0", + "evm-runtime 0.36.0", + "sha3", + "sp-std 8.0.0", +] + +[[package]] +name = "module-evm-utility-macro" +version = "2.22.0" +source = "git+https://github.com/AcalaNetwork/Acala?branch=release-acala-2.22.0#37d9e3604fb3f217869ccc49dcce8a7b632fb73a" +dependencies = [ + "module-evm-utility", + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "multiaddr" version = "0.16.0" @@ -5905,6 +6336,27 @@ dependencies = [ "libc", ] +[[package]] +name = "num_enum" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f646caf906c20226733ed5b1374287eb97e3c2a5c227ce668c1f2ce20ae57c9" +dependencies = [ + "num_enum_derive", +] + +[[package]] +name = "num_enum_derive" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcbff9bc912032c62bf65ef1d5aea88983b420f4f839db1e9b0c281a25c9c799" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "object" version = "0.29.0" @@ -6031,7 +6483,7 @@ dependencies = [ "sp-io", "sp-runtime", "sp-runtime-interface", - "sp-std", + "sp-std 5.0.0", "sp-storage", ] @@ -6048,7 +6500,7 @@ dependencies = [ "scale-info", "sp-io", "sp-runtime", - "sp-std", + "sp-std 5.0.0", ] [[package]] @@ -6063,7 +6515,7 @@ dependencies = [ "scale-info", "serde", "sp-runtime", - "sp-std", + "sp-std 5.0.0", ] [[package]] @@ -6081,7 +6533,7 @@ dependencies = [ "sp-core", "sp-io", "sp-runtime", - "sp-std", + "sp-std 5.0.0", "xcm", ] @@ -6096,7 +6548,7 @@ dependencies = [ "parity-scale-codec", "scale-info", "serde", - "sp-std", + "sp-std 5.0.0", "xcm", ] @@ -6111,7 +6563,7 @@ dependencies = [ "serde", "sp-io", "sp-runtime", - "sp-std", + "sp-std 5.0.0", ] [[package]] @@ -6126,7 +6578,7 @@ dependencies = [ "serde", "sp-io", "sp-runtime", - "sp-std", + "sp-std 5.0.0", ] [[package]] @@ -6139,7 +6591,7 @@ dependencies = [ "pallet-xcm", "parity-scale-codec", "scale-info", - "sp-std", + "sp-std 5.0.0", "xcm", ] @@ -6152,7 +6604,7 @@ dependencies = [ "orml-traits", "parity-scale-codec", "sp-runtime", - "sp-std", + "sp-std 5.0.0", "xcm", "xcm-executor", ] @@ -6173,7 +6625,7 @@ dependencies = [ "serde", "sp-io", "sp-runtime", - "sp-std", + "sp-std 5.0.0", "xcm", "xcm-executor", ] @@ -6218,7 +6670,7 @@ dependencies = [ [[package]] name = "pallet-asset-registry" -version = "2.3.1" +version = "2.3.2" dependencies = [ "frame-benchmarking", "frame-support", @@ -6235,7 +6687,7 @@ dependencies = [ "sp-core", "sp-io", "sp-runtime", - "sp-std", + "sp-std 5.0.0", "substrate-wasm-builder", "test-utils", "xcm", @@ -6254,7 +6706,7 @@ dependencies = [ "sp-application-crypto", "sp-consensus-aura", "sp-runtime", - "sp-std", + "sp-std 5.0.0", ] [[package]] @@ -6270,7 +6722,7 @@ dependencies = [ "sp-application-crypto", "sp-authority-discovery", "sp-runtime", - "sp-std", + "sp-std 5.0.0", ] [[package]] @@ -6284,7 +6736,7 @@ dependencies = [ "parity-scale-codec", "scale-info", "sp-runtime", - "sp-std", + "sp-std 5.0.0", ] [[package]] @@ -6308,7 +6760,7 @@ dependencies = [ "sp-runtime", "sp-session", "sp-staking", - "sp-std", + "sp-std 5.0.0", ] [[package]] @@ -6327,7 +6779,7 @@ dependencies = [ "sp-core", "sp-io", "sp-runtime", - "sp-std", + "sp-std 5.0.0", "sp-tracing", ] @@ -6343,7 +6795,7 @@ dependencies = [ "parity-scale-codec", "scale-info", "sp-runtime", - "sp-std", + "sp-std 5.0.0", ] [[package]] @@ -6359,7 +6811,7 @@ dependencies = [ "serde", "sp-beefy", "sp-runtime", - "sp-std", + "sp-std 5.0.0", ] [[package]] @@ -6382,7 +6834,7 @@ dependencies = [ "sp-core", "sp-io", "sp-runtime", - "sp-std", + "sp-std 5.0.0", ] [[package]] @@ -6406,7 +6858,7 @@ dependencies = [ "sp-core", "sp-io", "sp-runtime", - "sp-std", + "sp-std 5.0.0", "sp-tracing", ] @@ -6425,7 +6877,7 @@ dependencies = [ "sp-core", "sp-io", "sp-runtime", - "sp-std", + "sp-std 5.0.0", ] [[package]] @@ -6444,7 +6896,7 @@ dependencies = [ "sp-core", "sp-io", "sp-runtime", - "sp-std", + "sp-std 5.0.0", ] [[package]] @@ -6467,7 +6919,7 @@ dependencies = [ "sp-core", "sp-io", "sp-runtime", - "sp-std", + "sp-std 5.0.0", "test-case 3.1.0", "test-utils", ] @@ -6494,7 +6946,7 @@ dependencies = [ "sp-core", "sp-io", "sp-runtime", - "sp-std", + "sp-std 5.0.0", ] [[package]] @@ -6520,14 +6972,14 @@ dependencies = [ "sp-io", "sp-runtime", "sp-staking", - "sp-std", + "sp-std 5.0.0", "substrate-wasm-builder", ] [[package]] name = "pallet-collator-selection" version = "3.0.0" -source = "git+https://github.com/galacticcouncil/cumulus.git?branch=feat/xcmp-defer-xcm-v9-38#460647cc2ec988ee04370c1cdd9fd518ed4868eb" +source = "git+https://github.com/galacticcouncil/cumulus.git?rev=460647cc2ec988ee04370c1cdd9fd518ed4868eb#460647cc2ec988ee04370c1cdd9fd518ed4868eb" dependencies = [ "frame-benchmarking", "frame-support", @@ -6540,7 +6992,7 @@ dependencies = [ "scale-info", "sp-runtime", "sp-staking", - "sp-std", + "sp-std 5.0.0", ] [[package]] @@ -6557,7 +7009,7 @@ dependencies = [ "sp-core", "sp-io", "sp-runtime", - "sp-std", + "sp-std 5.0.0", ] [[package]] @@ -6574,7 +7026,7 @@ dependencies = [ "serde", "sp-io", "sp-runtime", - "sp-std", + "sp-std 5.0.0", ] [[package]] @@ -6593,7 +7045,7 @@ dependencies = [ "sp-core", "sp-io", "sp-runtime", - "sp-std", + "sp-std 5.0.0", ] [[package]] @@ -6631,7 +7083,7 @@ dependencies = [ "sp-core", "sp-io", "sp-runtime", - "sp-std", + "sp-std 5.0.0", "sp-tracing", "test-case 2.2.2", "test-utils", @@ -6652,12 +7104,12 @@ dependencies = [ "sp-core", "sp-io", "sp-runtime", - "sp-std", + "sp-std 5.0.0", ] [[package]] name = "pallet-democracy" -version = "4.0.1-dev" +version = "4.0.2-dev" dependencies = [ "frame-benchmarking", "frame-support", @@ -6672,7 +7124,7 @@ dependencies = [ "sp-core", "sp-io", "sp-runtime", - "sp-std", + "sp-std 5.0.0", ] [[package]] @@ -6695,7 +7147,7 @@ dependencies = [ "sp-core", "sp-io", "sp-runtime", - "sp-std", + "sp-std 5.0.0", "substrate-wasm-builder", ] @@ -6718,7 +7170,7 @@ dependencies = [ "sp-core", "sp-io", "sp-runtime", - "sp-std", + "sp-std 5.0.0", ] [[package]] @@ -6740,7 +7192,7 @@ dependencies = [ "sp-io", "sp-npos-elections", "sp-runtime", - "sp-std", + "sp-std 5.0.0", "strum", ] @@ -6772,7 +7224,7 @@ dependencies = [ "sp-io", "sp-npos-elections", "sp-runtime", - "sp-std", + "sp-std 5.0.0", ] [[package]] @@ -6795,7 +7247,79 @@ dependencies = [ "sp-arithmetic", "sp-core", "sp-io", - "sp-std", + "sp-std 5.0.0", +] + +[[package]] +name = "pallet-ethereum" +version = "4.0.0-dev" +source = "git+https://github.com/PureStake/frontier?branch=moonbeam-polkadot-v0.9.38#df4e329ef9b1ef54d83114deff98124139f1dd6d" +dependencies = [ + "environmental", + "ethereum", + "ethereum-types", + "evm 0.37.0", + "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", + "sp-io", + "sp-runtime", + "sp-std 5.0.0", +] + +[[package]] +name = "pallet-evm" +version = "6.0.0-dev" +source = "git+https://github.com/PureStake/frontier?branch=moonbeam-polkadot-v0.9.38#df4e329ef9b1ef54d83114deff98124139f1dd6d" +dependencies = [ + "environmental", + "evm 0.37.0", + "fp-evm", + "frame-benchmarking", + "frame-support", + "frame-system", + "hex", + "impl-trait-for-tuples", + "log", + "pallet-timestamp", + "parity-scale-codec", + "rlp", + "scale-info", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std 5.0.0", +] + +[[package]] +name = "pallet-evm-chain-id" +version = "1.0.0-dev" +source = "git+https://github.com/PureStake/frontier?branch=moonbeam-polkadot-v0.9.38#df4e329ef9b1ef54d83114deff98124139f1dd6d" +dependencies = [ + "frame-support", + "frame-system", + "parity-scale-codec", + "scale-info", +] + +[[package]] +name = "pallet-evm-precompile-dispatch" +version = "2.0.0-dev" +source = "git+https://github.com/PureStake/frontier?branch=moonbeam-polkadot-v0.9.38#df4e329ef9b1ef54d83114deff98124139f1dd6d" +dependencies = [ + "fp-evm", + "frame-support", + "pallet-evm", ] [[package]] @@ -6813,7 +7337,7 @@ dependencies = [ "sp-io", "sp-runtime", "sp-staking", - "sp-std", + "sp-std 5.0.0", ] [[package]] @@ -6830,7 +7354,7 @@ dependencies = [ "sp-core", "sp-io", "sp-runtime", - "sp-std", + "sp-std 5.0.0", ] [[package]] @@ -6853,7 +7377,7 @@ dependencies = [ "sp-runtime", "sp-session", "sp-staking", - "sp-std", + "sp-std 5.0.0", ] [[package]] @@ -6869,7 +7393,7 @@ dependencies = [ "scale-info", "sp-io", "sp-runtime", - "sp-std", + "sp-std 5.0.0", ] [[package]] @@ -6889,7 +7413,7 @@ dependencies = [ "sp-io", "sp-runtime", "sp-staking", - "sp-std", + "sp-std 5.0.0", ] [[package]] @@ -6906,7 +7430,7 @@ dependencies = [ "sp-io", "sp-keyring", "sp-runtime", - "sp-std", + "sp-std 5.0.0", ] [[package]] @@ -6930,7 +7454,7 @@ dependencies = [ "sp-core", "sp-io", "sp-runtime", - "sp-std", + "sp-std 5.0.0", "substrate-wasm-builder", "test-utils", ] @@ -6957,7 +7481,7 @@ dependencies = [ "sp-core", "sp-io", "sp-runtime", - "sp-std", + "sp-std 5.0.0", "test-utils", ] @@ -6975,7 +7499,7 @@ dependencies = [ "sp-core", "sp-io", "sp-runtime", - "sp-std", + "sp-std 5.0.0", ] [[package]] @@ -6992,7 +7516,7 @@ dependencies = [ "sp-io", "sp-mmr-primitives", "sp-runtime", - "sp-std", + "sp-std 5.0.0", ] [[package]] @@ -7008,7 +7532,7 @@ dependencies = [ "scale-info", "sp-io", "sp-runtime", - "sp-std", + "sp-std 5.0.0", ] [[package]] @@ -7024,7 +7548,7 @@ dependencies = [ "sp-arithmetic", "sp-core", "sp-runtime", - "sp-std", + "sp-std 5.0.0", ] [[package]] @@ -7041,7 +7565,7 @@ dependencies = [ "sp-io", "sp-runtime", "sp-staking", - "sp-std", + "sp-std 5.0.0", ] [[package]] @@ -7061,7 +7585,7 @@ dependencies = [ "sp-runtime", "sp-runtime-interface", "sp-staking", - "sp-std", + "sp-std 5.0.0", ] [[package]] @@ -7071,7 +7595,7 @@ source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.38#bc dependencies = [ "parity-scale-codec", "sp-api", - "sp-std", + "sp-std 5.0.0", ] [[package]] @@ -7088,7 +7612,7 @@ dependencies = [ "serde", "sp-runtime", "sp-staking", - "sp-std", + "sp-std 5.0.0", ] [[package]] @@ -7112,7 +7636,7 @@ dependencies = [ "scale-info", "sp-runtime", "sp-staking", - "sp-std", + "sp-std 5.0.0", ] [[package]] @@ -7138,7 +7662,7 @@ dependencies = [ "sp-core", "sp-io", "sp-runtime", - "sp-std", + "sp-std 5.0.0", "sp-tracing", ] @@ -7167,7 +7691,7 @@ dependencies = [ "sp-core", "sp-io", "sp-runtime", - "sp-std", + "sp-std 5.0.0", "test-utils", ] @@ -7189,7 +7713,7 @@ dependencies = [ "sp-core", "sp-io", "sp-runtime", - "sp-std", + "sp-std 5.0.0", "test-utils", ] @@ -7207,7 +7731,7 @@ dependencies = [ "sp-core", "sp-io", "sp-runtime", - "sp-std", + "sp-std 5.0.0", ] [[package]] @@ -7222,7 +7746,7 @@ dependencies = [ "scale-info", "sp-io", "sp-runtime", - "sp-std", + "sp-std 5.0.0", ] [[package]] @@ -7240,7 +7764,7 @@ dependencies = [ "sp-core", "sp-io", "sp-runtime", - "sp-std", + "sp-std 5.0.0", ] [[package]] @@ -7255,7 +7779,7 @@ dependencies = [ "scale-info", "sp-io", "sp-runtime", - "sp-std", + "sp-std 5.0.0", ] [[package]] @@ -7274,7 +7798,7 @@ dependencies = [ "sp-arithmetic", "sp-io", "sp-runtime", - "sp-std", + "sp-std 5.0.0", ] [[package]] @@ -7288,7 +7812,7 @@ dependencies = [ "parity-scale-codec", "scale-info", "sp-api", - "sp-std", + "sp-std 5.0.0", ] [[package]] @@ -7312,7 +7836,7 @@ dependencies = [ "sp-core", "sp-io", "sp-runtime", - "sp-std", + "sp-std 5.0.0", "test-utils", ] @@ -7329,7 +7853,7 @@ dependencies = [ "scale-info", "sp-io", "sp-runtime", - "sp-std", + "sp-std 5.0.0", "sp-weights", ] @@ -7350,7 +7874,7 @@ dependencies = [ "sp-runtime", "sp-session", "sp-staking", - "sp-std", + "sp-std 5.0.0", "sp-trie", ] @@ -7367,7 +7891,7 @@ dependencies = [ "rand 0.8.5", "sp-runtime", "sp-session", - "sp-std", + "sp-std 5.0.0", ] [[package]] @@ -7381,12 +7905,12 @@ dependencies = [ "rand_chacha 0.2.2", "scale-info", "sp-runtime", - "sp-std", + "sp-std 5.0.0", ] [[package]] name = "pallet-stableswap" -version = "3.3.1" +version = "3.4.0" dependencies = [ "bitflags", "frame-benchmarking", @@ -7404,7 +7928,7 @@ dependencies = [ "sp-core", "sp-io", "sp-runtime", - "sp-std", + "sp-std 5.0.0", "sp-tracing", ] @@ -7420,7 +7944,7 @@ dependencies = [ "orml-tokens", "orml-traits", "pallet-balances", - "pallet-democracy 4.0.1-dev", + "pallet-democracy 4.0.2-dev", "pallet-uniques", "parity-scale-codec", "pretty_assertions", @@ -7429,7 +7953,7 @@ dependencies = [ "sp-core", "sp-io", "sp-runtime", - "sp-std", + "sp-std 5.0.0", ] [[package]] @@ -7452,7 +7976,7 @@ dependencies = [ "sp-io", "sp-runtime", "sp-staking", - "sp-std", + "sp-std 5.0.0", ] [[package]] @@ -7489,7 +8013,7 @@ dependencies = [ "sp-core", "sp-io", "sp-runtime", - "sp-std", + "sp-std 5.0.0", ] [[package]] @@ -7503,7 +8027,7 @@ dependencies = [ "scale-info", "sp-io", "sp-runtime", - "sp-std", + "sp-std 5.0.0", ] [[package]] @@ -7520,7 +8044,7 @@ dependencies = [ "sp-inherents", "sp-io", "sp-runtime", - "sp-std", + "sp-std 5.0.0", "sp-timestamp", ] @@ -7540,12 +8064,12 @@ dependencies = [ "sp-core", "sp-io", "sp-runtime", - "sp-std", + "sp-std 5.0.0", ] [[package]] name = "pallet-transaction-multi-payment" -version = "9.0.1" +version = "9.0.2" dependencies = [ "frame-support", "frame-system", @@ -7554,14 +8078,16 @@ dependencies = [ "orml-traits", "pallet-balances", "pallet-currencies", + "pallet-evm", "pallet-transaction-payment", "parity-scale-codec", + "primitives", "scale-info", "sp-api", "sp-core", "sp-io", "sp-runtime", - "sp-std", + "sp-std 5.0.0", "test-utils", ] @@ -7583,7 +8109,7 @@ dependencies = [ "sp-core", "sp-io", "sp-runtime", - "sp-std", + "sp-std 5.0.0", ] [[package]] @@ -7599,7 +8125,7 @@ dependencies = [ "sp-core", "sp-io", "sp-runtime", - "sp-std", + "sp-std 5.0.0", ] [[package]] @@ -7644,7 +8170,7 @@ dependencies = [ "scale-info", "serde", "sp-runtime", - "sp-std", + "sp-std 5.0.0", ] [[package]] @@ -7659,7 +8185,7 @@ dependencies = [ "parity-scale-codec", "scale-info", "sp-runtime", - "sp-std", + "sp-std 5.0.0", ] [[package]] @@ -7675,7 +8201,7 @@ dependencies = [ "sp-core", "sp-io", "sp-runtime", - "sp-std", + "sp-std 5.0.0", ] [[package]] @@ -7690,7 +8216,7 @@ dependencies = [ "parity-scale-codec", "scale-info", "sp-runtime", - "sp-std", + "sp-std 5.0.0", ] [[package]] @@ -7705,7 +8231,7 @@ dependencies = [ "scale-info", "sp-api", "sp-runtime", - "sp-std", + "sp-std 5.0.0", ] [[package]] @@ -7723,7 +8249,7 @@ dependencies = [ "sp-core", "sp-io", "sp-runtime", - "sp-std", + "sp-std 5.0.0", "xcm", "xcm-executor", ] @@ -7741,7 +8267,7 @@ dependencies = [ "scale-info", "sp-io", "sp-runtime", - "sp-std", + "sp-std 5.0.0", "xcm", "xcm-builder", "xcm-executor", @@ -7770,7 +8296,7 @@ dependencies = [ "sp-core", "sp-io", "sp-runtime", - "sp-std", + "sp-std 5.0.0", "test-case 3.1.0", "test-utils", "xcm", @@ -7800,14 +8326,14 @@ dependencies = [ "sp-core", "sp-io", "sp-runtime", - "sp-std", + "sp-std 5.0.0", "substrate-wasm-builder", ] [[package]] name = "parachain-info" version = "0.1.0" -source = "git+https://github.com/galacticcouncil/cumulus.git?branch=feat/xcmp-defer-xcm-v9-38#460647cc2ec988ee04370c1cdd9fd518ed4868eb" +source = "git+https://github.com/galacticcouncil/cumulus.git?rev=460647cc2ec988ee04370c1cdd9fd518ed4868eb#460647cc2ec988ee04370c1cdd9fd518ed4868eb" dependencies = [ "cumulus-primitives-core", "frame-support", @@ -8321,7 +8847,7 @@ dependencies = [ "scale-info", "sp-core", "sp-runtime", - "sp-std", + "sp-std 5.0.0", ] [[package]] @@ -8921,7 +9447,7 @@ dependencies = [ "serde", "sp-core", "sp-runtime", - "sp-std", + "sp-std 5.0.0", ] [[package]] @@ -8962,7 +9488,7 @@ dependencies = [ "sp-keystore", "sp-runtime", "sp-staking", - "sp-std", + "sp-std 5.0.0", ] [[package]] @@ -9076,7 +9602,7 @@ dependencies = [ "sp-runtime", "sp-session", "sp-staking", - "sp-std", + "sp-std 5.0.0", "sp-transaction-pool", "sp-version", "static_assertions", @@ -9130,7 +9656,7 @@ dependencies = [ "sp-runtime", "sp-session", "sp-staking", - "sp-std", + "sp-std 5.0.0", "static_assertions", "xcm", ] @@ -9157,7 +9683,7 @@ dependencies = [ "bs58", "parity-scale-codec", "polkadot-primitives", - "sp-std", + "sp-std 5.0.0", "sp-tracing", ] @@ -9198,7 +9724,7 @@ dependencies = [ "sp-runtime", "sp-session", "sp-staking", - "sp-std", + "sp-std 5.0.0", "static_assertions", "xcm", "xcm-executor", @@ -9458,6 +9984,7 @@ checksum = "9f3486ccba82358b11a77516035647c34ba167dfa53312630de83b12bd4f3d66" dependencies = [ "fixed-hash", "impl-codec", + "impl-rlp", "impl-serde", "scale-info", "uint", @@ -9474,7 +10001,7 @@ dependencies = [ "scale-info", "serde", "sp-core", - "sp-std", + "sp-std 5.0.0", "static_assertions", ] @@ -10032,6 +10559,28 @@ dependencies = [ "winapi", ] +[[package]] +name = "rlp" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb919243f34364b6bd2fc10ef797edbfa75f33c252e7998527479c6d6b47e1ec" +dependencies = [ + "bytes", + "rlp-derive", + "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 1.0.109", +] + [[package]] name = "rocksdb" version = "0.19.0" @@ -10118,7 +10667,7 @@ dependencies = [ "sp-runtime", "sp-session", "sp-staking", - "sp-std", + "sp-std 5.0.0", "sp-transaction-pool", "sp-version", "static_assertions", @@ -10218,7 +10767,7 @@ dependencies = [ [[package]] name = "runtime-integration-tests" -version = "1.15.2" +version = "1.16.0" dependencies = [ "cumulus-pallet-aura-ext", "cumulus-pallet-dmp-queue", @@ -10229,7 +10778,8 @@ dependencies = [ "cumulus-primitives-parachain-inherent", "cumulus-primitives-timestamp", "cumulus-primitives-utility", - "cumulus-test-relay-sproof-builder 0.1.0 (git+https://github.com/paritytech/cumulus.git?branch=polkadot-v0.9.38)", + "cumulus-test-relay-sproof-builder", + "fp-evm", "frame-benchmarking", "frame-executive", "frame-remote-externalities", @@ -10258,11 +10808,12 @@ dependencies = [ "pallet-collective", "pallet-currencies", "pallet-dca", - "pallet-democracy 4.0.1-dev", + "pallet-democracy 4.0.2-dev", "pallet-duster", "pallet-dynamic-fees", "pallet-elections-phragmen", "pallet-ema-oracle", + "pallet-evm", "pallet-lbp", "pallet-liquidity-mining", "pallet-omnipool", @@ -10304,7 +10855,7 @@ dependencies = [ "sp-runtime", "sp-session", "sp-staking", - "sp-std", + "sp-std 5.0.0", "sp-transaction-pool", "sp-trie", "sp-version", @@ -11418,7 +11969,7 @@ dependencies = [ "serde_json", "sp-core", "sp-io", - "sp-std", + "sp-std 5.0.0", ] [[package]] @@ -11936,7 +12487,7 @@ dependencies = [ "parity-scale-codec", "paste", "sp-runtime", - "sp-std", + "sp-std 5.0.0", ] [[package]] @@ -12026,7 +12577,7 @@ dependencies = [ "sp-core", "sp-runtime", "sp-state-machine", - "sp-std", + "sp-std 5.0.0", "sp-trie", "sp-version", "thiserror", @@ -12054,7 +12605,7 @@ dependencies = [ "serde", "sp-core", "sp-io", - "sp-std", + "sp-std 5.0.0", ] [[package]] @@ -12067,7 +12618,7 @@ dependencies = [ "parity-scale-codec", "scale-info", "serde", - "sp-std", + "sp-std 5.0.0", "static_assertions", ] @@ -12081,7 +12632,7 @@ dependencies = [ "sp-api", "sp-application-crypto", "sp-runtime", - "sp-std", + "sp-std 5.0.0", ] [[package]] @@ -12098,7 +12649,7 @@ dependencies = [ "sp-io", "sp-mmr-primitives", "sp-runtime", - "sp-std", + "sp-std 5.0.0", ] [[package]] @@ -12110,7 +12661,7 @@ dependencies = [ "sp-api", "sp-inherents", "sp-runtime", - "sp-std", + "sp-std 5.0.0", ] [[package]] @@ -12144,7 +12695,7 @@ dependencies = [ "sp-inherents", "sp-runtime", "sp-state-machine", - "sp-std", + "sp-std 5.0.0", "sp-version", "thiserror", ] @@ -12163,7 +12714,7 @@ dependencies = [ "sp-consensus-slots", "sp-inherents", "sp-runtime", - "sp-std", + "sp-std 5.0.0", "sp-timestamp", ] @@ -12186,7 +12737,7 @@ dependencies = [ "sp-inherents", "sp-keystore", "sp-runtime", - "sp-std", + "sp-std 5.0.0", "sp-timestamp", ] @@ -12198,7 +12749,7 @@ dependencies = [ "parity-scale-codec", "scale-info", "serde", - "sp-std", + "sp-std 5.0.0", "sp-timestamp", ] @@ -12212,7 +12763,7 @@ dependencies = [ "schnorrkel", "sp-core", "sp-runtime", - "sp-std", + "sp-std 5.0.0", ] [[package]] @@ -12248,7 +12799,7 @@ dependencies = [ "sp-debug-derive", "sp-externalities", "sp-runtime-interface", - "sp-std", + "sp-std 5.0.0", "sp-storage", "ss58-registry", "substrate-bip39", @@ -12267,7 +12818,7 @@ dependencies = [ "digest 0.10.7", "sha2 0.10.7", "sha3", - "sp-std", + "sp-std 5.0.0", "twox-hash", ] @@ -12308,7 +12859,7 @@ source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.38#bc dependencies = [ "environmental", "parity-scale-codec", - "sp-std", + "sp-std 5.0.0", "sp-storage", ] @@ -12327,7 +12878,7 @@ dependencies = [ "sp-core", "sp-keystore", "sp-runtime", - "sp-std", + "sp-std 5.0.0", ] [[package]] @@ -12340,7 +12891,7 @@ dependencies = [ "parity-scale-codec", "sp-core", "sp-runtime", - "sp-std", + "sp-std 5.0.0", "thiserror", ] @@ -12362,7 +12913,7 @@ dependencies = [ "sp-keystore", "sp-runtime-interface", "sp-state-machine", - "sp-std", + "sp-std 5.0.0", "sp-tracing", "sp-trie", "tracing", @@ -12420,7 +12971,7 @@ dependencies = [ "sp-core", "sp-debug-derive", "sp-runtime", - "sp-std", + "sp-std 5.0.0", "thiserror", ] @@ -12435,7 +12986,7 @@ dependencies = [ "sp-arithmetic", "sp-core", "sp-runtime", - "sp-std", + "sp-std 5.0.0", ] [[package]] @@ -12486,7 +13037,7 @@ dependencies = [ "sp-arithmetic", "sp-core", "sp-io", - "sp-std", + "sp-std 5.0.0", "sp-weights", ] @@ -12501,7 +13052,7 @@ dependencies = [ "primitive-types", "sp-externalities", "sp-runtime-interface-proc-macro", - "sp-std", + "sp-std 5.0.0", "sp-storage", "sp-tracing", "sp-wasm-interface", @@ -12531,7 +13082,7 @@ dependencies = [ "sp-core", "sp-runtime", "sp-staking", - "sp-std", + "sp-std 5.0.0", ] [[package]] @@ -12543,7 +13094,7 @@ dependencies = [ "scale-info", "sp-core", "sp-runtime", - "sp-std", + "sp-std 5.0.0", ] [[package]] @@ -12560,7 +13111,7 @@ dependencies = [ "sp-core", "sp-externalities", "sp-panic-handler", - "sp-std", + "sp-std 5.0.0", "sp-trie", "thiserror", "tracing", @@ -12571,6 +13122,11 @@ name = "sp-std" version = "5.0.0" source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.38#bcff60a227d455d95b4712b6cb356ce56b1ff672" +[[package]] +name = "sp-std" +version = "8.0.0" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v1.0.0#948fbd2fd1233dc26dbb9f9bbc1d2cca2c03945d" + [[package]] name = "sp-storage" version = "7.0.0" @@ -12581,7 +13137,7 @@ dependencies = [ "ref-cast", "serde", "sp-debug-derive", - "sp-std", + "sp-std 5.0.0", ] [[package]] @@ -12595,7 +13151,7 @@ dependencies = [ "parity-scale-codec", "sp-inherents", "sp-runtime", - "sp-std", + "sp-std 5.0.0", "thiserror", ] @@ -12605,7 +13161,7 @@ version = "6.0.0" source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.38#bcff60a227d455d95b4712b6cb356ce56b1ff672" dependencies = [ "parity-scale-codec", - "sp-std", + "sp-std 5.0.0", "tracing", "tracing-core", "tracing-subscriber", @@ -12632,7 +13188,7 @@ dependencies = [ "sp-core", "sp-inherents", "sp-runtime", - "sp-std", + "sp-std 5.0.0", "sp-trie", ] @@ -12652,7 +13208,7 @@ dependencies = [ "scale-info", "schnellru", "sp-core", - "sp-std", + "sp-std 5.0.0", "thiserror", "tracing", "trie-db", @@ -12671,7 +13227,7 @@ dependencies = [ "serde", "sp-core-hashing-proc-macro", "sp-runtime", - "sp-std", + "sp-std 5.0.0", "sp-version-proc-macro", "thiserror", ] @@ -12695,7 +13251,7 @@ dependencies = [ "impl-trait-for-tuples", "log", "parity-scale-codec", - "sp-std", + "sp-std 5.0.0", "wasmi", "wasmtime", ] @@ -12712,7 +13268,7 @@ dependencies = [ "sp-arithmetic", "sp-core", "sp-debug-derive", - "sp-std", + "sp-std 5.0.0", ] [[package]] @@ -13290,6 +13846,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 = "tinytemplate" version = "1.2.1" @@ -13607,6 +14172,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.22.0" @@ -14620,7 +15195,7 @@ dependencies = [ "sp-runtime", "sp-session", "sp-staking", - "sp-std", + "sp-std 5.0.0", "sp-transaction-pool", "sp-version", "substrate-wasm-builder", @@ -15029,7 +15604,7 @@ dependencies = [ "sp-arithmetic", "sp-io", "sp-runtime", - "sp-std", + "sp-std 5.0.0", "xcm", "xcm-executor", ] @@ -15044,7 +15619,7 @@ dependencies = [ "cumulus-pallet-xcmp-queue", "cumulus-primitives-core", "cumulus-primitives-parachain-inherent", - "cumulus-test-relay-sproof-builder 0.1.0 (git+https://github.com/paritytech/cumulus.git?branch=polkadot-v0.9.38)", + "cumulus-test-relay-sproof-builder", "frame-support", "frame-system", "parachain-info", @@ -15055,7 +15630,7 @@ dependencies = [ "quote", "sp-arithmetic", "sp-io", - "sp-std", + "sp-std 5.0.0", "xcm", "xcm-executor", ] @@ -15075,7 +15650,7 @@ dependencies = [ "sp-core", "sp-io", "sp-runtime", - "sp-std", + "sp-std 5.0.0", "sp-weights", "xcm", ] diff --git a/Cargo.toml b/Cargo.toml index f4554dcd7..649a51331 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -38,6 +38,8 @@ members = [ ] [workspace.dependencies] +async-trait = "0.1" +futures = "0.3.25" hydra-dx-math = { path = "math", default-features = false } hydradx = { path = "node", default-features = false } hydradx-traits = { path = "traits", default-features = false } @@ -103,6 +105,7 @@ sp-blockchain = { git = "https://github.com/paritytech/substrate", branch = "pol sp-consensus = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38", default-features = false } sp-consensus-aura = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38", default-features = false } sp-core = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38", default-features = false } +sp-database = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38", default-features = false } sp-externalities = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38", default-features = false } sp-inherents = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38", default-features = false } sp-io = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38", default-features = false } @@ -124,6 +127,7 @@ sc-basic-authorship = { git = "https://github.com/paritytech/substrate", branch sc-chain-spec = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38", default-features = false } sc-cli = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38", default-features = false } sc-client-api = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38", default-features = false } +sc-client-db = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38", default-features = false } sc-consensus = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38", default-features = false } sc-consensus-aura = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38", default-features = false } sc-executor = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38", default-features = false } @@ -193,7 +197,7 @@ cumulus-pallet-aura-ext = { git = "https://github.com/paritytech/cumulus.git", b cumulus-pallet-dmp-queue = { git = "https://github.com/paritytech/cumulus.git", branch = "polkadot-v0.9.38", default-features = false } cumulus-pallet-parachain-system = { git = "https://github.com/paritytech/cumulus.git", branch = "polkadot-v0.9.38", default-features = false } cumulus-pallet-xcm = { git = "https://github.com/paritytech/cumulus.git", branch = "polkadot-v0.9.38", default-features = false } -cumulus-pallet-xcmp-queue = { git = "https://github.com/paritytech/cumulus.git", branch = "polkadot-v0.9.38", default-features = false } +cumulus-pallet-xcmp-queue = { git = "https://github.com/paritytech/cumulus.git", default-features = false, rev = "460647cc2ec988ee04370c1cdd9fd518ed4868eb"} cumulus-primitives-core = { git = "https://github.com/paritytech/cumulus.git", branch = "polkadot-v0.9.38", default-features = false } cumulus-primitives-parachain-inherent = { git = "https://github.com/paritytech/cumulus.git", branch = "polkadot-v0.9.38", default-features = false } cumulus-primitives-timestamp = { git = "https://github.com/paritytech/cumulus.git", branch = "polkadot-v0.9.38", default-features = false } @@ -205,6 +209,26 @@ cumulus-test-relay-sproof-builder = { git = "https://github.com/paritytech/cumul pallet-collator-selection = { git = "https://github.com/paritytech/cumulus.git", branch = "polkadot-v0.9.38", default-features = false } parachain-info = { git = "https://github.com/paritytech/cumulus.git", branch = "polkadot-v0.9.38", default-features = false } +# Frontier +fc-consensus = { git = "https://github.com/PureStake/frontier", branch = "moonbeam-polkadot-v0.9.38", default-features = false } +fc-db = { git = "https://github.com/PureStake/frontier", branch = "moonbeam-polkadot-v0.9.38", default-features = false } +fc-mapping-sync = { git = "https://github.com/PureStake/frontier", branch = "moonbeam-polkadot-v0.9.38", default-features = false } +fc-rpc = { git = "https://github.com/PureStake/frontier", branch = "moonbeam-polkadot-v0.9.38", default-features = false } +fc-rpc-core = { git = "https://github.com/PureStake/frontier", branch = "moonbeam-polkadot-v0.9.38", default-features = false } + +fp-evm = { git = "https://github.com/PureStake/frontier", branch = "moonbeam-polkadot-v0.9.38", default-features = false } +fp-rpc = { git = "https://github.com/PureStake/frontier", branch = "moonbeam-polkadot-v0.9.38", default-features = false } +fp-self-contained = { git = "https://github.com/PureStake/frontier", branch = "moonbeam-polkadot-v0.9.38", default-features = false } +fp-storage = { git = "https://github.com/PureStake/frontier", branch = "moonbeam-polkadot-v0.9.38", default-features = false } + +pallet-ethereum = { git = "https://github.com/PureStake/frontier", branch = "moonbeam-polkadot-v0.9.38", default-features = false } +pallet-evm = { git = "https://github.com/PureStake/frontier", branch = "moonbeam-polkadot-v0.9.38", default-features = false } +pallet-evm-chain-id = { git = "https://github.com/PureStake/frontier", branch = "moonbeam-polkadot-v0.9.38", default-features = false } +pallet-evm-precompile-dispatch = { git = "https://github.com/PureStake/frontier", branch = "moonbeam-polkadot-v0.9.38", default-features = false } + +# EVM from acala +module-evm-utility-macro = { git = "https://github.com/AcalaNetwork/Acala", branch = "release-acala-2.22.0", default-features = false } + # Polkadot dependencies pallet-xcm = { git = "https://github.com/paritytech/polkadot", branch = "release-v0.9.38", default-features = false } polkadot-cli = { git = "https://github.com/paritytech/polkadot", branch = "release-v0.9.38" } @@ -247,27 +271,231 @@ xcm-builder = { git = "https://github.com/galacticcouncil/polkadot", branch = "f xcm-executor = { git = "https://github.com/galacticcouncil/polkadot", branch = "fix-xcm-executor-atomicity-9-38" } [patch."https://github.com/paritytech/cumulus"] -cumulus-client-cli = { git = "https://github.com/galacticcouncil/cumulus.git", branch = "feat/xcmp-defer-xcm-v9-38" } -cumulus-client-collator = { git = "https://github.com/galacticcouncil/cumulus.git", branch = "feat/xcmp-defer-xcm-v9-38" } -cumulus-client-consensus-aura = { git = "https://github.com/galacticcouncil/cumulus.git", branch = "feat/xcmp-defer-xcm-v9-38" } -cumulus-client-consensus-common = { git = "https://github.com/galacticcouncil/cumulus.git", branch = "feat/xcmp-defer-xcm-v9-38" } -cumulus-client-consensus-relay-chain = { git = "https://github.com/galacticcouncil/cumulus.git", branch = "feat/xcmp-defer-xcm-v9-38" } -cumulus-client-network = { git = "https://github.com/galacticcouncil/cumulus.git", branch = "feat/xcmp-defer-xcm-v9-38" } -cumulus-client-pov-recovery = { git = "https://github.com/galacticcouncil/cumulus.git", branch = "feat/xcmp-defer-xcm-v9-38" } -cumulus-client-service = { git = "https://github.com/galacticcouncil/cumulus.git", branch = "feat/xcmp-defer-xcm-v9-38" } -cumulus-pallet-aura-ext = { git = "https://github.com/galacticcouncil/cumulus.git", branch = "feat/xcmp-defer-xcm-v9-38" } -cumulus-pallet-dmp-queue = { git = "https://github.com/galacticcouncil/cumulus.git", branch = "feat/xcmp-defer-xcm-v9-38" } -cumulus-pallet-parachain-system = { git = "https://github.com/galacticcouncil/cumulus.git", branch = "feat/xcmp-defer-xcm-v9-38" } -cumulus-pallet-parachain-system-proc-macro = { git = "https://github.com/galacticcouncil/cumulus.git", branch = "feat/xcmp-defer-xcm-v9-38" } -cumulus-pallet-xcm = { git = "https://github.com/galacticcouncil/cumulus.git", branch = "feat/xcmp-defer-xcm-v9-38" } -cumulus-pallet-xcmp-queue = { git = "https://github.com/galacticcouncil/cumulus.git", branch = "feat/xcmp-defer-xcm-v9-38" } -cumulus-primitives-core = { git = "https://github.com/galacticcouncil/cumulus.git", branch = "feat/xcmp-defer-xcm-v9-38" } -cumulus-primitives-parachain-inherent = { git = "https://github.com/galacticcouncil/cumulus.git", branch = "feat/xcmp-defer-xcm-v9-38" } -cumulus-primitives-timestamp = { git = "https://github.com/galacticcouncil/cumulus.git", branch = "feat/xcmp-defer-xcm-v9-38" } -cumulus-primitives-utility = { git = "https://github.com/galacticcouncil/cumulus.git", branch = "feat/xcmp-defer-xcm-v9-38" } -cumulus-relay-chain-inprocess-interface = { git = "https://github.com/galacticcouncil/cumulus.git", branch = "feat/xcmp-defer-xcm-v9-38" } -cumulus-relay-chain-interface = { git = "https://github.com/galacticcouncil/cumulus.git", branch = "feat/xcmp-defer-xcm-v9-38" } -cumulus-relay-chain-minimal-node = { git = "https://github.com/galacticcouncil/cumulus.git", branch = "feat/xcmp-defer-xcm-v9-38" } -cumulus-relay-chain-rpc-interface = { git = "https://github.com/galacticcouncil/cumulus.git", branch = "feat/xcmp-defer-xcm-v9-38" } -pallet-collator-selection = { git = "https://github.com/galacticcouncil/cumulus.git", branch = "feat/xcmp-defer-xcm-v9-38" } -parachain-info = { git = "https://github.com/galacticcouncil/cumulus.git", branch = "feat/xcmp-defer-xcm-v9-38" } +cumulus-client-cli = { git = "https://github.com/galacticcouncil/cumulus.git", rev = "460647cc2ec988ee04370c1cdd9fd518ed4868eb" } +cumulus-client-collator = { git = "https://github.com/galacticcouncil/cumulus.git", rev = "460647cc2ec988ee04370c1cdd9fd518ed4868eb" } +cumulus-client-consensus-aura = { git = "https://github.com/galacticcouncil/cumulus.git", rev = "460647cc2ec988ee04370c1cdd9fd518ed4868eb" } +cumulus-client-consensus-common = { git = "https://github.com/galacticcouncil/cumulus.git", rev = "460647cc2ec988ee04370c1cdd9fd518ed4868eb" } +cumulus-client-consensus-relay-chain = { git = "https://github.com/galacticcouncil/cumulus.git", rev = "460647cc2ec988ee04370c1cdd9fd518ed4868eb" } +cumulus-client-network = { git = "https://github.com/galacticcouncil/cumulus.git", rev = "460647cc2ec988ee04370c1cdd9fd518ed4868eb" } +cumulus-client-pov-recovery = { git = "https://github.com/galacticcouncil/cumulus.git", rev = "460647cc2ec988ee04370c1cdd9fd518ed4868eb" } +cumulus-client-service = { git = "https://github.com/galacticcouncil/cumulus.git", rev = "460647cc2ec988ee04370c1cdd9fd518ed4868eb" } +cumulus-pallet-aura-ext = { git = "https://github.com/galacticcouncil/cumulus.git", rev = "460647cc2ec988ee04370c1cdd9fd518ed4868eb" } +cumulus-pallet-dmp-queue = { git = "https://github.com/galacticcouncil/cumulus.git", rev = "460647cc2ec988ee04370c1cdd9fd518ed4868eb" } +cumulus-pallet-parachain-system = { git = "https://github.com/galacticcouncil/cumulus.git", rev = "460647cc2ec988ee04370c1cdd9fd518ed4868eb" } +cumulus-pallet-parachain-system-proc-macro = { git = "https://github.com/galacticcouncil/cumulus.git", rev = "460647cc2ec988ee04370c1cdd9fd518ed4868eb" } +cumulus-pallet-xcm = { git = "https://github.com/galacticcouncil/cumulus.git", rev = "460647cc2ec988ee04370c1cdd9fd518ed4868eb" } +cumulus-pallet-xcmp-queue = { git = "https://github.com/galacticcouncil/cumulus.git", rev = "460647cc2ec988ee04370c1cdd9fd518ed4868eb" } +cumulus-primitives-core = { git = "https://github.com/galacticcouncil/cumulus.git", rev = "460647cc2ec988ee04370c1cdd9fd518ed4868eb" } +cumulus-primitives-parachain-inherent = { git = "https://github.com/galacticcouncil/cumulus.git", rev = "460647cc2ec988ee04370c1cdd9fd518ed4868eb" } +cumulus-primitives-timestamp = { git = "https://github.com/galacticcouncil/cumulus.git", rev = "460647cc2ec988ee04370c1cdd9fd518ed4868eb" } +cumulus-primitives-utility = { git = "https://github.com/galacticcouncil/cumulus.git", rev = "460647cc2ec988ee04370c1cdd9fd518ed4868eb" } +cumulus-relay-chain-inprocess-interface = { git = "https://github.com/galacticcouncil/cumulus.git", rev = "460647cc2ec988ee04370c1cdd9fd518ed4868eb" } +cumulus-relay-chain-interface = { git = "https://github.com/galacticcouncil/cumulus.git", rev = "460647cc2ec988ee04370c1cdd9fd518ed4868eb" } +cumulus-relay-chain-minimal-node = { git = "https://github.com/galacticcouncil/cumulus.git", rev = "460647cc2ec988ee04370c1cdd9fd518ed4868eb" } +cumulus-relay-chain-rpc-interface = { git = "https://github.com/galacticcouncil/cumulus.git", rev = "460647cc2ec988ee04370c1cdd9fd518ed4868eb" } +cumulus-test-relay-sproof-builder = { git = "https://github.com/galacticcouncil/cumulus.git", rev = "460647cc2ec988ee04370c1cdd9fd518ed4868eb" } +pallet-collator-selection = { git = "https://github.com/galacticcouncil/cumulus.git", rev = "460647cc2ec988ee04370c1cdd9fd518ed4868eb" } +parachain-info = { git = "https://github.com/galacticcouncil/cumulus.git", rev = "460647cc2ec988ee04370c1cdd9fd518ed4868eb" } + +[patch."https://github.com/PureStake/substrate"] +frame-benchmarking = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } +frame-benchmarking-cli = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } +frame-election-provider-support = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } +frame-executive = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } +frame-support = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38", default-features = false } +frame-support-procedural = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } +frame-support-procedural-tools = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } +frame-support-procedural-tools-derive = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } +frame-system = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } +frame-system-benchmarking = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } +frame-system-rpc-runtime-api = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } +frame-try-runtime = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } +pallet-aura = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } +pallet-authority-discovery = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } +pallet-authorship = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } +pallet-babe = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } +pallet-balances = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } +pallet-bounties = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } +pallet-child-bounties = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } +pallet-collective = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } +pallet-democracy = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } +pallet-election-provider-multi-phase = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } +pallet-elections-phragmen = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } +pallet-grandpa = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } +pallet-identity = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } +pallet-im-online = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } +pallet-indices = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } +pallet-membership = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } +pallet-mmr = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } +pallet-multisig = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } +pallet-nomination-pools-runtime-api = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } +pallet-offences = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } +pallet-proxy = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } +pallet-recovery = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } +pallet-scheduler = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } +pallet-session = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } +pallet-session-benchmarking = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } +pallet-society = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } +pallet-staking = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } +pallet-staking-reward-curve = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } +pallet-staking-reward-fn = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } +pallet-sudo = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } +pallet-timestamp = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } +pallet-tips = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } +pallet-transaction-payment = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } +pallet-transaction-payment-rpc = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } +pallet-transaction-payment-rpc-runtime-api = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } +pallet-treasury = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } +pallet-uniques = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } +pallet-utility = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } +pallet-vesting = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } +pallet-beefy = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } +pallet-beefy-mmr = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } +pallet-bags-list = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } +pallet-preimage = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } +sp-beefy = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } +beefy-merkle-tree = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } +beefy-gadget = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } +beefy-gadget-rpc = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } +sc-authority-discovery = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } +sc-basic-authorship = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } +sc-block-builder = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } +sc-chain-spec = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } +sc-cli = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } +sc-client-api = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } +sc-client-db = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } +sc-consensus = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } +sc-consensus-aura = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } +sc-consensus-babe = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } +sc-consensus-babe-rpc = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } +sc-consensus-epochs = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } +sc-consensus-slots = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } +sc-executor = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } +sc-executor-common = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } +sc-executor-wasmtime = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } +sc-finality-grandpa = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } +sc-finality-grandpa-rpc = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } +sc-informant = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } +sc-keystore = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } +sc-network = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } +sc-network-common = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } +sc-network-gossip = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } +sc-network-light = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } +sc-network-sync = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } +sc-offchain = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } +sc-rpc = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } +sc-rpc-api = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } +sc-rpc-server = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } +sc-service = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } +sc-sync-state-rpc = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } +sc-sysinfo = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } +sc-storage-monitor = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } +sc-telemetry = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } +sc-tracing = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } +sc-transaction-pool = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } +sc-transaction-pool-api = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } +sc-utils = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } +sp-api = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } +sp-application-crypto = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } +sp-arithmetic = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } +sp-authority-discovery = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } +sp-block-builder = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } +sp-blockchain = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } +sp-consensus = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } +sp-consensus-aura = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } +sp-consensus-babe = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } +sp-consensus-slots = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } +sp-consensus-vrf = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } +sp-core = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } +sp-database = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } +sp-debug-derive = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } +sp-externalities = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } +sp-weights = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } +sp-finality-grandpa = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } +sp-inherents = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } +sp-io = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } +sp-keyring = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } +sp-keystore = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } +sp-maybe-compressed-blob = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } +sp-mmr-primitives = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } +sp-npos-elections = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } +sp-offchain = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } +sp-rpc = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } +sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } +sp-runtime-interface = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } +sp-runtime-interface-proc-macro = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } +sp-session = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } +sp-staking = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } +sp-state-machine = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } +sp-std = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } +sp-storage = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } +sp-timestamp = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } +sp-tracing = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } +sp-transaction-pool = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } +sp-trie = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } +sp-version = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } +sp-wasm-interface = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } +substrate-build-script-utils = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } +substrate-frame-rpc-system = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } +substrate-prometheus-endpoint = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } +substrate-wasm-builder = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } +substrate-state-trie-migration-rpc = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } +try-runtime-cli = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } + +# Cargo patch rules for all the PureStake/polkadot crates +[patch."https://github.com/PureStake/polkadot"] +kusama-runtime = { git = "https://github.com/galacticcouncil/polkadot", branch = "fix-xcm-executor-atomicity-9-38" } +kusama-runtime-constants = { git = "https://github.com/galacticcouncil/polkadot", branch = "fix-xcm-executor-atomicity-9-38" } +pallet-xcm = { git = "https://github.com/galacticcouncil/polkadot", branch = "fix-xcm-executor-atomicity-9-38" } +polkadot-cli = { git = "https://github.com/galacticcouncil/polkadot", branch = "fix-xcm-executor-atomicity-9-38" } +polkadot-client = { git = "https://github.com/galacticcouncil/polkadot", branch = "fix-xcm-executor-atomicity-9-38" } +polkadot-core-primitives = { git = "https://github.com/galacticcouncil/polkadot", branch = "fix-xcm-executor-atomicity-9-38" } +polkadot-network-bridge = { git = "https://github.com/galacticcouncil/polkadot", branch = "fix-xcm-executor-atomicity-9-38" } +polkadot-node-core-av-store = { git = "https://github.com/galacticcouncil/polkadot", branch = "fix-xcm-executor-atomicity-9-38" } +polkadot-node-core-pvf = { git = "https://github.com/galacticcouncil/polkadot", branch = "fix-xcm-executor-atomicity-9-38" } +polkadot-node-network-protocol = { git = "https://github.com/galacticcouncil/polkadot", branch = "fix-xcm-executor-atomicity-9-38" } +polkadot-node-primitives = { git = "https://github.com/galacticcouncil/polkadot", branch = "fix-xcm-executor-atomicity-9-38" } +polkadot-node-subsystem = { git = "https://github.com/galacticcouncil/polkadot", branch = "fix-xcm-executor-atomicity-9-38" } +polkadot-node-subsystem-util = { git = "https://github.com/galacticcouncil/polkadot", branch = "fix-xcm-executor-atomicity-9-38" } +polkadot-overseer = { git = "https://github.com/galacticcouncil/polkadot", branch = "fix-xcm-executor-atomicity-9-38" } +polkadot-parachain = { git = "https://github.com/galacticcouncil/polkadot", branch = "fix-xcm-executor-atomicity-9-38" } +polkadot-primitives = { git = "https://github.com/galacticcouncil/polkadot", branch = "fix-xcm-executor-atomicity-9-38" } +polkadot-runtime = { git = "https://github.com/galacticcouncil/polkadot", branch = "fix-xcm-executor-atomicity-9-38" } +polkadot-runtime-common = { git = "https://github.com/galacticcouncil/polkadot", branch = "fix-xcm-executor-atomicity-9-38" } +polkadot-runtime-constants = { git = "https://github.com/galacticcouncil/polkadot", branch = "fix-xcm-executor-atomicity-9-38" } +polkadot-runtime-parachains = { git = "https://github.com/galacticcouncil/polkadot", branch = "fix-xcm-executor-atomicity-9-38" } +polkadot-service = { git = "https://github.com/galacticcouncil/polkadot", branch = "fix-xcm-executor-atomicity-9-38" } +polkadot-statement-table = { git = "https://github.com/galacticcouncil/polkadot", branch = "fix-xcm-executor-atomicity-9-38" } +polkadot-rpc = { git = "https://github.com/galacticcouncil/polkadot", branch = "fix-xcm-executor-atomicity-9-38" } +rococo-runtime = { git = "https://github.com/galacticcouncil/polkadot", branch = "fix-xcm-executor-atomicity-9-38" } +xcm = { git = "https://github.com/galacticcouncil/polkadot", branch = "fix-xcm-executor-atomicity-9-38" } +xcm-builder = { git = "https://github.com/galacticcouncil/polkadot", branch = "fix-xcm-executor-atomicity-9-38" } +xcm-executor = { git = "https://github.com/galacticcouncil/polkadot", branch = "fix-xcm-executor-atomicity-9-38" } + +# Cargo patch rules for all the PureStake/cumulus crates +[patch."https://github.com/PureStake/cumulus"] +cumulus-client-cli = { git = "https://github.com/galacticcouncil/cumulus.git", rev = "460647cc2ec988ee04370c1cdd9fd518ed4868eb" } +cumulus-client-consensus-aura = { git = "https://github.com/galacticcouncil/cumulus.git", rev = "460647cc2ec988ee04370c1cdd9fd518ed4868eb" } +cumulus-client-consensus-common = { git = "https://github.com/galacticcouncil/cumulus.git", rev = "460647cc2ec988ee04370c1cdd9fd518ed4868eb" } +cumulus-client-network = { git = "https://github.com/galacticcouncil/cumulus.git", rev = "460647cc2ec988ee04370c1cdd9fd518ed4868eb" } +cumulus-client-service = { git = "https://github.com/galacticcouncil/cumulus.git", rev = "460647cc2ec988ee04370c1cdd9fd518ed4868eb" } +cumulus-pallet-aura-ext = { git = "https://github.com/galacticcouncil/cumulus.git", rev = "460647cc2ec988ee04370c1cdd9fd518ed4868eb" } +cumulus-pallet-dmp-queue = { git = "https://github.com/galacticcouncil/cumulus.git", rev = "460647cc2ec988ee04370c1cdd9fd518ed4868eb" } +cumulus-pallet-parachain-system = { git = "https://github.com/galacticcouncil/cumulus.git", rev = "460647cc2ec988ee04370c1cdd9fd518ed4868eb" } +cumulus-pallet-xcm = { git = "https://github.com/galacticcouncil/cumulus.git", rev = "460647cc2ec988ee04370c1cdd9fd518ed4868eb" } +cumulus-pallet-xcmp-queue = { git = "https://github.com/galacticcouncil/cumulus.git", rev = "460647cc2ec988ee04370c1cdd9fd518ed4868eb" } +cumulus-primitives-core = { git = "https://github.com/galacticcouncil/cumulus.git", rev = "460647cc2ec988ee04370c1cdd9fd518ed4868eb" } +cumulus-primitives-parachain-inherent = { git = "https://github.com/galacticcouncil/cumulus.git", rev = "460647cc2ec988ee04370c1cdd9fd518ed4868eb" } +cumulus-primitives-timestamp = { git = "https://github.com/galacticcouncil/cumulus.git", rev = "460647cc2ec988ee04370c1cdd9fd518ed4868eb" } +cumulus-primitives-utility = { git = "https://github.com/galacticcouncil/cumulus.git", rev = "460647cc2ec988ee04370c1cdd9fd518ed4868eb" } +cumulus-test-relay-sproof-builder = { git = "https://github.com/galacticcouncil/cumulus.git", rev = "460647cc2ec988ee04370c1cdd9fd518ed4868eb" } +parachain-info = { git = "https://github.com/galacticcouncil/cumulus.git", rev = "460647cc2ec988ee04370c1cdd9fd518ed4868eb" } +cumulus-relay-chain-interface = { git = "https://github.com/galacticcouncil/cumulus.git", rev = "460647cc2ec988ee04370c1cdd9fd518ed4868eb" } +cumulus-relay-chain-inprocess-interface = { git = "https://github.com/galacticcouncil/cumulus.git", rev = "460647cc2ec988ee04370c1cdd9fd518ed4868eb" } + +# Cargo patch rules for all the PureStake/open-runtime-module-library crates +[patch."https://github.com/PureStake/open-runtime-module-library"] +orml-tokens = { git = "https://github.com/open-web3-stack/open-runtime-module-library", branch = "polkadot-v0.9.38" } +orml-xcm-support = { git = "https://github.com/open-web3-stack/open-runtime-module-library", branch = "polkadot-v0.9.38" } +orml-traits = { git = "https://github.com/open-web3-stack/open-runtime-module-library", branch = "polkadot-v0.9.38" } +orml-xtokens = { git = "https://github.com/open-web3-stack/open-runtime-module-library", branch = "polkadot-v0.9.38" } diff --git a/README.md b/README.md index 97cfdca8a..4a1a0a06f 100644 --- a/README.md +++ b/README.md @@ -68,26 +68,7 @@ Start local testnet with 4 relay chain validators and HydraDX as a parachain wit ``` cd ./rococo-local -zombienet --provider native config-zombienet.json -``` - -### Use testing runtime - -In the case of starting a testnet using the `polkadot-launch` tool, -we don't have an option to communicate to its internal commands that we would like to use the testing runtime. -To overcome this limitation, rename the binary so it starts with the `testing` prefix, e.g. `testing-hydradx`. -Such a binary always uses the testing runtime, even if the `--runtime testing` option is not specified. - -Start local testnet with testing runtime -``` -cd ./rococo-local -polkadot-launch testing-config.json -``` - -Start local testnet with testing runtime using Zombienet -``` -cd ./rococo-local -zombienet --provider native testing-config-zombienet.json +zombienet spawn config-zombienet.json ``` ### Interaction with the node diff --git a/integration-tests/Cargo.toml b/integration-tests/Cargo.toml index 5636df6f3..dff10c86f 100644 --- a/integration-tests/Cargo.toml +++ b/integration-tests/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "runtime-integration-tests" -version = "1.15.2" +version = "1.16.0" description = "Integration tests" authors = ["GalacticCouncil"] edition = "2021" @@ -59,6 +59,9 @@ orml-xtokens = { workspace = true } orml-xcm-support = { workspace = true } orml-unknown-tokens = { workspace = true } +# Evm +pallet-evm = { workspace = true } +fp-evm = { workspace = true } # Cumulus dependencies cumulus-pallet-aura-ext = { workspace = true } cumulus-pallet-parachain-system = { workspace = true } diff --git a/integration-tests/src/evm.rs b/integration-tests/src/evm.rs new file mode 100644 index 000000000..8525b3ef3 --- /dev/null +++ b/integration-tests/src/evm.rs @@ -0,0 +1,815 @@ +#![cfg(test)] + +use crate::{assert_balance, polkadot_test_net::*}; +use fp_evm::{Context, Transfer}; +use frame_support::{assert_ok, codec::Encode, dispatch::GetDispatchInfo, traits::Contains}; +use frame_system::RawOrigin; +use hex_literal::hex; +use hydradx_runtime::{ + evm::precompiles::{ + addr, + handle::EvmDataWriter, + multicurrency::{Action, MultiCurrencyPrecompile}, + Address, Bytes, EvmAddress, HydraDXPrecompiles, + }, + AssetRegistry, Balances, CallFilter, Currencies, RuntimeCall, RuntimeOrigin, Tokens, TransactionPause, EVM, +}; +use orml_traits::MultiCurrency; +use pallet_evm::*; +use pretty_assertions::assert_eq; +use sp_core::{blake2_256, H160, H256, U256}; +use sp_runtime::{traits::SignedExtension, FixedU128, Permill}; +use std::borrow::Cow; +use xcm_emulator::TestExt; + +const TREASURY_ACCOUNT_INIT_BALANCE: Balance = 1000 * UNITS; + +mod currency_precompile { + use super::*; + use pretty_assertions::assert_eq; + + type AllHydraDXPrecompile = HydraDXPrecompiles; + type CurrencyPrecompile = MultiCurrencyPrecompile; + + #[test] + fn all_hydra_precompile_should_match_native_asset_address() { + TestNet::reset(); + + Hydra::execute_with(|| { + //Arrange + let data = EvmDataWriter::new_with_selector(Action::Name).build(); + + let mut handle = MockHandle { + input: data, + context: Context { + address: evm_address(), + caller: native_asset_ethereum_address(), + apparent_value: U256::from(0), + }, + core_address: native_asset_ethereum_address(), + is_static: true, + }; + + //Act + let result = AllHydraDXPrecompile::new().execute(&mut handle); + + //Assert + assert!(result.is_some()); + let output = EvmDataWriter::new().write(Bytes::from("HDX".as_bytes())).build(); + + assert_eq!( + result, + Some(Ok(PrecompileOutput { + exit_status: ExitSucceed::Returned, + output + })) + ); + }); + } + + #[test] + fn all_hydra_precompile_should_match_asset_address_with_max_asset_value() { + TestNet::reset(); + + Hydra::execute_with(|| { + //Arrange + let data = EvmDataWriter::new_with_selector(Action::Name).build(); + + let mut handle = MockHandle { + input: data, + context: Context { + address: evm_address(), + caller: native_asset_ethereum_address(), + apparent_value: U256::from(0), + }, + core_address: H160::from(hex!("00000000000000000000000000000001ffffffff")), + is_static: true, + }; + + //Act + let result = AllHydraDXPrecompile::new().execute(&mut handle); + + //Assert + assert!(result.is_some()); + assert_eq!( + result, + Some(Err(PrecompileFailure::Error { + exit_status: ExitError::Other("Non-existing asset.".into()), + })) + ); + }); + } + + #[test] + fn precompile_for_currency_name_should_work() { + TestNet::reset(); + + Hydra::execute_with(|| { + //Arrange + let data = EvmDataWriter::new_with_selector(Action::Name).build(); + + let mut handle = MockHandle { + input: data, + context: Context { + address: evm_address(), + caller: native_asset_ethereum_address(), + apparent_value: U256::from(0), + }, + core_address: native_asset_ethereum_address(), + is_static: true, + }; + + //Act + let result = CurrencyPrecompile::execute(&mut handle); + + //Assert + let output = EvmDataWriter::new().write(Bytes::from("HDX".as_bytes())).build(); + assert_eq!( + result, + Ok(PrecompileOutput { + exit_status: ExitSucceed::Returned, + output + }) + ); + }); + } + + #[test] + fn precompile_for_currency_symbol_should_work() { + TestNet::reset(); + + Hydra::execute_with(|| { + //Arrange + AssetRegistry::set_metadata(hydradx_runtime::RuntimeOrigin::root(), HDX, b"xHDX".to_vec(), 12u8).unwrap(); + + let data = EvmDataWriter::new_with_selector(Action::Symbol).build(); + + let mut handle = MockHandle { + input: data, + context: Context { + address: evm_address(), + caller: native_asset_ethereum_address(), + apparent_value: U256::from(0), + }, + core_address: native_asset_ethereum_address(), + is_static: true, + }; + + //Act + let result = CurrencyPrecompile::execute(&mut handle); + + //Assert + let output = EvmDataWriter::new().write(Bytes::from("xHDX".as_bytes())).build(); + assert_eq!( + result, + Ok(PrecompileOutput { + exit_status: ExitSucceed::Returned, + output + }) + ); + }); + } + + #[test] + fn precompile_for_currency_decimal_should_work() { + TestNet::reset(); + + Hydra::execute_with(|| { + //Arrange + AssetRegistry::set_metadata(hydradx_runtime::RuntimeOrigin::root(), HDX, b"xHDX".to_vec(), 12u8).unwrap(); + + let data = EvmDataWriter::new_with_selector(Action::Decimals).build(); + + let mut handle = MockHandle { + input: data, + context: Context { + address: evm_address(), + caller: native_asset_ethereum_address(), + apparent_value: U256::from(0), + }, + core_address: native_asset_ethereum_address(), + is_static: true, + }; + + //Act + let result = CurrencyPrecompile::execute(&mut handle); + + //Assert + + // 12 + let expected_output = hex! {" + 00000000000000000000000000000000 0000000000000000000000000000000C + "}; + + assert_eq!( + result, + Ok(PrecompileOutput { + exit_status: ExitSucceed::Returned, + output: expected_output.to_vec() + }) + ); + }); + } + + #[test] + fn precompile_for_total_supply_should_work() { + TestNet::reset(); + + Hydra::execute_with(|| { + //Arrange + let data = EvmDataWriter::new_with_selector(Action::TotalSupply).build(); + + let mut handle = MockHandle { + input: data, + context: Context { + address: evm_address(), + caller: native_asset_ethereum_address(), + apparent_value: U256::from(0), + }, + core_address: native_asset_ethereum_address(), + is_static: true, + }; + + //Act + let result = CurrencyPrecompile::execute(&mut handle); + + //Assert + + // 950330588000000000 + let expected_output = hex! {" + 00000000000000000000000000000000 00000000000000000D3040A27CED9800 + "}; + + assert_eq!( + result, + Ok(PrecompileOutput { + exit_status: ExitSucceed::Returned, + output: expected_output.to_vec() + }) + ); + }); + } + + #[test] + fn precompile_for_balance_of_should_work() { + TestNet::reset(); + + Hydra::execute_with(|| { + //Arrange + assert_ok!(hydradx_runtime::Currencies::update_balance( + hydradx_runtime::RuntimeOrigin::root(), + evm_account(), + HDX, + 100 * UNITS as i128, + )); + + let data = EvmDataWriter::new_with_selector(Action::BalanceOf) + .write(Address::from(evm_address())) + .build(); + + let mut handle = MockHandle { + input: data, + context: Context { + address: alice_evm_addr(), + caller: alice_evm_addr(), + apparent_value: U256::from(0), + }, + core_address: native_asset_ethereum_address(), + is_static: true, + }; + + //Act + let result = CurrencyPrecompile::execute(&mut handle); + + //Assert + + // 100 * UNITS + let expected_output = hex! {" + 00000000000000000000000000000000 000000000000000000005AF3107A4000 + "}; + + assert_eq!( + result, + Ok(PrecompileOutput { + exit_status: ExitSucceed::Returned, + output: expected_output.to_vec() + }) + ); + }); + } + + #[test] + fn precompile_for_transfer_should_work() { + TestNet::reset(); + + Hydra::execute_with(|| { + //Arrange + assert_ok!(hydradx_runtime::Currencies::update_balance( + hydradx_runtime::RuntimeOrigin::root(), + evm_account(), + HDX, + 100 * UNITS as i128, + )); + + let data = EvmDataWriter::new_with_selector(Action::Transfer) + .write(Address::from(evm_address2())) + .write(U256::from(86u128 * UNITS)) + .build(); + + let mut handle = MockHandle { + input: data, + context: Context { + address: evm_address(), + caller: evm_address(), + apparent_value: U256::from(0), + }, + core_address: native_asset_ethereum_address(), + is_static: false, + }; + + //Act + let result = CurrencyPrecompile::execute(&mut handle); + + //Assert + assert_eq!(result.unwrap().exit_status, ExitSucceed::Returned); + assert_balance!(evm_account2(), HDX, 86u128 * UNITS); + }); + } + + #[test] + fn precompile_for_currency_approve_allowance_should_fail_as_not_supported() { + TestNet::reset(); + + Hydra::execute_with(|| { + //Arrange + assert_ok!(hydradx_runtime::Currencies::update_balance( + hydradx_runtime::RuntimeOrigin::root(), + evm_account(), + HDX, + 100 * UNITS as i128, + )); + + let data = EvmDataWriter::new_with_selector(Action::Approve) + .write(Address::from(evm_address2())) + .write(U256::from(50u128 * UNITS)) + .build(); + + let mut handle = MockHandle { + input: data, + context: Context { + address: evm_address(), + caller: native_asset_ethereum_address(), + apparent_value: U256::from(0), + }, + core_address: native_asset_ethereum_address(), + is_static: true, + }; + + //Act + let result = CurrencyPrecompile::execute(&mut handle); + + //Assert + assert_eq!( + result, + Err(PrecompileFailure::Error { + exit_status: pallet_evm::ExitError::Other("not supported".into()) + }) + ); + }); + } + + #[test] + fn precompile_for_currency_allowance_should_fail_as_not_supported() { + TestNet::reset(); + + Hydra::execute_with(|| { + //Arrange + let data = EvmDataWriter::new_with_selector(Action::Allowance) + .write(Address::from(evm_address())) + .write(Address::from(evm_address2())) + .build(); + + let mut handle = MockHandle { + input: data, + context: Context { + address: evm_address(), + caller: native_asset_ethereum_address(), + apparent_value: U256::from(0), + }, + core_address: native_asset_ethereum_address(), + is_static: true, + }; + + //Act + let result = CurrencyPrecompile::execute(&mut handle); + + //Assert + assert_eq!( + result, + Err(PrecompileFailure::Error { + exit_status: pallet_evm::ExitError::Other("not supported".into()) + }) + ); + }); + } + + #[test] + fn precompile_for_transfer_from_should_fail_as_not_supported() { + TestNet::reset(); + + Hydra::execute_with(|| { + //Arrange + assert_ok!(hydradx_runtime::Currencies::update_balance( + hydradx_runtime::RuntimeOrigin::root(), + evm_account(), + HDX, + 100 * UNITS as i128, + )); + + let data = EvmDataWriter::new_with_selector(Action::TransferFrom) + .write(Address::from(evm_address())) + .write(Address::from(evm_address2())) + .write(U256::from(50u128 * UNITS)) + .build(); + + let mut handle = MockHandle { + input: data, + context: Context { + address: evm_address(), + caller: evm_address(), + apparent_value: U256::from(0), + }, + core_address: native_asset_ethereum_address(), + is_static: false, + }; + + //Act + let result = CurrencyPrecompile::execute(&mut handle); + + //Assert + assert_eq!( + result, + Err(PrecompileFailure::Error { + exit_status: pallet_evm::ExitError::Other("not supported".into()) + }) + ); + assert_balance!(evm_account2(), HDX, 0); + }); + } + + 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 fn alice_evm_addr() -> H160 { + //H160::from(hex_literal::hex!("1000000000000000000000000000000000000001")) + account_to_default_evm_address(&ALICE) + } +} + +#[test] +fn dispatch_should_work_with_remark() { + TestNet::reset(); + + Hydra::execute_with(|| { + //Arrange + let mut handle = create_dispatch_handle(hex!["0107081337"].to_vec()); + + //Act + let prec = HydraDXPrecompiles::::new(); + let result = prec.execute(&mut handle); + + //Assert + assert_eq!( + result.unwrap(), + Ok(PrecompileOutput { + exit_status: ExitSucceed::Stopped, + output: Default::default(), + }) + ) + }); +} + +#[test] +fn dispatch_should_work_with_transfer() { + TestNet::reset(); + + Hydra::execute_with(|| { + //Arrange + let data = hex!["4d0045544800d1820d45118d78d091e685490c674d7596e62d1f0000000000000000140000000f0000c16ff28623"] + .to_vec(); + let balance = Tokens::free_balance(WETH, &evm_account()); + + //Act + assert_ok!(EVM::call( + evm_signed_origin(evm_address()), + evm_address(), + DISPATCH_ADDR, + data, + U256::from(0), + 1000000, + gas_price(), + None, + Some(U256::zero()), + [].into() + )); + + //Assert + assert!(Tokens::free_balance(WETH, &evm_account()) < balance - 10u128.pow(16)); + }); +} + +#[test] +fn dispatch_transfer_should_not_work_with_insufficient_fees() { + TestNet::reset(); + + Hydra::execute_with(|| { + //Arrange + let data = hex!["4d0045544800d1820d45118d78d091e685490c674d7596e62d1f0000000000000000140000000f0000c16ff28623"] + .to_vec(); + let insufficient_gas_price = gas_price() - U256::one(); + + //Act + let call = EVM::call( + evm_signed_origin(evm_address()), + evm_address(), + DISPATCH_ADDR, + data, + U256::from(0), + 1000000, + insufficient_gas_price, + None, + Some(U256::zero()), + [].into(), + ); + + //Assert + call.expect_err("Expected GasPriceTooLow error"); + }); +} + +#[test] +fn dispatch_should_respect_call_filter() { + TestNet::reset(); + + Hydra::execute_with(|| { + //Arrange + let balance = Tokens::free_balance(WETH, &evm_account()); + let amount = 10u128.pow(16); + let gas_limit = 1000000; + let transfer_call = RuntimeCall::Tokens(orml_tokens::Call::transfer { + dest: ALICE.into(), + currency_id: WETH, + amount, + }); + assert!(CallFilter::contains(&transfer_call)); + assert_ok!(TransactionPause::pause_transaction( + RuntimeOrigin::root(), + b"Tokens".to_vec(), + b"transfer".to_vec() + )); + assert!(!CallFilter::contains(&transfer_call)); + + //Act + assert_ok!(EVM::call( + evm_signed_origin(evm_address()), + evm_address(), + DISPATCH_ADDR, + transfer_call.encode(), + U256::from(0), + gas_limit, + gas_price(), + None, + Some(U256::zero()), + [].into(), + )); + + //Assert + let new_balance = Tokens::free_balance(WETH, &evm_account()); + assert!(new_balance < balance, "fee wasn't charged"); + assert!(new_balance > balance - amount, "more than fee was taken from account"); + assert_eq!( + new_balance, + balance - (U256::from(gas_limit) * gas_price()).as_u128(), + "gas limit was not charged" + ); + assert_eq!( + HydraDXPrecompiles::::new() + .execute(&mut create_dispatch_handle(transfer_call.encode())) + .unwrap(), + Err(PrecompileFailure::Error { + exit_status: ExitError::Other(Cow::from("dispatch execution failed: CallFiltered")) + }) + ); + }); +} + +#[test] +fn compare_fee_between_evm_and_native_omnipool_calls() { + TestNet::reset(); + + Hydra::execute_with(|| { + //Set alice with as fee currency and fund it + assert_ok!(hydradx_runtime::MultiTransactionPayment::set_currency( + hydradx_runtime::RuntimeOrigin::signed(ALICE.into()), + WETH, + )); + assert_ok!(hydradx_runtime::Currencies::update_balance( + hydradx_runtime::RuntimeOrigin::root(), + ALICE.into(), + WETH, + 100 * UNITS as i128, + )); + + //Fund evm account with HDX to dispatch omnipool sell + assert_ok!(hydradx_runtime::Currencies::update_balance( + hydradx_runtime::RuntimeOrigin::root(), + evm_account(), + HDX, + 100 * UNITS as i128, + )); + + init_omnipool_with_oracle_for_block_10(); + let treasury_eth_balance = Tokens::free_balance(WETH, &Treasury::account_id()); + let alice_weth_balance = Tokens::free_balance(WETH, &AccountId::from(ALICE)); + + //Act + let omni_sell = + hydradx_runtime::RuntimeCall::Omnipool(pallet_omnipool::Call::::sell { + asset_in: HDX, + asset_out: DAI, + amount: UNITS, + min_buy_amount: 0, + }); + + let gas_limit = 1000000; + //Execute omnipool via EVM + assert_ok!(EVM::call( + evm_signed_origin(evm_address()), + evm_address(), + DISPATCH_ADDR, + omni_sell.encode(), + U256::from(0), + gas_limit, + gas_price(), + None, + Some(U256::zero()), + [].into(), + )); + + //Pre dispatch the native omnipool call - so withdrawring only the fees for the execution + let info = omni_sell.get_dispatch_info(); + let len: usize = 1; + assert_ok!( + pallet_transaction_payment::ChargeTransactionPayment::::from(0).pre_dispatch( + &AccountId::from(ALICE), + &omni_sell, + &info, + len, + ) + ); + + //Determine fees and compare + let alice_new_weth_balance = Tokens::free_balance(WETH, &AccountId::from(ALICE)); + let fee_weth_native = alice_weth_balance - alice_new_weth_balance; + + let new_treasury_eth_balance = Tokens::free_balance(WETH, &Treasury::account_id()); + let fee_weth_evm = new_treasury_eth_balance - treasury_eth_balance; + + let fee_difference = fee_weth_evm - fee_weth_native; + + let relative_fee_difference = FixedU128::from_rational(fee_difference, fee_weth_native); + let tolerated_fee_difference = FixedU128::from_rational(20, 100); + + // EVM fees should be higher + assert!(fee_difference > 0); + + // EVM fees should be not higher than 20% + assert!(relative_fee_difference < tolerated_fee_difference); + }) +} + +fn init_omnipool_with_oracle_for_block_10() { + init_omnipol(); + //do_trade_to_populate_oracle(DAI, HDX, UNITS); + set_relaychain_block_number(10); + //do_trade_to_populate_oracle(DAI, HDX, UNITS); +} + +pub fn init_omnipol() { + let native_price = FixedU128::from_float(0.5); + let stable_price = FixedU128::from_float(0.7); + let acc = hydradx_runtime::Omnipool::protocol_account(); + + assert_ok!(hydradx_runtime::Omnipool::set_tvl_cap(RuntimeOrigin::root(), u128::MAX)); + + let stable_amount: Balance = 5_000_000_000_000_000_000_000u128; + let native_amount: Balance = 5_000_000_000_000_000_000_000u128; + assert_ok!(Tokens::set_balance( + RawOrigin::Root.into(), + acc.clone(), + DAI, + stable_amount, + 0 + )); + assert_ok!(Currencies::update_balance( + hydradx_runtime::RuntimeOrigin::root(), + acc, + HDX, + native_amount as i128, + )); + + assert_ok!(hydradx_runtime::Omnipool::initialize_pool( + hydradx_runtime::RuntimeOrigin::root(), + stable_price, + native_price, + Permill::from_percent(60), + Permill::from_percent(60) + )); + + assert_ok!(Balances::set_balance( + RawOrigin::Root.into(), + hydradx_runtime::Treasury::account_id(), + TREASURY_ACCOUNT_INIT_BALANCE, + 0, + )); +} + +// TODO: test that we charge approximatelly same fee on evm as with extrinsics directly + +const DISPATCH_ADDR: H160 = addr(1025); + +fn gas_price() -> U256 { + U256::from(10_u128.pow(8)) +} + +fn create_dispatch_handle(data: Vec) -> MockHandle { + MockHandle { + input: data, + context: Context { + address: DISPATCH_ADDR, + caller: evm_address(), + apparent_value: U256::zero(), + }, + core_address: DISPATCH_ADDR, + is_static: true, + } +} + +pub fn native_asset_ethereum_address() -> H160 { + H160::from(hex!("0000000000000000000000000000000100000000")) +} + +pub struct MockHandle { + pub input: Vec, + pub context: Context, + pub core_address: H160, + pub is_static: bool, +} + +impl PrecompileHandle for MockHandle { + fn call( + &mut self, + _: H160, + _: Option, + _: Vec, + _: Option, + _: bool, + _: &Context, + ) -> (ExitReason, Vec) { + unimplemented!() + } + + fn record_cost(&mut self, _: u64) -> Result<(), ExitError> { + Ok(()) + } + + fn remaining_gas(&self) -> u64 { + unimplemented!() + } + + fn log(&mut self, _: H160, _: Vec, _: Vec) -> Result<(), ExitError> { + unimplemented!() + } + + fn code_address(&self) -> H160 { + self.core_address + } + + fn input(&self) -> &[u8] { + &self.input + } + + fn context(&self) -> &Context { + &self.context + } + + fn is_static(&self) -> bool { + self.is_static + } + + fn gas_limit(&self) -> Option { + None + } +} diff --git a/integration-tests/src/lib.rs b/integration-tests/src/lib.rs index d5772fb39..1dca8de52 100644 --- a/integration-tests/src/lib.rs +++ b/integration-tests/src/lib.rs @@ -8,6 +8,7 @@ mod dca; mod dust; mod dust_removal_whitelist; mod dynamic_fees; +mod evm; mod exchange_asset; mod non_native_fee; mod omnipool_init; diff --git a/integration-tests/src/polkadot_test_net.rs b/integration-tests/src/polkadot_test_net.rs index c7fe25598..009089706 100644 --- a/integration-tests/src/polkadot_test_net.rs +++ b/integration-tests/src/polkadot_test_net.rs @@ -9,15 +9,21 @@ use frame_support::{ traits::GenesisBuild, weights::Weight, }; -pub use hydradx_runtime::{AccountId, Currencies, NativeExistentialDeposit, Treasury, VestingPalletId}; +pub use hydradx_runtime::{ + evm::ExtendedAddressMapping, AccountId, Currencies, NativeExistentialDeposit, Treasury, VestingPalletId, +}; use pallet_transaction_multi_payment::Price; pub use primitives::{constants::chain::CORE_ASSET_ID, AssetId, Balance, Moment}; use cumulus_primitives_core::ParaId; use cumulus_test_relay_sproof_builder::RelayStateSproofBuilder; -//use cumulus_primitives_core::relay_chain::AccountId; +use hex_literal::hex; +use hydradx_runtime::evm::WETH_ASSET_LOCATION; +use hydradx_runtime::RuntimeOrigin; +use pallet_evm::AddressMapping; use polkadot_primitives::v2::{BlockNumber, MAX_CODE_SIZE, MAX_POV_SIZE}; use polkadot_runtime_parachains::configuration::HostConfiguration; +use sp_core::H160; use xcm_emulator::{decl_test_network, decl_test_parachain, decl_test_relay_chain}; pub const ALICE: [u8; 32] = [4u8; 32]; @@ -26,6 +32,29 @@ pub const CHARLIE: [u8; 32] = [6u8; 32]; pub const DAVE: [u8; 32] = [7u8; 32]; pub const UNKNOWN: [u8; 32] = [8u8; 32]; +pub fn evm_address() -> H160 { + hex!["222222ff7Be76052e023Ec1a306fCca8F9659D80"].into() +} +pub fn evm_account() -> AccountId { + ExtendedAddressMapping::into_account_id(evm_address()) +} + +pub fn evm_address2() -> H160 { + hex!["222222ff7Be76052e023Ec1a306fCca8F9659D81"].into() +} +pub fn evm_account2() -> AccountId { + ExtendedAddressMapping::into_account_id(evm_address2()) +} +pub fn evm_signed_origin(address: H160) -> RuntimeOrigin { + // account has to be truncated to spoof it as an origin + let mut account_truncated: [u8; 32] = [0; 32]; + account_truncated[..address.clone().as_bytes().len()].copy_from_slice(address.as_bytes()); + RuntimeOrigin::signed(AccountId::from(account_truncated)) +} +pub fn to_ether(b: Balance) -> Balance { + b * 10_u128.pow(18) +} + pub const UNITS: Balance = 1_000_000_000_000; pub const ACALA_PARA_ID: u32 = 2_000; @@ -53,6 +82,7 @@ pub const DOT: AssetId = 3; pub const ETH: AssetId = 4; pub const BTC: AssetId = 5; pub const ACA: AssetId = 6; +pub const WETH: AssetId = 20; pub const PEPE: AssetId = 420; pub const NOW: Moment = 1689844300000; // unix time in milliseconds @@ -230,6 +260,7 @@ pub fn hydra_ext() -> sp_io::TestExternalities { (b"ETH".to_vec(), 1_000u128, Some(ETH)), (b"BTC".to_vec(), 1_000u128, Some(BTC)), (b"ACA".to_vec(), 1_000u128, Some(ACA)), + (b"WETH".to_vec(), 1_000u128, Some(WETH)), (b"PEPE".to_vec(), 1_000u128, Some(PEPE)), // workaround for next_asset_id() to return correct values (b"DUMMY".to_vec(), 1_000u128, None), @@ -260,6 +291,7 @@ pub fn hydra_ext() -> sp_io::TestExternalities { (AccountId::from(CHARLIE), LRNA, CHARLIE_INITIAL_LRNA_BALANCE), (AccountId::from(DAVE), LRNA, 1_000 * UNITS), (AccountId::from(DAVE), DAI, 1_000_000_000 * UNITS), + (evm_account(), WETH, to_ether(1_000)), (omnipool_account.clone(), DAI, stable_amount), (omnipool_account.clone(), ETH, eth_amount), (omnipool_account.clone(), BTC, btc_amount), @@ -283,6 +315,7 @@ pub fn hydra_ext() -> sp_io::TestExternalities { (DAI, Price::from(1)), (ACA, Price::from(1)), (BTC, Price::from_inner(134_000_000)), + (WETH, Price::from_inner(3_666_754_716_981_130_000)), ], account_currencies: vec![], } @@ -310,6 +343,7 @@ pub fn hydra_ext() -> sp_io::TestExternalities { Timestamp::set_timestamp(NOW); // Make sure the prices are up-to-date. MultiTransactionPayment::on_initialize(1); + hydradx_runtime::AssetRegistry::set_location(RuntimeOrigin::root(), WETH, WETH_ASSET_LOCATION).unwrap(); }); ext } @@ -368,7 +402,7 @@ pub fn expect_hydra_events(e: Vec) { pub fn set_relaychain_block_number(number: BlockNumber) { use frame_support::traits::OnInitialize; - use hydradx_runtime::{ParachainSystem, RuntimeOrigin}; + use hydradx_runtime::ParachainSystem; // We need to set block number this way as well because tarpaulin code coverage tool does not like the way // how we set the block number with `cumulus-test-relay-sproof-builder` package @@ -445,11 +479,11 @@ pub fn apply_blocks_from_file(pallet_whitelist: Vec<&str>) { for block in blocks.iter() { for tx in block.extrinsics() { - let call = &tx.function; + let call = &tx.0.function; let call_p = call.get_call_metadata().pallet_name; if pallet_whitelist.contains(&call_p) { - let acc = &tx.signature.as_ref().unwrap().0; + let acc = &tx.0.signature.as_ref().unwrap().0; assert_ok!(call .clone() .dispatch(hydradx_runtime::RuntimeOrigin::signed(acc.clone()))); diff --git a/node/Cargo.toml b/node/Cargo.toml index ef67a465f..6b6c69c22 100644 --- a/node/Cargo.toml +++ b/node/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "hydradx" -version = "10.0.1" +version = "11.0.0" description = "HydraDX node" authors = ["GalacticCouncil"] edition = "2021" @@ -26,6 +26,7 @@ serde = { version = "1.0.136", features = ["derive"] } serde_json = "1.0.85" clap = { version = "4.1.8", features = [ "derive" ] } futures = "0.3.21" +async-trait = "0.1" # local dependencies hydradx-runtime = { workspace = true } @@ -39,6 +40,7 @@ sc-basic-authorship = { workspace = true } sc-chain-spec = { workspace = true } sc-cli = { workspace = true } sc-client-api = { workspace = true } +sc-client-db = { workspace = true } sc-consensus = { workspace = true } sc-consensus-aura = { workspace = true } sc-executor = { workspace = true } @@ -96,6 +98,15 @@ polkadot-parachain = { workspace = true } polkadot-primitives = { workspace = true } polkadot-service = { workspace = true } +# Frontier +fc-consensus = { workspace = true } +fc-db = { workspace = true } +fc-mapping-sync = { workspace = true } +fc-rpc = { workspace = true } +fc-rpc-core = { workspace = true } +fp-rpc = { workspace = true } +fp-storage = { workspace = true } + [features] default = [ "frame-benchmarking-cli", @@ -113,4 +124,3 @@ try-runtime = [ "hydradx-runtime/try-runtime", "try-runtime-cli/try-runtime", ] - diff --git a/node/src/chain_spec/mod.rs b/node/src/chain_spec/mod.rs index da280c343..1decc1b67 100644 --- a/node/src/chain_spec/mod.rs +++ b/node/src/chain_spec/mod.rs @@ -182,6 +182,11 @@ pub fn parachain_genesis( duster, omnipool_warehouse_lm: Default::default(), omnipool_liquidity_mining: Default::default(), + evm_chain_id: hydradx_runtime::EVMChainIdConfig { + chain_id: 222_222u32.into(), + }, + ethereum: Default::default(), + evm: Default::default(), } } diff --git a/node/src/cli.rs b/node/src/cli.rs index fd0481bac..685c79c78 100644 --- a/node/src/cli.rs +++ b/node/src/cli.rs @@ -35,6 +35,9 @@ pub struct Cli { /// Relaychain arguments #[clap(raw = true)] pub relaychain_args: Vec, + + #[clap(flatten)] + pub ethereum_config: crate::service::evm::EthereumConfig, } #[derive(Debug)] diff --git a/node/src/command.rs b/node/src/command.rs index 53ae913d8..b55744116 100644 --- a/node/src/command.rs +++ b/node/src/command.rs @@ -16,7 +16,7 @@ // limitations under the License. use crate::cli::{Cli, RelayChainCli, Subcommand}; -use crate::service::{new_partial, HydraDXExecutorDispatch}; +use crate::service::new_partial; use crate::{chain_spec, service}; use codec::Encode; @@ -143,28 +143,28 @@ pub fn run() -> sc_cli::Result<()> { Some(Subcommand::CheckBlock(cmd)) => { let runner = cli.create_runner(cmd)?; runner.async_run(|config| { - let partials = new_partial::(&config)?; + let partials = new_partial::(&config)?; Ok((cmd.run(partials.client, partials.import_queue), partials.task_manager)) }) } Some(Subcommand::ExportBlocks(cmd)) => { let runner = cli.create_runner(cmd)?; runner.async_run(|config| { - let partials = new_partial::(&config)?; + let partials = new_partial::(&config)?; Ok((cmd.run(partials.client, config.database), partials.task_manager)) }) } Some(Subcommand::ExportState(cmd)) => { let runner = cli.create_runner(cmd)?; runner.async_run(|config| { - let partials = new_partial::(&config)?; + let partials = new_partial::(&config)?; Ok((cmd.run(partials.client, config.chain_spec), partials.task_manager)) }) } Some(Subcommand::ImportBlocks(cmd)) => { let runner = cli.create_runner(cmd)?; runner.async_run(|config| { - let partials = new_partial::(&config)?; + let partials = new_partial::(&config)?; Ok((cmd.run(partials.client, partials.import_queue), partials.task_manager)) }) } @@ -188,7 +188,7 @@ pub fn run() -> sc_cli::Result<()> { Some(Subcommand::Revert(cmd)) => { let runner = cli.create_runner(cmd)?; runner.async_run(|config| { - let partials = new_partial::(&config)?; + let partials = new_partial::(&config)?; Ok((cmd.run(partials.client, partials.backend, None), partials.task_manager)) }) } @@ -206,18 +206,14 @@ pub fn run() -> sc_cli::Result<()> { } } BenchmarkCmd::Block(cmd) => runner.sync_run(|config| { - let partials = crate::service::new_partial::< - hydradx_runtime::RuntimeApi, - service::HydraDXExecutorDispatch, - >(&config)?; + let partials = crate::service::new_partial::(&config)?; cmd.run(partials.client) }), #[cfg(not(feature = "runtime-benchmarks"))] BenchmarkCmd::Storage(_) => Err("Storage benchmarking can be enabled with `--features runtime-benchmarks`.".into()), #[cfg(feature = "runtime-benchmarks")] BenchmarkCmd::Storage(cmd) => runner.sync_run(|config| { - let partials = - new_partial::(&config)?; + let partials = new_partial::(&config)?; let db = partials.backend.expose_db(); let storage = partials.backend.expose_storage(); @@ -345,7 +341,7 @@ pub fn run() -> sc_cli::Result<()> { if config.role.is_authority() { "yes" } else { "no" } ); - crate::service::start_node(config, polkadot_config, collator_options, id) + crate::service::start_node(config, polkadot_config, cli.ethereum_config, collator_options, id) .await .map(|r| r.1) .map_err(Into::into) diff --git a/node/src/rpc.rs b/node/src/rpc.rs index c525fabeb..5a1f4df36 100644 --- a/node/src/rpc.rs +++ b/node/src/rpc.rs @@ -1,19 +1,49 @@ -//! 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)] +// : $$\ $$\ $$\ $$$$$$$\ $$\ $$\ +// !YJJ^ $$ | $$ | $$ | $$ __$$\ $$ | $$ | +// 7B5. ~B5^ $$ | $$ |$$\ $$\ $$$$$$$ | $$$$$$\ $$$$$$\ $$ | $$ |\$$\ $$ | +// .?B@G ~@@P~ $$$$$$$$ |$$ | $$ |$$ __$$ |$$ __$$\ \____$$\ $$ | $$ | \$$$$ / +// :?#@@@Y .&@@@P!. $$ __$$ |$$ | $$ |$$ / $$ |$$ | \__|$$$$$$$ |$$ | $$ | $$ $$< +// ^?J^7P&@@! .5@@#Y~!J!. $$ | $$ |$$ | $$ |$$ | $$ |$$ | $$ __$$ |$$ | $$ |$$ /\$$\ +// ^JJ!. :!J5^ ?5?^ ^?Y7. $$ | $$ |\$$$$$$$ |\$$$$$$$ |$$ | \$$$$$$$ |$$$$$$$ |$$ / $$ | +// ~PP: 7#B5!. :?P#G: 7G?. \__| \__| \____$$ | \_______|\__| \_______|\_______/ \__| \__| +// .!P@G 7@@@#Y^ .!P@@@#. ~@&J: $$\ $$ | +// !&@@J :&@@@@P. !&@@@@5 #@@P. \$$$$$$ | +// :J##: Y@@&P! :JB@@&~ ?@G! \______/ +// .?P!.?GY7: .. . ^?PP^:JP~ +// .7Y7. .!YGP^ ?BP?^ ^JJ^ This file is part of https://github.com/galacticcouncil/HydraDX-node +// .!Y7Y#@@#: ?@@@G?JJ^ Built with <3 for decentralisation. +// !G@@@Y .&@@&J: +// ^5@#. 7@#?. Copyright (C) 2021-2023 Intergalactic, Limited (GIB). +// :5P^.?G7. SPDX-License-Identifier: Apache-2.0 +// :?Y! Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// http://www.apache.org/licenses/LICENSE-2.0 use std::sync::Arc; +use fc_db::Backend as FrontierBackend; +pub use fc_rpc::{ + EthBlockDataCacheTask, OverrideHandle, RuntimeApiStorageOverride, SchemaV1Override, SchemaV2Override, + SchemaV3Override, StorageOverride, +}; +pub use fc_rpc_core::types::{FeeHistoryCache, FeeHistoryCacheLimit, FilterPool}; +use fp_rpc::{ConvertTransaction, ConvertTransactionRuntimeApi, EthereumRuntimeRPCApi}; use hydradx_runtime::{opaque::Block, AccountId, Balance, Index}; -pub use sc_rpc::SubscriptionTaskExecutor; +use jsonrpsee::RpcModule; +use sc_client_api::{ + backend::{Backend, StateBackend, StorageProvider}, + client::BlockchainEvents, +}; +use sc_network::NetworkService; +use sc_rpc::SubscriptionTaskExecutor; pub use sc_rpc_api::DenyUnsafe; +use sc_transaction_pool::{ChainApi, Pool}; use sc_transaction_pool_api::TransactionPool; -use sp_api::ProvideRuntimeApi; -use sp_block_builder::BlockBuilder; +use sp_api::{CallApiAt, ProvideRuntimeApi}; +use sp_block_builder::BlockBuilder as BlockBuilderApi; use sp_blockchain::{Error as BlockChainError, HeaderBackend, HeaderMetadata}; +use sp_core::H256; +use sp_runtime::traits::{BlakeTwo256, Block as BlockT}; /// Full client dependencies. pub struct FullDeps { @@ -25,6 +55,41 @@ pub struct FullDeps { pub deny_unsafe: DenyUnsafe, } +/// Extra dependencies for Ethereum compatibility. +pub struct Deps { + /// 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>, + /// 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: FilterPool, + /// 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, +} + /// RPC Extension Builder pub type RpcExtension = jsonrpsee::RpcModule<()>; @@ -36,7 +101,7 @@ where C: Send + Sync + 'static, C::Api: substrate_frame_rpc_system::AccountNonceApi, C::Api: pallet_transaction_payment_rpc::TransactionPaymentRuntimeApi, - C::Api: BlockBuilder, + C::Api: BlockBuilderApi, P: TransactionPool + Sync + Send + 'static, { use pallet_transaction_payment_rpc::{TransactionPayment, TransactionPaymentApiServer}; @@ -54,3 +119,129 @@ where Ok(module) } + +/// Instantiate Ethereum-compatible RPC extensions. +pub fn create( + mut io: RpcModule<()>, + deps: Deps, + subscription_task_executor: SubscriptionTaskExecutor, +) -> Result, Box> +where + B: BlockT, + C: ProvideRuntimeApi, + C::Api: BlockBuilderApi + EthereumRuntimeRPCApi + ConvertTransactionRuntimeApi, + C: BlockchainEvents + 'static, + C: HeaderBackend + HeaderMetadata + StorageProvider, + C: CallApiAt, + BE: Backend + 'static, + BE::State: StateBackend, + P: TransactionPool + 'static, + A: ChainApi + 'static, + CT: ConvertTransaction<::Extrinsic> + Send + Sync + 'static, +{ + use fc_rpc::{ + Eth, EthApiServer, EthDevSigner, EthFilter, EthFilterApiServer, EthPubSub, EthPubSubApiServer, EthSigner, Net, + NetApiServer, Web3, Web3ApiServer, + }; + + let Deps { + client, + pool, + graph, + converter, + is_authority, + enable_dev_signer, + network, + frontier_backend, + overrides, + block_data_cache, + filter_pool, + max_past_logs, + fee_history_cache, + fee_history_cache_limit, + execute_gas_limit_multiplier, + } = 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, + converter, + network.clone(), + vec![], + overrides.clone(), + frontier_backend.clone(), + is_authority, + block_data_cache.clone(), + fee_history_cache, + fee_history_cache_limit, + execute_gas_limit_multiplier, + ) + .into_rpc(), + )?; + + io.merge( + EthFilter::new( + client.clone(), + frontier_backend, + filter_pool, + 500_usize, // max stored filters + max_past_logs, + block_data_cache, + ) + .into_rpc(), + )?; + + io.merge( + EthPubSub::new( + pool, + client.clone(), + network.clone(), + subscription_task_executor, + overrides, + ) + .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).into_rpc())?; + + Ok(io) +} + +impl Clone for Deps { + fn clone(&self) -> Self { + Self { + client: self.client.clone(), + pool: self.pool.clone(), + graph: self.graph.clone(), + converter: self.converter.clone(), + is_authority: self.is_authority, + enable_dev_signer: self.enable_dev_signer, + network: self.network.clone(), + frontier_backend: self.frontier_backend.clone(), + overrides: self.overrides.clone(), + block_data_cache: self.block_data_cache.clone(), + filter_pool: self.filter_pool.clone(), + max_past_logs: self.max_past_logs, + fee_history_cache: self.fee_history_cache.clone(), + fee_history_cache_limit: self.fee_history_cache_limit, + execute_gas_limit_multiplier: self.execute_gas_limit_multiplier, + } + } +} diff --git a/node/src/service.rs b/node/src/service.rs index 0273cbb26..eed8991e5 100644 --- a/node/src/service.rs +++ b/node/src/service.rs @@ -30,20 +30,31 @@ use cumulus_primitives_core::{CollectCollationInfo, ParaId}; use cumulus_relay_chain_inprocess_interface::build_inprocess_relay_chain; use cumulus_relay_chain_interface::{RelayChainInterface, RelayChainResult}; use cumulus_relay_chain_minimal_node::build_minimal_relay_chain_node; -use jsonrpsee::RpcModule; +use fc_db::Backend as FrontierBackend; +use fc_rpc::{EthBlockDataCacheTask, OverrideHandle}; +use fc_rpc_core::types::{FeeHistoryCache, FilterPool}; +use fp_rpc::{ConvertTransactionRuntimeApi, EthereumRuntimeRPCApi}; use polkadot_service::CollatorPair; use primitives::{AccountId, Balance, Block, Index}; use sc_consensus::ImportQueue; use sc_executor::{NativeElseWasmExecutor, NativeExecutionDispatch, NativeVersion}; use sc_network::NetworkService; use sc_network_common::service::NetworkBlock; +use sc_rpc::SubscriptionTaskExecutor; +use sc_rpc_api::DenyUnsafe; use sc_service::{Configuration, PartialComponents, TFullBackend, TFullClient, TaskManager}; use sc_telemetry::{Telemetry, TelemetryHandle, TelemetryWorker, TelemetryWorkerHandle}; use sp_api::ConstructRuntimeApi; use sp_keystore::SyncCryptoStorePtr; -use std::{sync::Arc, time::Duration}; +use std::{ + collections::BTreeMap, + sync::{Arc, Mutex}, + time::Duration, +}; use substrate_prometheus_endpoint::Registry; -type Hash = sp_core::H256; + +pub(crate) mod evm; +use crate::rpc; // native executor instance. pub struct HydraDXExecutorDispatch; @@ -60,22 +71,21 @@ impl NativeExecutionDispatch for HydraDXExecutorDispatch { } pub type FullBackend = TFullBackend; -pub type FullClient = - TFullClient>; +pub type FullClient = TFullClient>; -type ParachainBlockImport = - TParachainBlockImport>, FullBackend>; +pub type ParachainBlockImport = TParachainBlockImport>, FullBackend>; /// Build the import queue for the parachain runtime. -pub fn parachain_build_import_queue( - client: Arc>, +pub fn parachain_build_import_queue( + client: Arc>, backend: Arc, config: &Configuration, telemetry: Option, task_manager: &TaskManager, -) -> Result>, sc_service::Error> + frontier_backend: Arc>, +) -> Result>, sc_service::Error> where - RuntimeApi: ConstructRuntimeApi> + Send + Sync + 'static, + RuntimeApi: ConstructRuntimeApi> + Send + Sync + 'static, RuntimeApi::RuntimeApi: sp_transaction_pool::runtime_api::TaggedTransactionQueue // + sp_api::ApiExt + sp_api::ApiExt> @@ -85,15 +95,20 @@ where + sp_api::Metadata + sp_offchain::OffchainWorkerApi + sp_session::SessionKeys - + sp_consensus_aura::AuraApi, - Executor: NativeExecutionDispatch + 'static, + + sp_consensus_aura::AuraApi + + EthereumRuntimeRPCApi, { let slot_duration = cumulus_client_consensus_aura::slot_duration(&*client)?; + let block_import = evm::BlockImport::new( + ParachainBlockImport::new(client.clone(), backend.clone()), + client.clone(), + frontier_backend, + ); cumulus_client_consensus_aura::import_queue::( cumulus_client_consensus_aura::ImportQueueParams { - block_import: ParachainBlockImport::new(client.clone(), backend.clone()), - client: client.clone(), + block_import, + client, create_inherent_data_providers: move |_, _| async move { let timestamp = sp_timestamp::InherentDataProvider::from_system_time(); @@ -112,21 +127,27 @@ where .map_err(Into::into) } -pub fn new_partial( +pub fn new_partial( config: &Configuration, ) -> Result< PartialComponents< - TFullClient>, - TFullBackend, + FullClient, + FullBackend, (), - sc_consensus::DefaultImportQueue>, - sc_transaction_pool::FullPool>, - (Option, Option), + sc_consensus::DefaultImportQueue>, + sc_transaction_pool::FullPool>, + ( + Option, + Option, + Arc>, + FilterPool, + FeeHistoryCache, + ), >, sc_service::Error, > where - RuntimeApi: ConstructRuntimeApi> + Send + Sync + 'static, + RuntimeApi: ConstructRuntimeApi> + Send + Sync + 'static, RuntimeApi::RuntimeApi: sp_transaction_pool::runtime_api::TaggedTransactionQueue // + sp_api::ApiExt + sp_api::ApiExt> @@ -136,8 +157,8 @@ where + sp_api::Metadata + sp_offchain::OffchainWorkerApi + sp_session::SessionKeys - + sp_consensus_aura::AuraApi, - Executor: NativeExecutionDispatch + 'static, + + sp_consensus_aura::AuraApi + + EthereumRuntimeRPCApi, { let telemetry = config .telemetry_endpoints @@ -150,7 +171,7 @@ where }) .transpose()?; - let executor = NativeElseWasmExecutor::::new( + let executor = NativeElseWasmExecutor::::new( config.wasm_method, config.default_heap_pages, config.max_runtime_instances, @@ -158,7 +179,7 @@ where ); let (client, backend, keystore_container, task_manager) = - sc_service::new_full_parts::>( + sc_service::new_full_parts::>( config, telemetry.as_ref().map(|(_, telemetry)| telemetry.handle()), executor, @@ -182,14 +203,24 @@ where client.clone(), ); - let import_queue = parachain_build_import_queue::( + let frontier_backend = Arc::new(FrontierBackend::open( + Arc::clone(&client), + &config.database, + &evm::db_config_dir(config), + )?); + + let import_queue = parachain_build_import_queue::( client.clone(), backend.clone(), config, telemetry.as_ref().map(|telemetry| telemetry.handle()), &task_manager, + frontier_backend.clone(), )?; + let filter_pool: FilterPool = Arc::new(Mutex::new(BTreeMap::new())); + let fee_history_cache: FeeHistoryCache = Arc::new(Mutex::new(BTreeMap::new())); + Ok(PartialComponents { client, backend, @@ -198,7 +229,13 @@ where keystore_container, transaction_pool, select_chain: (), - other: (telemetry, telemetry_worker_handle), + other: ( + telemetry, + telemetry_worker_handle, + frontier_backend, + filter_pool, + fee_history_cache, + ), }) } @@ -228,17 +265,17 @@ async fn build_relay_chain_interface( /// Start a node with the given parachain `Configuration` and relay chain `Configuration`. /// /// This is the actual implementation that is abstract over the executor and the runtime api. -async fn start_node_impl( +async fn start_node_impl( parachain_config: Configuration, polkadot_config: Configuration, + ethereum_config: evm::EthereumConfig, collator_options: CollatorOptions, para_id: ParaId, - _rpc_ext_builder: RpcBuilder, + rpc_ext_builder: RpcExtBuilder, build_consensus: ConsensusBuilder, -) -> sc_service::error::Result<(Arc>, TaskManager)> +) -> sc_service::error::Result<(Arc>, TaskManager)> where - RpcBuilder: Fn(Arc>) -> Result, sc_service::Error> + Send + 'static, - RuntimeApi: ConstructRuntimeApi> + Send + Sync + 'static, + RuntimeApi: ConstructRuntimeApi> + Send + Sync + 'static, RuntimeApi::RuntimeApi: sp_transaction_pool::runtime_api::TaggedTransactionQueue // + sp_api::ApiExt + sp_api::ApiExt> @@ -249,25 +286,41 @@ where + sp_offchain::OffchainWorkerApi + sp_session::SessionKeys + CollectCollationInfo - + sp_consensus_aura::AuraApi, + + sp_consensus_aura::AuraApi + + cumulus_primitives_core::CollectCollationInfo + + EthereumRuntimeRPCApi + + ConvertTransactionRuntimeApi, Executor: NativeExecutionDispatch + 'static, + RpcExtBuilder: Fn( + Arc>, + Arc>>, + DenyUnsafe, + SubscriptionTaskExecutor, + Arc>, + Arc>, + FilterPool, + FeeHistoryCache, + Arc>, + Arc>, + ) -> Result + + 'static, ConsensusBuilder: FnOnce( - Arc>, - ParachainBlockImport, + Arc>, + ParachainBlockImport, Option<&Registry>, Option, &TaskManager, Arc, - Arc>>, - Arc>, + Arc>>, + Arc>, SyncCryptoStorePtr, bool, ) -> Result>, sc_service::Error>, { let parachain_config = prepare_node_config(parachain_config); - let params = new_partial::(¶chain_config)?; - let (mut telemetry, telemetry_worker_handle) = params.other; + let params = new_partial::(¶chain_config)?; + let (mut telemetry, telemetry_worker_handle, frontier_backend, filter_pool, fee_history_cache) = params.other; let client = params.client.clone(); let backend = params.backend.clone(); let mut task_manager = params.task_manager; @@ -300,18 +353,36 @@ where warp_sync: None, })?; - let rpc_builder = { - let client = client.clone(); - let transaction_pool = transaction_pool.clone(); + let rpc_client = client.clone(); + let overrides = evm::overrides_handle(client.clone()); + let block_data_cache = Arc::new(fc_rpc::EthBlockDataCacheTask::new( + task_manager.spawn_handle(), + overrides.clone(), + ethereum_config.eth_log_block_cache, + ethereum_config.eth_statuses_cache, + prometheus_registry.clone(), + )); - move |deny_unsafe, _| { - let deps = crate::rpc::FullDeps { - client: client.clone(), - pool: transaction_pool.clone(), - deny_unsafe, - }; - - crate::rpc::create_full(deps).map_err(Into::into) + let rpc_builder = { + let network = network.clone(); + let pool = transaction_pool.clone(); + let frontier_backend = frontier_backend.clone(); + let fee_history_cache = fee_history_cache.clone(); + let filter_pool = filter_pool.clone(); + let overrides = overrides.clone(); + move |deny, subscription_task_executor| { + rpc_ext_builder( + rpc_client.clone(), + pool.clone(), + deny, + subscription_task_executor, + network.clone(), + frontier_backend.clone(), + filter_pool.clone(), + fee_history_cache.clone(), + overrides.clone(), + block_data_cache.clone(), + ) } }; @@ -338,6 +409,17 @@ where telemetry: telemetry.as_mut(), })?; + evm::spawn_frontier_tasks::( + &task_manager, + client.clone(), + backend.clone(), + frontier_backend.clone(), + filter_pool.clone(), + overrides, + fee_history_cache.clone(), + ethereum_config.fee_history_limit, + ); + let announce_block = { let network = network.clone(); Arc::new(move |hash, data| network.announce_block(hash, data)) @@ -400,18 +482,54 @@ where pub async fn start_node( parachain_config: Configuration, polkadot_config: Configuration, + ethereum_config: evm::EthereumConfig, collator_options: CollatorOptions, para_id: ParaId, -) -> sc_service::error::Result<( - Arc>, - TaskManager, -)> { - start_node_impl::<_, hydradx_runtime::RuntimeApi, HydraDXExecutorDispatch, _>( +) -> sc_service::error::Result<(Arc>, TaskManager)> { + let is_authority = parachain_config.role.is_authority(); + + start_node_impl::( parachain_config, polkadot_config, + ethereum_config, collator_options, para_id, - |_| Ok(RpcModule::new(())), + move |client, + pool, + deny_unsafe, + subscription_task_executor, + network, + frontier_backend, + filter_pool, + fee_history_cache, + overrides, + block_data_cache| { + let deps = rpc::FullDeps { + client: client.clone(), + pool: pool.clone(), + deny_unsafe, + }; + let module = rpc::create_full(deps)?; + let eth_deps = rpc::Deps { + client, + pool: pool.clone(), + graph: pool.pool().clone(), + converter: Some(hydradx_runtime::TransactionConverter), + is_authority, + enable_dev_signer: ethereum_config.enable_dev_signer, + network, + frontier_backend, + overrides, + block_data_cache, + filter_pool, + max_past_logs: ethereum_config.max_past_logs, + fee_history_cache, + fee_history_cache_limit: ethereum_config.fee_history_limit, + execute_gas_limit_multiplier: ethereum_config.execute_gas_limit_multiplier, + }; + let module = rpc::create(module, eth_deps, subscription_task_executor)?; + Ok(module) + }, |client, block_import, prometheus_registry, diff --git a/node/src/service/evm.rs b/node/src/service/evm.rs new file mode 100644 index 000000000..321c90221 --- /dev/null +++ b/node/src/service/evm.rs @@ -0,0 +1,220 @@ +// : $$\ $$\ $$\ $$$$$$$\ $$\ $$\ +// !YJJ^ $$ | $$ | $$ | $$ __$$\ $$ | $$ | +// 7B5. ~B5^ $$ | $$ |$$\ $$\ $$$$$$$ | $$$$$$\ $$$$$$\ $$ | $$ |\$$\ $$ | +// .?B@G ~@@P~ $$$$$$$$ |$$ | $$ |$$ __$$ |$$ __$$\ \____$$\ $$ | $$ | \$$$$ / +// :?#@@@Y .&@@@P!. $$ __$$ |$$ | $$ |$$ / $$ |$$ | \__|$$$$$$$ |$$ | $$ | $$ $$< +// ^?J^7P&@@! .5@@#Y~!J!. $$ | $$ |$$ | $$ |$$ | $$ |$$ | $$ __$$ |$$ | $$ |$$ /\$$\ +// ^JJ!. :!J5^ ?5?^ ^?Y7. $$ | $$ |\$$$$$$$ |\$$$$$$$ |$$ | \$$$$$$$ |$$$$$$$ |$$ / $$ | +// ~PP: 7#B5!. :?P#G: 7G?. \__| \__| \____$$ | \_______|\__| \_______|\_______/ \__| \__| +// .!P@G 7@@@#Y^ .!P@@@#. ~@&J: $$\ $$ | +// !&@@J :&@@@@P. !&@@@@5 #@@P. \$$$$$$ | +// :J##: Y@@&P! :JB@@&~ ?@G! \______/ +// .?P!.?GY7: .. . ^?PP^:JP~ +// .7Y7. .!YGP^ ?BP?^ ^JJ^ This file is part of https://github.com/galacticcouncil/HydraDX-node +// .!Y7Y#@@#: ?@@@G?JJ^ Built with <3 for decentralisation. +// !G@@@Y .&@@&J: +// ^5@#. 7@#?. Copyright (C) 2021-2023 Intergalactic, Limited (GIB). +// :5P^.?G7. SPDX-License-Identifier: Apache-2.0 +// :?Y! Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// http://www.apache.org/licenses/LICENSE-2.0 + +use std::{ + collections::{BTreeMap, HashMap}, + path::PathBuf, + sync::Arc, + time::Duration, +}; + +use crate::service::{ + rpc::{RuntimeApiStorageOverride, SchemaV1Override, SchemaV2Override, SchemaV3Override, StorageOverride}, + FullClient, +}; +use cumulus_client_consensus_common::ParachainBlockImportMarker; +use fc_consensus::FrontierBlockImport; +use fc_db::Backend as FrontierBackend; +use fc_mapping_sync::{MappingSyncWorker, SyncStrategy}; +use fc_rpc::{EthTask, OverrideHandle}; +use fc_rpc_core::types::{FeeHistoryCache, FeeHistoryCacheLimit, FilterPool}; +use fp_rpc::EthereumRuntimeRPCApi; +use fp_storage::EthereumStorageSchema; +use futures::{future, StreamExt}; +use polkadot_cli::Cli; +use primitives::Block; +use sc_cli::SubstrateCli; +use sc_client_api::{backend::AuxStore, Backend, BlockOf, BlockchainEvents, StateBackend, StorageProvider}; +use sc_consensus::{BlockCheckParams, BlockImport as BlockImportT, BlockImportParams, ImportResult}; +use sc_service::{BasePath, Configuration, TFullBackend, TaskManager}; +use sp_api::{ConstructRuntimeApi, ProvideRuntimeApi}; +use sp_block_builder::BlockBuilder as BlockBuilderApi; +use sp_blockchain::{well_known_cache_keys::Id as CacheKeyId, Error as BlockchainError, HeaderBackend, HeaderMetadata}; +use sp_consensus::Error as ConsensusError; +use sp_core::H256; +use sp_runtime::traits::{BlakeTwo256, Block as BlockT}; + +/// The ethereum-compatibility configuration used to run a node. +/// evmTODO: revise settings, these are by Centrifuge +#[derive(Clone, Copy, Debug, clap::Parser)] +pub struct EthereumConfig { + /// Maximum number of logs in a query. + #[clap(long, default_value = "10000")] + pub max_past_logs: u32, + + /// Maximum fee history cache size. + #[clap(long, default_value = "2048")] + pub fee_history_limit: u64, + + #[clap(long)] + pub enable_dev_signer: bool, + + /// Maximum allowed gas limit will be `block.gas_limit * + /// execute_gas_limit_multiplier` when using eth_call/eth_estimateGas. + #[clap(long, default_value = "10")] + pub execute_gas_limit_multiplier: u64, + + /// Size in bytes of the LRU cache for block data. + #[clap(long, default_value = "50")] + pub eth_log_block_cache: usize, + + /// Size in bytes of the LRU cache for transactions statuses data. + #[clap(long, default_value = "50")] + pub eth_statuses_cache: usize, +} + +pub type Hash = sp_core::H256; + +#[derive(Clone)] +pub struct BlockImport, C>(FrontierBlockImport); + +impl BlockImport +where + B: BlockT, + I: BlockImportT> + Send + Sync, + I::Error: Into, + C: ProvideRuntimeApi + Send + Sync + HeaderBackend + AuxStore + BlockOf, + C::Api: EthereumRuntimeRPCApi, + C::Api: BlockBuilderApi, +{ + pub fn new(inner: I, client: Arc, backend: Arc>) -> Self { + Self(FrontierBlockImport::new(inner, client, backend)) + } +} + +#[async_trait::async_trait] +impl BlockImportT for BlockImport +where + B: BlockT, + I: BlockImportT> + Send + Sync, + I::Error: Into, + C: ProvideRuntimeApi + Send + Sync + HeaderBackend + AuxStore + BlockOf, + C::Api: EthereumRuntimeRPCApi, + C::Api: BlockBuilderApi, +{ + type Error = ConsensusError; + type Transaction = sp_api::TransactionFor; + + async fn check_block(&mut self, block: BlockCheckParams) -> Result { + self.0.check_block(block).await + } + + async fn import_block( + &mut self, + block: BlockImportParams, + new_cache: HashMap>, + ) -> Result { + self.0.import_block(block, new_cache).await + } +} + +impl, C> ParachainBlockImportMarker for BlockImport {} + +pub 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())) +} + +pub fn spawn_frontier_tasks( + task_manager: &TaskManager, + client: Arc>, + backend: Arc>, + frontier_backend: Arc>, + filter_pool: FilterPool, + overrides: Arc>, + fee_history_cache: FeeHistoryCache, + fee_history_cache_limit: FeeHistoryCacheLimit, +) where + RuntimeApi: ConstructRuntimeApi> + Send + Sync + 'static, + RuntimeApi::RuntimeApi: sp_transaction_pool::runtime_api::TaggedTransactionQueue + + sp_api::Metadata + + sp_session::SessionKeys + + sp_api::ApiExt, Block>> + + sp_offchain::OffchainWorkerApi + + sp_block_builder::BlockBuilder + + cumulus_primitives_core::CollectCollationInfo + + fp_rpc::EthereumRuntimeRPCApi, + Executor: sc_executor::NativeExecutionDispatch + 'static, +{ + task_manager.spawn_essential_handle().spawn( + "frontier-mapping-sync-worker", + None, + MappingSyncWorker::new( + client.import_notification_stream(), + Duration::new(6, 0), + client.clone(), + backend, + frontier_backend, + 3, + 0, + SyncStrategy::Parachain, + ) + .for_each(|()| future::ready(())), + ); + + // Spawn Frontier EthFilterApi maintenance task. + // 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", + None, + 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", + None, + EthTask::fee_history_task(client, overrides, fee_history_cache, fee_history_cache_limit), + ); +} + +pub fn overrides_handle, C, BE>(client: Arc) -> Arc> +where + C: ProvideRuntimeApi + StorageProvider + AuxStore, + C: HeaderBackend + HeaderMetadata, + C: Send + Sync + 'static, + C::Api: sp_api::ApiExt + fp_rpc::EthereumRuntimeRPCApi + fp_rpc::ConvertTransactionRuntimeApi, + BE: Backend + 'static, + BE::State: StateBackend, +{ + let mut overrides_map = BTreeMap::new(); + overrides_map.insert( + EthereumStorageSchema::V1, + Box::new(SchemaV1Override::new(client.clone())) as Box>, + ); + overrides_map.insert( + EthereumStorageSchema::V2, + Box::new(SchemaV2Override::new(client.clone())) as Box>, + ); + overrides_map.insert( + EthereumStorageSchema::V3, + Box::new(SchemaV3Override::new(client.clone())) as Box>, + ); + + Arc::new(OverrideHandle { + schemas: overrides_map, + fallback: Box::new(RuntimeApiStorageOverride::new(client)), + }) +} diff --git a/pallets/asset-registry/Cargo.toml b/pallets/asset-registry/Cargo.toml index 4508e98d9..1d4518a40 100644 --- a/pallets/asset-registry/Cargo.toml +++ b/pallets/asset-registry/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-asset-registry" -version = "2.3.1" +version = "2.3.2" description = "Pallet for asset registry management" authors = ["GalacticCouncil"] edition = "2021" diff --git a/pallets/asset-registry/src/lib.rs b/pallets/asset-registry/src/lib.rs index 162b9d697..507cab3cb 100644 --- a/pallets/asset-registry/src/lib.rs +++ b/pallets/asset-registry/src/lib.rs @@ -638,4 +638,14 @@ impl InspectRegistry for Pallet { fn decimals(asset_id: T::AssetId) -> Option { Some(AssetMetadataMap::::get(asset_id)?.decimals) } + + fn asset_name(asset_id: T::AssetId) -> Option> { + let asset = Assets::::get(asset_id)?; + Some(asset.name.into_inner()) + } + + fn asset_symbol(asset_id: T::AssetId) -> Option> { + let asset_metadata = AssetMetadataMap::::get(asset_id)?; + Some(asset_metadata.symbol.into_inner()) + } } diff --git a/pallets/democracy/Cargo.toml b/pallets/democracy/Cargo.toml index a2e5fc544..3580e0c6d 100644 --- a/pallets/democracy/Cargo.toml +++ b/pallets/democracy/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-democracy" -version = "4.0.1-dev" +version = "4.0.2-dev" authors = ["Parity Technologies "] edition = "2021" license = "Apache-2.0" diff --git a/pallets/democracy/src/lib.rs b/pallets/democracy/src/lib.rs index 66fbbf4c0..30a57514a 100644 --- a/pallets/democracy/src/lib.rs +++ b/pallets/democracy/src/lib.rs @@ -170,7 +170,6 @@ use sp_runtime::{ }; use sp_std::prelude::*; use sp_std::vec; - mod conviction; pub mod traits; mod types; diff --git a/pallets/stableswap/Cargo.toml b/pallets/stableswap/Cargo.toml index 3025cbcc1..54e1a085d 100644 --- a/pallets/stableswap/Cargo.toml +++ b/pallets/stableswap/Cargo.toml @@ -1,6 +1,6 @@ [package] name = 'pallet-stableswap' -version = '3.3.1' +version = '3.4.0' description = 'AMM for correlated assets' authors = ['GalacticCouncil'] edition = '2021' diff --git a/pallets/stableswap/src/tests/mock.rs b/pallets/stableswap/src/tests/mock.rs index c357cc019..b0d2a7fa6 100644 --- a/pallets/stableswap/src/tests/mock.rs +++ b/pallets/stableswap/src/tests/mock.rs @@ -326,6 +326,14 @@ impl InspectRegistry for DummyRegistry { let asset = REGISTERED_ASSETS.with(|v| v.borrow().get(&asset_id).copied())?; Some(asset.1) } + + fn asset_name(_asset_id: AssetId) -> Option> { + unimplemented!() + } + + fn asset_symbol(_asset_id: AssetId) -> Option> { + unimplemented!() + } } #[cfg(feature = "runtime-benchmarks")] diff --git a/pallets/transaction-multi-payment/Cargo.toml b/pallets/transaction-multi-payment/Cargo.toml index 014f557ec..c75886ddc 100644 --- a/pallets/transaction-multi-payment/Cargo.toml +++ b/pallets/transaction-multi-payment/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-transaction-multi-payment" -version = "9.0.1" +version = "9.0.2" description = "Transaction multi currency payment support module" authors = ["GalacticCoucil"] edition = "2021" @@ -19,6 +19,7 @@ orml-traits = { workspace = true } # HydraDX traits hydradx-traits = { workspace = true } +primitives = { workspace = true } # Substrate dependencies frame-support = { workspace = true } @@ -29,6 +30,8 @@ sp-std = { workspace = true } sp-runtime = { workspace = true } pallet-transaction-payment = { workspace = true } +pallet-evm = { workspace = true } + [dev-dependencies] pallet-currencies = { workspace = true } orml-tokens = { workspace = true, features=["std"] } @@ -48,5 +51,7 @@ std = [ "orml-traits/std", "hydradx-traits/std", "scale-info/std", + "pallet-evm/std", + "primitives/std", ] try-runtime = ["frame-support/try-runtime"] diff --git a/pallets/transaction-multi-payment/src/lib.rs b/pallets/transaction-multi-payment/src/lib.rs index 1a3f4170c..b8b2c3cbb 100644 --- a/pallets/transaction-multi-payment/src/lib.rs +++ b/pallets/transaction-multi-payment/src/lib.rs @@ -29,6 +29,7 @@ mod mock; mod tests; mod traits; +use frame_support::traits::Currency as PalletCurrency; use frame_support::{dispatch::DispatchResult, ensure, traits::Get, weights::Weight}; use frame_system::ensure_signed; use sp_runtime::{ @@ -36,6 +37,7 @@ use sp_runtime::{ transaction_validity::{InvalidTransaction, TransactionValidityError}, FixedU128, }; + use sp_std::prelude::*; use pallet_transaction_payment::OnChargeTransaction; @@ -46,7 +48,10 @@ use frame_support::sp_runtime::FixedPointOperand; use hydradx_traits::{pools::SpotPriceProvider, NativePriceOracle}; use orml_traits::{Happened, MultiCurrency}; -use frame_support::traits::IsSubType; +use frame_support::traits::{Imbalance, IsSubType, OnUnbalanced}; +use pallet_evm::{EVMCurrencyAdapter, OnChargeEVMTransaction}; +use sp_core::{H160, U256}; +use sp_runtime::traits::UniqueSaturatedInto; pub use crate::traits::*; @@ -345,6 +350,48 @@ impl DepositFee, BalanceOf> for Deposit } } +type CurrencyAccountId = ::AccountId; +type BalanceFor = <::Currency as PalletCurrency>>::Balance; +type PositiveImbalanceFor = + <::Currency as PalletCurrency>>::PositiveImbalance; +type NegativeImbalanceFor = + <::Currency as PalletCurrency>>::NegativeImbalance; + +/// Implements the transaction payment for EVM transactions. +pub struct TransferEvmFees(PhantomData); + +impl OnChargeEVMTransaction for TransferEvmFees +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 OnChargeEVMTransaction< + 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); + } + } +} + /// Implements the transaction payment for native as well as non-native currencies pub struct TransferFees(PhantomData<(MC, DF, FR)>); diff --git a/rococo-local/config-zombienet.json b/rococo-local/config-zombienet.json index 9dca3f009..595d14bed 100644 --- a/rococo-local/config-zombienet.json +++ b/rococo-local/config-zombienet.json @@ -39,7 +39,8 @@ { "name": "alice", "command": "../target/release/hydradx", - "ws_port": 9988 + "ws_port": 9988, + "rpc_port": 9999 }, { "name": "bob", @@ -49,4 +50,4 @@ ] } ] -} \ No newline at end of file +} diff --git a/runtime/hydradx/Cargo.toml b/runtime/hydradx/Cargo.toml index 2a534dfa5..4dfd4c5dd 100644 --- a/runtime/hydradx/Cargo.toml +++ b/runtime/hydradx/Cargo.toml @@ -19,6 +19,7 @@ serde = { features = ["derive"], optional = true, version = "1.0.136" } codec = { package = "parity-scale-codec", version = "3.4.0", default-features = false, features = ["derive"] } scale-info = { version = "2.3.1", default-features = false, features = ["derive"] } smallvec = "1.9.0" +num_enum = { version = "0.5.1", default-features = false } # local dependencies primitives = { workspace = true } @@ -131,6 +132,16 @@ sp-trie = { workspace = true } sp-io = { workspace = true } primitive-types = { workspace = true } +# Frontier +fp-rpc = { workspace = true } +fp-self-contained = { workspace = true } +pallet-ethereum = { workspace = true } +pallet-evm = { workspace = true } +pallet-evm-chain-id = { workspace = true } +pallet-evm-precompile-dispatch = { workspace = true } +module-evm-utility-macro = { workspace = true } +ethabi = { version = "18.0.0", default-features = false } + [features] default = ["std"] runtime-benchmarks = [ @@ -170,6 +181,8 @@ runtime-benchmarks = [ "pallet-otc/runtime-benchmarks", "pallet-dca/runtime-benchmarks", "pallet-route-executor/runtime-benchmarks", + "pallet-ethereum/runtime-benchmarks", + "pallet-evm/runtime-benchmarks", "pallet-staking/runtime-benchmarks", "pallet-bonds/runtime-benchmarks", "pallet-stableswap/runtime-benchmarks", @@ -260,6 +273,12 @@ std = [ "pallet-bonds/std", "pallet-stableswap/std", "pallet-lbp/std", + "fp-rpc/std", + "fp-self-contained/std", + "pallet-ethereum/std", + "pallet-evm/std", + "pallet-evm-chain-id/std", + "pallet-evm-precompile-dispatch/std", "pallet-xyk/std", ] try-runtime= [ @@ -322,5 +341,9 @@ try-runtime= [ "pallet-bonds/try-runtime", "pallet-stableswap/try-runtime", "pallet-lbp/try-runtime", + "fp-self-contained/try-runtime", + "pallet-ethereum/try-runtime", + "pallet-evm/try-runtime", + "pallet-evm-chain-id/try-runtime", "pallet-xyk/try-runtime", ] diff --git a/runtime/hydradx/src/evm/accounts_conversion.rs b/runtime/hydradx/src/evm/accounts_conversion.rs new file mode 100644 index 000000000..173aeaf26 --- /dev/null +++ b/runtime/hydradx/src/evm/accounts_conversion.rs @@ -0,0 +1,75 @@ +// : $$\ $$\ $$\ $$$$$$$\ $$\ $$\ +// !YJJ^ $$ | $$ | $$ | $$ __$$\ $$ | $$ | +// 7B5. ~B5^ $$ | $$ |$$\ $$\ $$$$$$$ | $$$$$$\ $$$$$$\ $$ | $$ |\$$\ $$ | +// .?B@G ~@@P~ $$$$$$$$ |$$ | $$ |$$ __$$ |$$ __$$\ \____$$\ $$ | $$ | \$$$$ / +// :?#@@@Y .&@@@P!. $$ __$$ |$$ | $$ |$$ / $$ |$$ | \__|$$$$$$$ |$$ | $$ | $$ $$< +// ^?J^7P&@@! .5@@#Y~!J!. $$ | $$ |$$ | $$ |$$ | $$ |$$ | $$ __$$ |$$ | $$ |$$ /\$$\ +// ^JJ!. :!J5^ ?5?^ ^?Y7. $$ | $$ |\$$$$$$$ |\$$$$$$$ |$$ | \$$$$$$$ |$$$$$$$ |$$ / $$ | +// ~PP: 7#B5!. :?P#G: 7G?. \__| \__| \____$$ | \_______|\__| \_______|\_______/ \__| \__| +// .!P@G 7@@@#Y^ .!P@@@#. ~@&J: $$\ $$ | +// !&@@J :&@@@@P. !&@@@@5 #@@P. \$$$$$$ | +// :J##: Y@@&P! :JB@@&~ ?@G! \______/ +// .?P!.?GY7: .. . ^?PP^:JP~ +// .7Y7. .!YGP^ ?BP?^ ^JJ^ This file is part of https://github.com/galacticcouncil/HydraDX-node +// .!Y7Y#@@#: ?@@@G?JJ^ Built with <3 for decentralisation. +// !G@@@Y .&@@&J: +// ^5@#. 7@#?. Copyright (C) 2021-2023 Intergalactic, Limited (GIB). +// :5P^.?G7. SPDX-License-Identifier: Apache-2.0 +// :?Y! Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// http://www.apache.org/licenses/LICENSE-2.0 +#![allow(unused_imports)] +use crate::{ + evm::{ConsensusEngineId, FindAuthor}, + AccountId, Aura, +}; +use codec::{Decode, Encode}; +use core::marker::PhantomData; +use hex_literal::hex; +use pallet_evm::AddressMapping; +use sp_core::{crypto::ByteArray, H160}; +use sp_runtime::traits::AccountIdConversion; + +#[derive(Encode, Decode, Default)] +struct EthereumAccount(H160); + +impl sp_runtime::TypeId for EthereumAccount { + const TYPE_ID: [u8; 4] = *b"ETH\0"; +} + +pub struct ExtendedAddressMapping; + +impl AddressMapping for ExtendedAddressMapping { + fn into_account_id(address: H160) -> AccountId { + EthereumAccount(address).into_account_truncating() + } +} + +// Ethereum-compatible blocks author (20 bytes) +// Converted by truncating from Substrate author (32 bytes) +pub struct FindAuthorTruncated(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.to_raw_vec()[4..24])); + } + None + } +} + +#[cfg(test)] +#[test] +fn eth_address_should_convert_to_account_id() { + // Private key: 42d8d953e4f9246093a33e9ca6daa078501012f784adfe4bbed57918ff13be14 + // Address: 0x222222ff7Be76052e023Ec1a306fCca8F9659D80 + // Account Id: 45544800222222ff7be76052e023ec1a306fcca8f9659d800000000000000000 + // SS58(63): 7KATdGakyhfBGnAt3XVgXTL7cYjzRXeSZHezKNtENcbwWibb + assert_eq!( + ExtendedAddressMapping::into_account_id(H160::from(hex!["222222ff7Be76052e023Ec1a306fCca8F9659D80"])), + AccountId::from(hex!["45544800222222ff7be76052e023ec1a306fcca8f9659d800000000000000000"]) + ); +} diff --git a/runtime/hydradx/src/evm/mod.rs b/runtime/hydradx/src/evm/mod.rs new file mode 100644 index 000000000..5b122c4f8 --- /dev/null +++ b/runtime/hydradx/src/evm/mod.rs @@ -0,0 +1,145 @@ +// : $$\ $$\ $$\ $$$$$$$\ $$\ $$\ +// !YJJ^ $$ | $$ | $$ | $$ __$$\ $$ | $$ | +// 7B5. ~B5^ $$ | $$ |$$\ $$\ $$$$$$$ | $$$$$$\ $$$$$$\ $$ | $$ |\$$\ $$ | +// .?B@G ~@@P~ $$$$$$$$ |$$ | $$ |$$ __$$ |$$ __$$\ \____$$\ $$ | $$ | \$$$$ / +// :?#@@@Y .&@@@P!. $$ __$$ |$$ | $$ |$$ / $$ |$$ | \__|$$$$$$$ |$$ | $$ | $$ $$< +// ^?J^7P&@@! .5@@#Y~!J!. $$ | $$ |$$ | $$ |$$ | $$ |$$ | $$ __$$ |$$ | $$ |$$ /\$$\ +// ^JJ!. :!J5^ ?5?^ ^?Y7. $$ | $$ |\$$$$$$$ |\$$$$$$$ |$$ | \$$$$$$$ |$$$$$$$ |$$ / $$ | +// ~PP: 7#B5!. :?P#G: 7G?. \__| \__| \____$$ | \_______|\__| \_______|\_______/ \__| \__| +// .!P@G 7@@@#Y^ .!P@@@#. ~@&J: $$\ $$ | +// !&@@J :&@@@@P. !&@@@@5 #@@P. \$$$$$$ | +// :J##: Y@@&P! :JB@@&~ ?@G! \______/ +// .?P!.?GY7: .. . ^?PP^:JP~ +// .7Y7. .!YGP^ ?BP?^ ^JJ^ This file is part of https://github.com/galacticcouncil/HydraDX-node +// .!Y7Y#@@#: ?@@@G?JJ^ Built with <3 for decentralisation. +// !G@@@Y .&@@&J: +// ^5@#. 7@#?. Copyright (C) 2021-2023 Intergalactic, Limited (GIB). +// :5P^.?G7. SPDX-License-Identifier: Apache-2.0 +// :?Y! Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// http://www.apache.org/licenses/LICENSE-2.0 + +use crate::TreasuryAccount; +pub use crate::{ + evm::accounts_conversion::{ExtendedAddressMapping, FindAuthorTruncated}, + AssetLocation, Aura, NORMAL_DISPATCH_RATIO, +}; +use frame_support::{ + parameter_types, + traits::{Defensive, FindAuthor, Imbalance, OnUnbalanced}, + weights::{constants::WEIGHT_REF_TIME_PER_SECOND, Weight}, + ConsensusEngineId, +}; +use hex_literal::hex; +use orml_tokens::CurrencyAdapter; +use pallet_evm::{EnsureAddressTruncated, FeeCalculator}; +use pallet_transaction_multi_payment::{DepositAll, DepositFee, TransferEvmFees}; +use polkadot_xcm::{ + latest::MultiLocation, + prelude::{AccountKey20, PalletInstance, Parachain, X3}, +}; +use primitives::{constants::chain::MAXIMUM_BLOCK_WEIGHT, AccountId, AssetId}; +use sp_core::{Get, U256}; + +mod accounts_conversion; +pub mod precompiles; + +// Centrifuge / Moonbeam: +// Current approximation of the gas per second 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. +const WEIGHT_PER_GAS: u64 = WEIGHT_REF_TIME_PER_SECOND / GAS_PER_SECOND; + +// Fixed gas price of 0.1 gwei per gas +// pallet-base-fee to be implemented after migration to polkadot-v1.1.0 +const DEFAULT_BASE_FEE_PER_GAS: u128 = 100_000_000; + +parameter_types! { + // We allow for a 75% fullness of a 0.5s block + pub BlockGasLimit: U256 = U256::from(NORMAL_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT.ref_time() / WEIGHT_PER_GAS); + + pub PrecompilesValue: precompiles::HydraDXPrecompiles = precompiles::HydraDXPrecompiles::<_>::new(); + pub WeightPerGas: Weight = Weight::from_ref_time(WEIGHT_PER_GAS); +} + +const MOONBEAM_PARA_ID: u32 = 2004; +pub const WETH_ASSET_LOCATION: AssetLocation = AssetLocation(MultiLocation { + parents: 1, + interior: X3( + Parachain(MOONBEAM_PARA_ID), + PalletInstance(110), + AccountKey20 { + network: None, + key: hex!["ab3f0245b83feb11d15aaffefd7ad465a59817ed"], + }, + ), +}); + +pub struct WethAssetId; +impl Get for WethAssetId { + fn get() -> AssetId { + let invalid_id = + pallet_asset_registry::Pallet::::next_asset_id().defensive_unwrap_or(AssetId::MAX); + + match pallet_asset_registry::Pallet::::location_to_asset(WETH_ASSET_LOCATION) { + Some(asset_id) => asset_id, + None => invalid_id, + } + } +} + +type WethCurrency = CurrencyAdapter; +use frame_support::traits::Currency as PalletCurrency; + +type NegativeImbalance = >::NegativeImbalance; + +pub struct DealWithFees; +impl OnUnbalanced for DealWithFees { + // this is called for substrate-based transactions + fn on_unbalanceds(_: impl Iterator) {} + + // this is called from pallet_evm for Ethereum-based transactions + // (technically, it calls on_unbalanced, which calls this when non-zero) + fn on_nonzero_unbalanced(amount: NegativeImbalance) { + let _ = DepositAll::::deposit_fee(&TreasuryAccount::get(), WethAssetId::get(), amount.peek()); + } +} + +pub struct FixedGasPrice; +impl FeeCalculator for FixedGasPrice { + fn min_gas_price() -> (U256, Weight) { + // Return some meaningful gas price and weight + (DEFAULT_BASE_FEE_PER_GAS.into(), Weight::from_parts(7u64, 0)) + } +} + +impl pallet_evm::Config for crate::Runtime { + type AddressMapping = ExtendedAddressMapping; + type BlockGasLimit = BlockGasLimit; + type BlockHashMapping = pallet_ethereum::EthereumBlockHashMapping; + type CallOrigin = EnsureAddressTruncated; + type ChainId = crate::EVMChainId; + type Currency = WethCurrency; + type FeeCalculator = FixedGasPrice; + type FindAuthor = FindAuthorTruncated; + type GasWeightMapping = pallet_evm::FixedGasWeightMapping; + type OnChargeTransaction = TransferEvmFees; + type OnCreate = (); + type PrecompilesType = precompiles::HydraDXPrecompiles; + type PrecompilesValue = PrecompilesValue; + type Runner = pallet_evm::runner::stack::Runner; + type RuntimeEvent = crate::RuntimeEvent; + type WeightPerGas = WeightPerGas; + type WithdrawOrigin = EnsureAddressTruncated; +} + +impl pallet_evm_chain_id::Config for crate::Runtime {} + +impl pallet_ethereum::Config for crate::Runtime { + type RuntimeEvent = crate::RuntimeEvent; + type StateRoot = pallet_ethereum::IntermediateStateRoot; +} diff --git a/runtime/hydradx/src/evm/precompiles/costs.rs b/runtime/hydradx/src/evm/precompiles/costs.rs new file mode 100644 index 000000000..c8472158f --- /dev/null +++ b/runtime/hydradx/src/evm/precompiles/costs.rs @@ -0,0 +1,50 @@ +// : $$\ $$\ $$\ $$$$$$$\ $$\ $$\ +// !YJJ^ $$ | $$ | $$ | $$ __$$\ $$ | $$ | +// 7B5. ~B5^ $$ | $$ |$$\ $$\ $$$$$$$ | $$$$$$\ $$$$$$\ $$ | $$ |\$$\ $$ | +// .?B@G ~@@P~ $$$$$$$$ |$$ | $$ |$$ __$$ |$$ __$$\ \____$$\ $$ | $$ | \$$$$ / +// :?#@@@Y .&@@@P!. $$ __$$ |$$ | $$ |$$ / $$ |$$ | \__|$$$$$$$ |$$ | $$ | $$ $$< +// ^?J^7P&@@! .5@@#Y~!J!. $$ | $$ |$$ | $$ |$$ | $$ |$$ | $$ __$$ |$$ | $$ |$$ /\$$\ +// ^JJ!. :!J5^ ?5?^ ^?Y7. $$ | $$ |\$$$$$$$ |\$$$$$$$ |$$ | \$$$$$$$ |$$$$$$$ |$$ / $$ | +// ~PP: 7#B5!. :?P#G: 7G?. \__| \__| \____$$ | \_______|\__| \_______|\_______/ \__| \__| +// .!P@G 7@@@#Y^ .!P@@@#. ~@&J: $$\ $$ | +// !&@@J :&@@@@P. !&@@@@5 #@@P. \$$$$$$ | +// :J##: Y@@&P! :JB@@&~ ?@G! \______/ +// .?P!.?GY7: .. . ^?PP^:JP~ +// .7Y7. .!YGP^ ?BP?^ ^JJ^ This file is part of https://github.com/galacticcouncil/HydraDX-node +// .!Y7Y#@@#: ?@@@G?JJ^ Built with <3 for decentralisation. +// !G@@@Y .&@@&J: +// ^5@#. 7@#?. Copyright (C) 2021-2023 Intergalactic, Limited (GIB). +// :5P^.?G7. SPDX-License-Identifier: Apache-2.0 +// :?Y! Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// http://www.apache.org/licenses/LICENSE-2.0 + +//! Cost calculations. +use crate::evm::precompiles::EvmResult; +use pallet_evm::{ExitError, PrecompileFailure}; + +// Cost calculation is copied from EVM code that is not publicly exposed by the crates. +// https://github.com/rust-blockchain/evm/blob/master/gasometer/src/costs.rs#L148 +pub fn log_costs(topics: usize, data_len: usize) -> EvmResult { + const G_LOG: u64 = 375; + const G_LOGDATA: u64 = 8; + const G_LOGTOPIC: u64 = 375; + + let topic_cost = G_LOGTOPIC.checked_mul(topics as u64).ok_or(PrecompileFailure::Error { + exit_status: ExitError::OutOfGas, + })?; + + let data_cost = G_LOGDATA.checked_mul(data_len as u64).ok_or(PrecompileFailure::Error { + exit_status: ExitError::OutOfGas, + })?; + + G_LOG + .checked_add(topic_cost) + .ok_or(PrecompileFailure::Error { + exit_status: ExitError::OutOfGas, + })? + .checked_add(data_cost) + .ok_or(PrecompileFailure::Error { + exit_status: ExitError::OutOfGas, + }) +} diff --git a/runtime/hydradx/src/evm/precompiles/erc20_mapping.rs b/runtime/hydradx/src/evm/precompiles/erc20_mapping.rs new file mode 100644 index 000000000..22474cb4a --- /dev/null +++ b/runtime/hydradx/src/evm/precompiles/erc20_mapping.rs @@ -0,0 +1,71 @@ +// : $$\ $$\ $$\ $$$$$$$\ $$\ $$\ +// !YJJ^ $$ | $$ | $$ | $$ __$$\ $$ | $$ | +// 7B5. ~B5^ $$ | $$ |$$\ $$\ $$$$$$$ | $$$$$$\ $$$$$$\ $$ | $$ |\$$\ $$ | +// .?B@G ~@@P~ $$$$$$$$ |$$ | $$ |$$ __$$ |$$ __$$\ \____$$\ $$ | $$ | \$$$$ / +// :?#@@@Y .&@@@P!. $$ __$$ |$$ | $$ |$$ / $$ |$$ | \__|$$$$$$$ |$$ | $$ | $$ $$< +// ^?J^7P&@@! .5@@#Y~!J!. $$ | $$ |$$ | $$ |$$ | $$ |$$ | $$ __$$ |$$ | $$ |$$ /\$$\ +// ^JJ!. :!J5^ ?5?^ ^?Y7. $$ | $$ |\$$$$$$$ |\$$$$$$$ |$$ | \$$$$$$$ |$$$$$$$ |$$ / $$ | +// ~PP: 7#B5!. :?P#G: 7G?. \__| \__| \____$$ | \_______|\__| \_______|\_______/ \__| \__| +// .!P@G 7@@@#Y^ .!P@@@#. ~@&J: $$\ $$ | +// !&@@J :&@@@@P. !&@@@@5 #@@P. \$$$$$$ | +// :J##: Y@@&P! :JB@@&~ ?@G! \______/ +// .?P!.?GY7: .. . ^?PP^:JP~ +// .7Y7. .!YGP^ ?BP?^ ^JJ^ This file is part of https://github.com/galacticcouncil/HydraDX-node +// .!Y7Y#@@#: ?@@@G?JJ^ Built with <3 for decentralisation. +// !G@@@Y .&@@&J: +// ^5@#. 7@#?. Copyright (C) 2021-2023 Intergalactic, Limited (GIB). +// :5P^.?G7. SPDX-License-Identifier: Apache-2.0 +// :?Y! Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// http://www.apache.org/licenses/LICENSE-2.0 + +use crate::evm::precompiles::EvmAddress; +use hex_literal::hex; +use primitive_types::H160; +use primitives::AssetId; + +/// A mapping between AssetId and Erc20 EVM address. +pub trait Erc20Mapping { + fn encode_evm_address(asset_id: AssetId) -> Option; + + fn decode_evm_address(evm_address: EvmAddress) -> Option; +} + +pub struct HydraErc20Mapping; + +/// Erc20Mapping logic for HydraDX +/// The asset id (with type u32) is encoded in the last 4 bytes of EVM address +impl Erc20Mapping for HydraErc20Mapping { + fn encode_evm_address(asset_id: AssetId) -> Option { + let asset_id_bytes: [u8; 4] = asset_id.to_le_bytes(); + + let mut evm_address_bytes = [0u8; 20]; + + evm_address_bytes[15] = 1; + + for i in 0..4 { + evm_address_bytes[16 + i] = asset_id_bytes[3 - i]; + } + + Some(EvmAddress::from(evm_address_bytes)) + } + + fn decode_evm_address(evm_address: EvmAddress) -> Option { + if !is_asset_address(evm_address) { + return None; + } + + let mut asset_id: u32 = 0; + for byte in evm_address.as_bytes() { + asset_id = (asset_id << 8) | (*byte as u32); + } + + Some(asset_id) + } +} + +pub fn is_asset_address(address: H160) -> bool { + let asset_address_prefix = &(H160::from(hex!("0000000000000000000000000000000100000000"))[0..16]); + + &address.to_fixed_bytes()[0..16] == asset_address_prefix +} diff --git a/runtime/hydradx/src/evm/precompiles/handle.rs b/runtime/hydradx/src/evm/precompiles/handle.rs new file mode 100644 index 000000000..930a6c690 --- /dev/null +++ b/runtime/hydradx/src/evm/precompiles/handle.rs @@ -0,0 +1,519 @@ +// : $$\ $$\ $$\ $$$$$$$\ $$\ $$\ +// !YJJ^ $$ | $$ | $$ | $$ __$$\ $$ | $$ | +// 7B5. ~B5^ $$ | $$ |$$\ $$\ $$$$$$$ | $$$$$$\ $$$$$$\ $$ | $$ |\$$\ $$ | +// .?B@G ~@@P~ $$$$$$$$ |$$ | $$ |$$ __$$ |$$ __$$\ \____$$\ $$ | $$ | \$$$$ / +// :?#@@@Y .&@@@P!. $$ __$$ |$$ | $$ |$$ / $$ |$$ | \__|$$$$$$$ |$$ | $$ | $$ $$< +// ^?J^7P&@@! .5@@#Y~!J!. $$ | $$ |$$ | $$ |$$ | $$ |$$ | $$ __$$ |$$ | $$ |$$ /\$$\ +// ^JJ!. :!J5^ ?5?^ ^?Y7. $$ | $$ |\$$$$$$$ |\$$$$$$$ |$$ | \$$$$$$$ |$$$$$$$ |$$ / $$ | +// ~PP: 7#B5!. :?P#G: 7G?. \__| \__| \____$$ | \_______|\__| \_______|\_______/ \__| \__| +// .!P@G 7@@@#Y^ .!P@@@#. ~@&J: $$\ $$ | +// !&@@J :&@@@@P. !&@@@@5 #@@P. \$$$$$$ | +// :J##: Y@@&P! :JB@@&~ ?@G! \______/ +// .?P!.?GY7: .. . ^?PP^:JP~ +// .7Y7. .!YGP^ ?BP?^ ^JJ^ This file is part of https://github.com/galacticcouncil/HydraDX-node +// .!Y7Y#@@#: ?@@@G?JJ^ Built with <3 for decentralisation. +// !G@@@Y .&@@&J: +// ^5@#. 7@#?. Copyright (C) 2021-2023 Intergalactic, Limited (GIB). +// :5P^.?G7. SPDX-License-Identifier: Apache-2.0 +// :?Y! Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// http://www.apache.org/licenses/LICENSE-2.0 + +use crate::evm::precompiles::{costs, revert, Address, Bytes, EvmResult}; +use frame_support::log; +use pallet_evm::{Context, Log, PrecompileHandle}; +use primitive_types::{H160, H256, U256}; +use smallvec::alloc; +use sp_std::borrow::ToOwned; +use sp_std::vec; +use sp_std::vec::Vec; + +/// Wrapper around an EVM input slice, helping to parse it. +/// Provide functions to parse common types. +#[derive(Clone, Copy, Debug)] +pub struct EvmDataReader<'a> { + input: &'a [u8], + cursor: usize, +} + +#[derive(Clone, Debug)] +pub struct EvmDataWriter { + pub(crate) data: Vec, + offset_data: Vec, + selector: Option, +} + +impl EvmDataWriter { + /// Creates a new empty output builder (without selector). + pub fn new() -> Self { + Self { + data: vec![], + offset_data: vec![], + selector: None, + } + } + + /// Creates a new empty output builder with provided selector. + /// Selector will only be appended before the data when calling + /// `build` to not mess with the offsets. + pub fn new_with_selector(selector: impl Into) -> Self { + Self { + data: vec![], + offset_data: vec![], + selector: Some(selector.into()), + } + } + + /// Return the built data. + pub fn build(mut self) -> Vec { + Self::bake_offsets(&mut self.data, self.offset_data); + + if let Some(selector) = self.selector { + let mut output = selector.to_be_bytes().to_vec(); + output.append(&mut self.data); + output + } else { + self.data + } + } + + /// Add offseted data at the end of this writer's data, updating the offsets. + fn bake_offsets(output: &mut Vec, offsets: Vec) { + for mut offset_datum in offsets { + let offset_position = offset_datum.offset_position; + let offset_position_end = offset_position + 32; + + // The offset is the distance between the start of the data and the + // start of the pointed data (start of a struct, length of an array). + // Offsets in inner data are relative to the start of their respective "container". + // However in arrays the "container" is actually the item itself instead of the whole + // array, which is corrected by `offset_shift`. + let free_space_offset = output.len() - offset_datum.offset_shift; + + // Override dummy offset to the offset it will be in the final output. + U256::from(free_space_offset).to_big_endian(&mut output[offset_position..offset_position_end]); + + // Append this data at the end of the current output. + output.append(&mut offset_datum.data); + } + } + + /// Write arbitrary bytes. + /// Doesn't handle any alignement checks, prefer using `write` instead if possible. + fn write_raw_bytes(mut self, value: &[u8]) -> Self { + self.data.extend_from_slice(value); + self + } + + /// Write data of requested type. + pub fn write(mut self, value: T) -> Self { + T::write(&mut self, value); + self + } + + /// Writes a pointer to given data. + /// The data will be appended when calling `build`. + /// Initially write a dummy value as offset in this writer's data, which will be replaced by + /// the correct offset once the pointed data is appended. + /// + /// Takes `&mut self` since its goal is to be used inside `EvmData` impl and not in chains. + pub fn write_pointer(&mut self, data: Vec) { + let offset_position = self.data.len(); + H256::write(self, H256::repeat_byte(0xff)); + + self.offset_data.push(OffsetDatum { + offset_position, + data, + offset_shift: 0, + }); + } +} + +impl Default for EvmDataWriter { + fn default() -> Self { + Self::new() + } +} + +#[derive(Clone, Debug)] +struct OffsetDatum { + // Offset location in the container data. + offset_position: usize, + // Data pointed by the offset that must be inserted at the end of container data. + data: Vec, + // Inside of arrays, the offset is not from the start of array data (length), but from the start + // of the item. This shift allow to correct this. + offset_shift: usize, +} + +/// Data that can be converted from and to EVM data types. +pub trait EvmData: Sized { + fn read(reader: &mut EvmDataReader) -> EvmResult; + fn write(writer: &mut EvmDataWriter, value: Self); + fn has_static_size() -> bool; +} + +impl EvmData for U256 { + fn read(reader: &mut EvmDataReader) -> EvmResult { + let range = reader.move_cursor(32)?; + + let data = reader + .input + .get(range) + .ok_or_else(|| revert("tried to parse U256 out of bounds"))?; + + Ok(U256::from_big_endian(data)) + } + + fn write(writer: &mut EvmDataWriter, value: Self) { + let mut buffer = [0u8; 32]; + value.to_big_endian(&mut buffer); + writer.data.extend_from_slice(&buffer); + } + + fn has_static_size() -> bool { + true + } +} + +impl EvmData for H256 { + fn read(reader: &mut EvmDataReader) -> EvmResult { + let range = reader.move_cursor(32)?; + + let data = reader + .input + .get(range) + .ok_or_else(|| revert("tried to parse H256 out of bounds"))?; + + Ok(H256::from_slice(data)) + } + + fn write(writer: &mut EvmDataWriter, value: Self) { + writer.data.extend_from_slice(value.as_bytes()); + } + + fn has_static_size() -> bool { + true + } +} + +impl EvmData for Bytes { + fn read(reader: &mut EvmDataReader) -> EvmResult { + let mut inner_reader = reader.read_pointer()?; + + // Read bytes/string size. + let array_size: usize = inner_reader + .read::() + .map_err(|_| revert("tried to parse bytes/string length out of bounds"))? + .try_into() + .map_err(|_| revert("bytes/string length is too large"))?; + + // Get valid range over the bytes data. + let range = inner_reader.move_cursor(array_size)?; + + let data = inner_reader + .input + .get(range) + .ok_or_else(|| revert("tried to parse bytes/string out of bounds"))?; + + let bytes = Self(data.to_owned()); + + Ok(bytes) + } + + fn write(writer: &mut EvmDataWriter, value: Self) { + let length = value.0.len(); + + // Pad the data. + // Leave it as is if a multiple of 32, otherwise pad to next + // multiple or 32. + let chunks = length / 32; + let padded_size = match length % 32 { + 0 => chunks * 32, + _ => (chunks + 1) * 32, + }; + + let mut value = value.0.to_vec(); + value.resize(padded_size, 0); + + writer.write_pointer( + EvmDataWriter::new() + .write(U256::from(length)) + .write_raw_bytes(&value) + .build(), + ); + } + + fn has_static_size() -> bool { + false + } +} + +impl EvmData for Address { + fn read(reader: &mut EvmDataReader) -> EvmResult { + let range = reader.move_cursor(32)?; + + let data = reader + .input + .get(range) + .ok_or_else(|| revert("tried to parse H160 out of bounds"))?; + + Ok(H160::from_slice(&data[12..32]).into()) + } + + fn write(writer: &mut EvmDataWriter, value: Self) { + H256::write(writer, value.0.into()); + } + + fn has_static_size() -> bool { + true + } +} + +macro_rules! impl_evmdata_for_uints { + ($($uint:ty, )*) => { + $( + impl EvmData for $uint { + fn read(reader: &mut EvmDataReader) -> EvmResult { + let value256: U256 = reader.read()?; + + value256 + .try_into() + .map_err(|_| revert(alloc::format!( + "value too big for type", + ))) + } + + fn write(writer: &mut EvmDataWriter, value: Self) { + U256::write(writer, value.into()); + } + + fn has_static_size() -> bool { + true + } + } + )* + }; +} + +impl_evmdata_for_uints!(u8, u16, u32, u64, u128,); + +impl EvmData for bool { + fn read(reader: &mut EvmDataReader) -> EvmResult { + let h256 = H256::read(reader).map_err(|_| revert("tried to parse bool out of bounds"))?; + + Ok(!h256.is_zero()) + } + + fn write(writer: &mut EvmDataWriter, value: Self) { + let mut buffer = [0u8; 32]; + if value { + buffer[31] = 1; + } + + writer.data.extend_from_slice(&buffer); + } + + fn has_static_size() -> bool { + true + } +} + +impl<'a> EvmDataReader<'a> { + /// Create a new input parser. + pub fn new(input: &'a [u8]) -> Self { + Self { input, cursor: 0 } + } + + /// Create a new input parser from a selector-initial input. + pub fn read_selector(input: &'a [u8]) -> EvmResult + where + T: num_enum::TryFromPrimitive, + { + if input.len() < 4 { + return Err(revert("tried to parse selector out of bounds")); + } + + let mut buffer = [0u8; 4]; + buffer.copy_from_slice(&input[0..4]); + let selector = T::try_from_primitive(u32::from_be_bytes(buffer)).map_err(|_| { + log::trace!( + target: "precompile-utils", + "Failed to match function selector" + //TODO: add type in log + ); + revert("unknown selector") + })?; + + Ok(selector) + } + + /// Create a new input parser from a selector-initial input. + pub fn new_skip_selector(input: &'a [u8]) -> EvmResult { + if input.len() < 4 { + return Err(revert("input is too short")); + } + + Ok(Self::new(&input[4..])) + } + + /// Check the input has at least the correct amount of arguments before the end (32 bytes + /// values). + pub fn expect_arguments(&self, args: usize) -> EvmResult { + if self.input.len() >= self.cursor + args * 32 { + Ok(()) + } else { + Err(revert("input doesn't match expected length")) + } + } + + /// Read data from the input. + pub fn read(&mut self) -> EvmResult { + T::read(self) + } + + /// Read raw bytes from the input. + /// Doesn't handle any alignment checks, prefer using `read` instead of possible. + /// Returns an error if trying to parse out of bounds. + pub fn read_raw_bytes(&mut self, len: usize) -> EvmResult<&[u8]> { + let range = self.move_cursor(len)?; + + let data = self + .input + .get(range) + .ok_or_else(|| revert("tried to parse raw bytes out of bounds"))?; + + Ok(data) + } + + /// Reads a pointer, returning a reader targetting the pointed location. + pub fn read_pointer(&mut self) -> EvmResult { + let offset: usize = self + .read::() + .map_err(|_| revert("tried to parse array offset out of bounds"))? + .try_into() + .map_err(|_| revert("array offset is too large"))?; + + if offset >= self.input.len() { + return Err(revert("pointer points out of bounds")); + } + + Ok(Self { + input: &self.input[offset..], + cursor: 0, + }) + } + + /// Read remaining bytes + pub fn read_till_end(&mut self) -> EvmResult<&[u8]> { + let range = self.move_cursor(self.input.len() - self.cursor)?; + + let data = self + .input + .get(range) + .ok_or_else(|| revert("tried to parse raw bytes out of bounds"))?; + + Ok(data) + } + + /// Move the reading cursor with provided length, and return a range from the previous cursor + /// location to the new one. + /// Checks cursor overflows. + fn move_cursor(&mut self, len: usize) -> EvmResult> { + let start = self.cursor; + let end = self + .cursor + .checked_add(len) + .ok_or_else(|| revert("data reading cursor overflow"))?; + + self.cursor = end; + + Ok(start..end) + } +} + +/// Represents modifiers a Solidity function can be annotated with. +#[derive(Copy, Clone, PartialEq, Eq)] +pub enum FunctionModifier { + /// Function that doesn't modify the state. + View, + /// Function that modifies the state but refuse receiving funds. + /// Correspond to a Solidity function with no modifiers. + NonPayable, + /// Function that modifies the state and accept funds. + Payable, +} + +pub trait PrecompileHandleExt: PrecompileHandle { + /// Record cost of a log manually. + /// This can be useful to record log costs early when their content have static size. + fn record_log_costs_manual(&mut self, topics: usize, data_len: usize) -> EvmResult; + + /// Record cost of logs. + fn record_log_costs(&mut self, logs: &[&Log]) -> EvmResult; + + /// Check that a function call is compatible with the context it is + /// called into. + fn check_function_modifier(&self, modifier: FunctionModifier) -> EvmResult; + + /// Read the selector from the input data. + fn read_selector(&self) -> EvmResult + where + T: num_enum::TryFromPrimitive; + + /// Returns a reader of the input, skipping the selector. + fn read_input(&self) -> EvmResult; +} + +impl PrecompileHandleExt for T { + /// Record cost of a log manualy. + /// This can be useful to record log costs early when their content have static size. + fn record_log_costs_manual(&mut self, topics: usize, data_len: usize) -> EvmResult { + self.record_cost(costs::log_costs(topics, data_len)?)?; + + Ok(()) + } + + /// Record cost of logs. + fn record_log_costs(&mut self, logs: &[&Log]) -> EvmResult { + for log in logs { + self.record_log_costs_manual(log.topics.len(), log.data.len())?; + } + + Ok(()) + } + + /// Check that a function call is compatible with the context it is + /// called into. + fn check_function_modifier(&self, modifier: FunctionModifier) -> EvmResult { + check_function_modifier(self.context(), self.is_static(), modifier) + } + + /// Read the selector from the input data. + fn read_selector(&self) -> EvmResult + where + S: num_enum::TryFromPrimitive, + { + let input = self.input(); + EvmDataReader::read_selector(input) + } + + /// Returns a reader of the input, skipping the selector. + fn read_input(&self) -> EvmResult { + EvmDataReader::new_skip_selector(self.input()) + } +} + +/// Check that a function call is compatible with the context it is +/// called into. +pub fn check_function_modifier(context: &Context, is_static: bool, modifier: FunctionModifier) -> EvmResult { + if is_static && modifier != FunctionModifier::View { + return Err(revert("can't call non-static function in static context")); + } + + if modifier != FunctionModifier::Payable && context.apparent_value > U256::zero() { + return Err(revert("function is not payable")); + } + + Ok(()) +} diff --git a/runtime/hydradx/src/evm/precompiles/mod.rs b/runtime/hydradx/src/evm/precompiles/mod.rs new file mode 100644 index 000000000..10f008172 --- /dev/null +++ b/runtime/hydradx/src/evm/precompiles/mod.rs @@ -0,0 +1,224 @@ +// : $$\ $$\ $$\ $$$$$$$\ $$\ $$\ +// !YJJ^ $$ | $$ | $$ | $$ __$$\ $$ | $$ | +// 7B5. ~B5^ $$ | $$ |$$\ $$\ $$$$$$$ | $$$$$$\ $$$$$$\ $$ | $$ |\$$\ $$ | +// .?B@G ~@@P~ $$$$$$$$ |$$ | $$ |$$ __$$ |$$ __$$\ \____$$\ $$ | $$ | \$$$$ / +// :?#@@@Y .&@@@P!. $$ __$$ |$$ | $$ |$$ / $$ |$$ | \__|$$$$$$$ |$$ | $$ | $$ $$< +// ^?J^7P&@@! .5@@#Y~!J!. $$ | $$ |$$ | $$ |$$ | $$ |$$ | $$ __$$ |$$ | $$ |$$ /\$$\ +// ^JJ!. :!J5^ ?5?^ ^?Y7. $$ | $$ |\$$$$$$$ |\$$$$$$$ |$$ | \$$$$$$$ |$$$$$$$ |$$ / $$ | +// ~PP: 7#B5!. :?P#G: 7G?. \__| \__| \____$$ | \_______|\__| \_______|\_______/ \__| \__| +// .!P@G 7@@@#Y^ .!P@@@#. ~@&J: $$\ $$ | +// !&@@J :&@@@@P. !&@@@@5 #@@P. \$$$$$$ | +// :J##: Y@@&P! :JB@@&~ ?@G! \______/ +// .?P!.?GY7: .. . ^?PP^:JP~ +// .7Y7. .!YGP^ ?BP?^ ^JJ^ This file is part of https://github.com/galacticcouncil/HydraDX-node +// .!Y7Y#@@#: ?@@@G?JJ^ Built with <3 for decentralisation. +// !G@@@Y .&@@&J: +// ^5@#. 7@#?. Copyright (C) 2021-2023 Intergalactic, Limited (GIB). +// :5P^.?G7. SPDX-License-Identifier: Apache-2.0 +// :?Y! Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// http://www.apache.org/licenses/LICENSE-2.0 + +use core::marker::PhantomData; + +use crate::evm::precompiles::{erc20_mapping::is_asset_address, multicurrency::MultiCurrencyPrecompile}; +use codec::Decode; +use frame_support::dispatch::{Dispatchable, GetDispatchInfo, PostDispatchInfo}; +use pallet_evm::{ + ExitError, ExitRevert, ExitSucceed, Precompile, PrecompileFailure, PrecompileHandle, PrecompileOutput, + PrecompileResult, PrecompileSet, +}; + +use codec::alloc; +use ethabi::Token; +use primitive_types::{H160, U256}; +use sp_std::{borrow::ToOwned, vec::Vec}; + +pub mod costs; +pub mod erc20_mapping; +pub mod handle; +pub mod multicurrency; +pub mod substrate; + +pub type EvmResult = Result; + +#[cfg(test)] +mod tests; + +pub type EvmAddress = sp_core::H160; + +/// The `address` type of Solidity. +/// H160 could represent 2 types of data (bytes20 and address) that are not encoded the same way. +/// To avoid issues writing H160 is thus not supported. +#[derive(Clone, Copy, Debug, Eq, PartialEq)] +pub struct Address(pub H160); + +impl From for Address { + fn from(a: H160) -> Address { + Address(a) + } +} + +impl From

for H160 { + fn from(a: Address) -> H160 { + a.0 + } +} + +pub struct HydraDXPrecompiles(PhantomData); + +impl HydraDXPrecompiles { + #[allow(clippy::new_without_default)] // We'll never use Default and can't derive it. + pub fn new() -> Self { + Self(Default::default()) + } +} + +// Same as Moonbean and Centrifuge, should benefit interoperability +// See also +// https://docs.moonbeam.network/builders/pallets-precompiles/precompiles/overview/#precompiled-contract-addresses +const DISPATCH_ADDR: H160 = addr(1025); + +impl PrecompileSet for HydraDXPrecompiles +where + R: pallet_evm::Config + pallet_currencies::Config, + R::RuntimeCall: Dispatchable + GetDispatchInfo + Decode, + ::RuntimeOrigin: From>, + MultiCurrencyPrecompile: Precompile, +{ + fn execute(&self, handle: &mut impl PrecompileHandle) -> Option { + let address = handle.code_address(); + + if address == DISPATCH_ADDR { + Some(pallet_evm_precompile_dispatch::Dispatch::::execute(handle)) + } else if is_asset_address(address) { + Some(MultiCurrencyPrecompile::::execute(handle)) + } else { + None + } + } + + fn is_precompile(&self, address: H160) -> bool { + address == DISPATCH_ADDR || is_asset_address(address) + } +} + +// This is a reimplementation of the upstream u64->H160 conversion +// function, made `const` to make our precompile address `const`s a +// bit cleaner. It can be removed when upstream has a const conversion +// function. +pub const fn addr(a: u64) -> H160 { + let b = a.to_be_bytes(); + H160([ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7], + ]) +} + +#[must_use] +pub fn error>>(text: T) -> PrecompileFailure { + PrecompileFailure::Error { + exit_status: ExitError::Other(text.into()), + } +} + +#[must_use] +pub fn revert(output: impl AsRef<[u8]>) -> PrecompileFailure { + PrecompileFailure::Revert { + exit_status: ExitRevert::Reverted, + output: output.as_ref().to_owned(), + } +} + +#[must_use] +pub fn succeed(output: impl AsRef<[u8]>) -> PrecompileOutput { + PrecompileOutput { + exit_status: ExitSucceed::Returned, + output: output.as_ref().to_owned(), + } +} + +pub struct Output; + +impl Output { + pub fn encode_bool(b: bool) -> Vec { + ethabi::encode(&[Token::Bool(b)]) + } + + pub fn encode_uint(b: T) -> Vec + where + U256: From, + { + ethabi::encode(&[Token::Uint(U256::from(b))]) + } + + pub fn encode_uint_tuple(b: Vec) -> Vec + where + U256: From, + { + ethabi::encode(&[Token::Tuple(b.into_iter().map(U256::from).map(Token::Uint).collect())]) + } + + pub fn encode_uint_array(b: Vec) -> Vec + where + U256: From, + { + ethabi::encode(&[Token::Array(b.into_iter().map(U256::from).map(Token::Uint).collect())]) + } + + pub fn encode_bytes(b: &[u8]) -> Vec { + ethabi::encode(&[Token::Bytes(b.to_vec())]) + } + + pub fn encode_fixed_bytes(b: &[u8]) -> Vec { + ethabi::encode(&[Token::FixedBytes(b.to_vec())]) + } + + pub fn encode_address(b: H160) -> Vec { + ethabi::encode(&[Token::Address(b)]) + } + + pub fn encode_address_tuple(b: Vec) -> Vec { + ethabi::encode(&[Token::Tuple(b.into_iter().map(Token::Address).collect())]) + } + + pub fn encode_address_array(b: Vec) -> Vec { + ethabi::encode(&[Token::Array(b.into_iter().map(Token::Address).collect())]) + } +} + +/// The `bytes`/`string` type of Solidity. +/// It is different from `Vec` which will be serialized with padding for each `u8` element +/// of the array, while `Bytes` is tightly packed. +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct Bytes(pub Vec); + +impl Bytes { + /// Interpret as `bytes`. + pub fn as_bytes(&self) -> &[u8] { + &self.0 + } + + /// Interpret as `string`. + /// Can fail if the string is not valid UTF8. + pub fn as_str(&self) -> Result<&str, sp_std::str::Utf8Error> { + sp_std::str::from_utf8(&self.0) + } +} + +impl From<&[u8]> for Bytes { + fn from(a: &[u8]) -> Self { + Self(a.to_owned()) + } +} + +impl From<&str> for Bytes { + fn from(a: &str) -> Self { + a.as_bytes().into() + } +} + +impl From for Vec { + fn from(val: Bytes) -> Self { + val.0 + } +} diff --git a/runtime/hydradx/src/evm/precompiles/multicurrency.rs b/runtime/hydradx/src/evm/precompiles/multicurrency.rs new file mode 100644 index 000000000..457cf7dcc --- /dev/null +++ b/runtime/hydradx/src/evm/precompiles/multicurrency.rs @@ -0,0 +1,250 @@ +// : $$\ $$\ $$\ $$$$$$$\ $$\ $$\ +// !YJJ^ $$ | $$ | $$ | $$ __$$\ $$ | $$ | +// 7B5. ~B5^ $$ | $$ |$$\ $$\ $$$$$$$ | $$$$$$\ $$$$$$\ $$ | $$ |\$$\ $$ | +// .?B@G ~@@P~ $$$$$$$$ |$$ | $$ |$$ __$$ |$$ __$$\ \____$$\ $$ | $$ | \$$$$ / +// :?#@@@Y .&@@@P!. $$ __$$ |$$ | $$ |$$ / $$ |$$ | \__|$$$$$$$ |$$ | $$ | $$ $$< +// ^?J^7P&@@! .5@@#Y~!J!. $$ | $$ |$$ | $$ |$$ | $$ |$$ | $$ __$$ |$$ | $$ |$$ /\$$\ +// ^JJ!. :!J5^ ?5?^ ^?Y7. $$ | $$ |\$$$$$$$ |\$$$$$$$ |$$ | \$$$$$$$ |$$$$$$$ |$$ / $$ | +// ~PP: 7#B5!. :?P#G: 7G?. \__| \__| \____$$ | \_______|\__| \_______|\_______/ \__| \__| +// .!P@G 7@@@#Y^ .!P@@@#. ~@&J: $$\ $$ | +// !&@@J :&@@@@P. !&@@@@5 #@@P. \$$$$$$ | +// :J##: Y@@&P! :JB@@&~ ?@G! \______/ +// .?P!.?GY7: .. . ^?PP^:JP~ +// .7Y7. .!YGP^ ?BP?^ ^JJ^ This file is part of https://github.com/galacticcouncil/HydraDX-node +// .!Y7Y#@@#: ?@@@G?JJ^ Built with <3 for decentralisation. +// !G@@@Y .&@@&J: +// ^5@#. 7@#?. Copyright (C) 2021-2023 Intergalactic, Limited (GIB). +// :5P^.?G7. SPDX-License-Identifier: Apache-2.0 +// :?Y! Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// http://www.apache.org/licenses/LICENSE-2.0 + +use frame_support::log; + +use crate::{ + evm::{ + precompiles::{ + erc20_mapping::{Erc20Mapping, HydraErc20Mapping}, + handle::{EvmDataWriter, FunctionModifier, PrecompileHandleExt}, + substrate::RuntimeHelper, + succeed, Address, Output, + }, + ExtendedAddressMapping, + }, + Currencies, +}; +use codec::EncodeLike; +use frame_support::traits::OriginTrait; +use hydradx_traits::InspectRegistry; +use num_enum::{IntoPrimitive, TryFromPrimitive}; +use orml_traits::{MultiCurrency as MultiCurrencyT, MultiCurrency}; +use pallet_evm::{AddressMapping, ExitRevert, Precompile, PrecompileFailure, PrecompileHandle, PrecompileResult}; +use primitive_types::H160; +use primitives::{AssetId, Balance}; +use sp_runtime::{traits::Dispatchable, RuntimeDebug}; +use sp_std::{marker::PhantomData, prelude::*}; + +#[module_evm_utility_macro::generate_function_selector] +#[derive(RuntimeDebug, Eq, PartialEq, TryFromPrimitive, IntoPrimitive)] +#[repr(u32)] +pub enum Action { + Name = "name()", + Symbol = "symbol()", + Decimals = "decimals()", + TotalSupply = "totalSupply()", + BalanceOf = "balanceOf(address)", + Allowance = "allowance(address,address)", + Transfer = "transfer(address,uint256)", + Approve = "approve(address,uint256)", + TransferFrom = "transferFrom(address,address,uint256)", +} +pub struct MultiCurrencyPrecompile(PhantomData); + +impl Precompile for MultiCurrencyPrecompile +where + Runtime: frame_system::Config + pallet_evm::Config + pallet_asset_registry::Config + pallet_currencies::Config, + AssetId: EncodeLike<::AssetId>, + <::RuntimeCall as Dispatchable>::RuntimeOrigin: OriginTrait, + ::AssetId: core::convert::From, + Currencies: MultiCurrency, + pallet_currencies::Pallet: MultiCurrency, + ::AccountId: core::convert::From, + <::RuntimeCall as Dispatchable>::RuntimeOrigin: OriginTrait, +{ + fn execute(handle: &mut impl PrecompileHandle) -> pallet_evm::PrecompileResult { + let address = handle.code_address(); + if let Some(asset_id) = HydraErc20Mapping::decode_evm_address(address) { + log::debug!(target: "evm", "multicurrency: currency id: {:?}", asset_id); + + let selector = match handle.read_selector() { + Ok(selector) => selector, + Err(e) => return Err(e), + }; + + handle.check_function_modifier(match selector { + Action::Transfer => FunctionModifier::NonPayable, + _ => FunctionModifier::View, + })?; + + return match selector { + Action::Name => Self::name(asset_id, handle), + Action::Symbol => Self::symbol(asset_id, handle), + Action::Decimals => Self::decimals(asset_id, handle), + Action::TotalSupply => Self::total_supply(asset_id, handle), + Action::BalanceOf => Self::balance_of(asset_id, handle), + Action::Transfer => Self::transfer(asset_id, handle), + Action::Allowance => Self::not_supported(asset_id, handle), + Action::Approve => Self::not_supported(asset_id, handle), + Action::TransferFrom => Self::not_supported(asset_id, handle), + }; + } + Err(PrecompileFailure::Revert { + exit_status: ExitRevert::Reverted, + output: "invalid currency id".into(), + }) + } +} + +impl MultiCurrencyPrecompile +where + Runtime: frame_system::Config + pallet_evm::Config + pallet_asset_registry::Config + pallet_currencies::Config, + AssetId: EncodeLike<::AssetId>, + ::AssetId: core::convert::From, + Currencies: MultiCurrency, + pallet_currencies::Pallet: MultiCurrency, + ::AccountId: core::convert::From, + <::RuntimeCall as Dispatchable>::RuntimeOrigin: OriginTrait, +{ + fn name(asset_id: AssetId, handle: &mut impl PrecompileHandle) -> PrecompileResult { + handle.record_cost(RuntimeHelper::::db_read_gas_cost())?; + + // Parse input + let input = handle.read_input()?; + input.expect_arguments(0)?; + + match >::asset_name(asset_id.into()) { + Some(name) => { + log::debug!(target: "evm", "multicurrency: symbol: {:?}", name); + + let encoded = Output::encode_bytes(name.as_slice()); + + Ok(succeed(encoded)) + } + None => Err(PrecompileFailure::Error { + exit_status: pallet_evm::ExitError::Other("Non-existing asset.".into()), + }), + } + } + + fn symbol(asset_id: AssetId, handle: &mut impl PrecompileHandle) -> PrecompileResult { + handle.record_cost(RuntimeHelper::::db_read_gas_cost())?; + + // Parse input + let input = handle.read_input()?; + input.expect_arguments(0)?; + + match >::asset_symbol(asset_id.into()) { + Some(symbol) => { + log::debug!(target: "evm", "multicurrency: name: {:?}", symbol); + + let encoded = Output::encode_bytes(symbol.as_slice()); + + Ok(succeed(encoded)) + } + None => Err(PrecompileFailure::Error { + exit_status: pallet_evm::ExitError::Other("Non-existing asset.".into()), + }), + } + } + + fn decimals(asset_id: AssetId, handle: &mut impl PrecompileHandle) -> PrecompileResult { + handle.record_cost(RuntimeHelper::::db_read_gas_cost())?; + + // Parse input + let input = handle.read_input()?; + input.expect_arguments(0)?; + + match >::decimals(asset_id.into()) { + Some(decimals) => { + log::debug!(target: "evm", "multicurrency: decimals: {:?}", decimals); + + let encoded = Output::encode_uint::(decimals); + + Ok(succeed(encoded)) + } + None => Err(PrecompileFailure::Error { + exit_status: pallet_evm::ExitError::Other("Non-existing asset.".into()), + }), + } + } + + fn total_supply(asset_id: AssetId, handle: &mut impl PrecompileHandle) -> PrecompileResult { + handle.record_cost(RuntimeHelper::::db_read_gas_cost())?; + + // Parse input + let input = handle.read_input()?; + input.expect_arguments(0)?; + + let total_issuance = Currencies::total_issuance(asset_id); + + log::debug!(target: "evm", "multicurrency: totalSupply: {:?}", total_issuance); + + let encoded = Output::encode_uint::(total_issuance); + + Ok(succeed(encoded)) + } + + fn balance_of(asset_id: AssetId, handle: &mut impl PrecompileHandle) -> PrecompileResult { + handle.record_cost(RuntimeHelper::::db_read_gas_cost())?; + + // Parse input + let mut input = handle.read_input()?; + input.expect_arguments(1)?; + + let owner: H160 = input.read::
()?.into(); + let who: Runtime::AccountId = ExtendedAddressMapping::into_account_id(owner).into(); //TODO: use pallet? + + let free_balance = Currencies::free_balance(asset_id, &who); + + log::debug!(target: "evm", "multicurrency: balanceOf: {:?}", free_balance); + + let encoded = Output::encode_uint::(free_balance); + + Ok(succeed(encoded)) + } + + fn transfer(asset_id: AssetId, handle: &mut impl PrecompileHandle) -> PrecompileResult { + handle.record_cost(RuntimeHelper::::db_read_gas_cost())?; + + // Parse input + let mut input = handle.read_input()?; + input.expect_arguments(2)?; + + let to: H160 = input.read::
()?.into(); + let amount = input.read::()?; + + let origin = ExtendedAddressMapping::into_account_id(handle.context().caller); + let to = ExtendedAddressMapping::into_account_id(to); + + log::debug!(target: "evm", "multicurrency: transfer from: {:?}, to: {:?}, amount: {:?}", origin, to, amount); + + as MultiCurrency>::transfer( + asset_id, + &(>::into(origin)), + &(>::into(to)), + amount, + ) + .map_err(|e| PrecompileFailure::Revert { + exit_status: ExitRevert::Reverted, + output: Into::<&str>::into(e).as_bytes().to_vec(), + })?; + + Ok(succeed(EvmDataWriter::new().write(true).build())) + } + + fn not_supported(_: AssetId, _: &mut impl PrecompileHandle) -> PrecompileResult { + Err(PrecompileFailure::Error { + exit_status: pallet_evm::ExitError::Other("not supported".into()), + }) + } +} diff --git a/runtime/hydradx/src/evm/precompiles/substrate.rs b/runtime/hydradx/src/evm/precompiles/substrate.rs new file mode 100644 index 000000000..cdf55d602 --- /dev/null +++ b/runtime/hydradx/src/evm/precompiles/substrate.rs @@ -0,0 +1,107 @@ +// : $$\ $$\ $$\ $$$$$$$\ $$\ $$\ +// !YJJ^ $$ | $$ | $$ | $$ __$$\ $$ | $$ | +// 7B5. ~B5^ $$ | $$ |$$\ $$\ $$$$$$$ | $$$$$$\ $$$$$$\ $$ | $$ |\$$\ $$ | +// .?B@G ~@@P~ $$$$$$$$ |$$ | $$ |$$ __$$ |$$ __$$\ \____$$\ $$ | $$ | \$$$$ / +// :?#@@@Y .&@@@P!. $$ __$$ |$$ | $$ |$$ / $$ |$$ | \__|$$$$$$$ |$$ | $$ | $$ $$< +// ^?J^7P&@@! .5@@#Y~!J!. $$ | $$ |$$ | $$ |$$ | $$ |$$ | $$ __$$ |$$ | $$ |$$ /\$$\ +// ^JJ!. :!J5^ ?5?^ ^?Y7. $$ | $$ |\$$$$$$$ |\$$$$$$$ |$$ | \$$$$$$$ |$$$$$$$ |$$ / $$ | +// ~PP: 7#B5!. :?P#G: 7G?. \__| \__| \____$$ | \_______|\__| \_______|\_______/ \__| \__| +// .!P@G 7@@@#Y^ .!P@@@#. ~@&J: $$\ $$ | +// !&@@J :&@@@@P. !&@@@@5 #@@P. \$$$$$$ | +// :J##: Y@@&P! :JB@@&~ ?@G! \______/ +// .?P!.?GY7: .. . ^?PP^:JP~ +// .7Y7. .!YGP^ ?BP?^ ^JJ^ This file is part of https://github.com/galacticcouncil/HydraDX-node +// .!Y7Y#@@#: ?@@@G?JJ^ Built with <3 for decentralisation. +// !G@@@Y .&@@&J: +// ^5@#. 7@#?. Copyright (C) 2021-2023 Intergalactic, Limited (GIB). +// :5P^.?G7. SPDX-License-Identifier: Apache-2.0 +// :?Y! Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// http://www.apache.org/licenses/LICENSE-2.0 + +//! Utils related to Substrate features: +//! - Substrate call dispatch. +//! - Substrate DB read and write costs + +use crate::evm::precompiles::{revert, EvmResult}; +use smallvec::alloc; +use { + core::marker::PhantomData, + frame_support::{ + dispatch::{Dispatchable, GetDispatchInfo, PostDispatchInfo}, + traits::Get, + weights::Weight, + }, + pallet_evm::GasWeightMapping, + pallet_evm::{ExitError, PrecompileFailure, PrecompileHandle}, +}; + +/// Helper functions requiring a Substrate runtime. +/// This runtime must of course implement `pallet_evm::Config`. +#[derive(Clone, Copy, Debug)] +pub struct RuntimeHelper(PhantomData); + +impl RuntimeHelper +where + Runtime: pallet_evm::Config, + Runtime::RuntimeCall: Dispatchable + GetDispatchInfo, +{ + /// Try to dispatch a Substrate call. + /// Return an error if there are not enough gas, or if the call fails. + /// If successful returns the used gas using the Runtime GasWeightMapping. + pub fn try_dispatch( + handle: &mut impl PrecompileHandle, + origin: ::RuntimeOrigin, + call: RuntimeCall, + ) -> EvmResult<()> + where + Runtime::RuntimeCall: From, + { + let call = Runtime::RuntimeCall::from(call); + let dispatch_info = call.get_dispatch_info(); + + // Make sure there is enough gas. + let remaining_gas = handle.remaining_gas(); + let required_gas = Runtime::GasWeightMapping::weight_to_gas(dispatch_info.weight); + if required_gas > remaining_gas { + return Err(PrecompileFailure::Error { + exit_status: ExitError::OutOfGas, + }); + } + + // Dispatch call. + // It may be possible to not record gas cost if the call returns Pays::No. + // However while Substrate handle checking weight while not making the sender pay for it, + // the EVM doesn't. It seems this safer to always record the costs to avoid unmetered + // computations. + let used_weight = call + .dispatch(origin) + .map_err(|e| revert(alloc::format!("Dispatched call failed with error: {:?}", e)))? + .actual_weight; + + let used_gas = Runtime::GasWeightMapping::weight_to_gas(used_weight.unwrap_or(dispatch_info.weight)); + + handle.record_cost(used_gas)?; + + Ok(()) + } +} + +impl RuntimeHelper +where + Runtime: pallet_evm::Config + frame_system::Config, +{ + /// Cost of a Substrate DB write in gas. + pub fn db_write_gas_cost() -> u64 { + ::GasWeightMapping::weight_to_gas(Weight::from_ref_time( + ::DbWeight::get().write, + )) + } + + /// Cost of a Substrate DB read in gas. + pub fn db_read_gas_cost() -> u64 { + ::GasWeightMapping::weight_to_gas(Weight::from_ref_time( + ::DbWeight::get().read, + )) + } +} diff --git a/runtime/hydradx/src/evm/precompiles/tests/erc20_mapping.rs b/runtime/hydradx/src/evm/precompiles/tests/erc20_mapping.rs new file mode 100644 index 000000000..56167a8d6 --- /dev/null +++ b/runtime/hydradx/src/evm/precompiles/tests/erc20_mapping.rs @@ -0,0 +1,69 @@ +use crate::evm::precompiles::erc20_mapping::{Erc20Mapping, HydraErc20Mapping}; +use hex_literal::hex; +use primitive_types::H160; + +macro_rules! encode { + ($asset_id:expr) => {{ + HydraErc20Mapping::encode_evm_address($asset_id).unwrap() + }}; +} + +macro_rules! decode { + ($evm_address:expr) => {{ + HydraErc20Mapping::decode_evm_address(H160::from($evm_address)).unwrap() + }}; +} + +macro_rules! decode_optional { + ($evm_address:expr) => {{ + HydraErc20Mapping::decode_evm_address(H160::from($evm_address)) + }}; +} + +#[test] +fn decode_asset_id_from_evm_address_should_work() { + assert_eq!(decode!(hex!("0000000000000000000000000000000100000000")), 0); + assert_eq!(decode!(hex!("0000000000000000000000000000000100000001")), 1); + assert_eq!(decode!(hex!("0000000000000000000000000000000100000002")), 2); + assert_eq!(decode!(hex!("0000000000000000000000000000000100000003")), 3); + assert_eq!(decode!(hex!("0000000000000000000000000000000100000009")), 9); + assert_eq!(decode!(hex!("000000000000000000000000000000010000000a")), 10); + assert_eq!(decode!(hex!("000000000000000000000000000000010000000b")), 11); + assert_eq!(decode!(hex!("00000000000000000000000000000001000000ff")), 255); + assert_eq!(decode!(hex!("00000000000000000000000000000001ffffffff")), 4294967295); +} + +#[test] +fn decode_asset_id_from_evm_address_should_not_work_with_invalid_asset_addresses() { + assert_eq!(decode_optional!(hex!("0000000000000000000000000000000200000000")), None); + assert_eq!(decode_optional!(hex!("0000000000000000000000000000000000000001")), None); + assert_eq!(decode_optional!(hex!("90000000000000000000000000000001ffffffff")), None); + assert_eq!(decode_optional!(hex!("0000000000000000000000000000001100000003")), None); + assert_eq!(decode_optional!(hex!("0000000000000000900000000000000100000003")), None); + assert_eq!(decode_optional!(hex!("7777777777777777777777777777777777777777")), None); +} + +#[test] +fn encode_asset_id_to_evm_address_should_work() { + assert_eq!(encode!(0), H160::from(hex!("0000000000000000000000000000000100000000"))); + assert_eq!(encode!(1), H160::from(hex!("0000000000000000000000000000000100000001"))); + assert_eq!(encode!(2), H160::from(hex!("0000000000000000000000000000000100000002"))); + assert_eq!(encode!(3), H160::from(hex!("0000000000000000000000000000000100000003"))); + assert_eq!(encode!(9), H160::from(hex!("0000000000000000000000000000000100000009"))); + assert_eq!( + encode!(10), + H160::from(hex!("000000000000000000000000000000010000000a")) + ); + assert_eq!( + encode!(11), + H160::from(hex!("000000000000000000000000000000010000000b")) + ); + assert_eq!( + encode!(255), + H160::from(hex!("00000000000000000000000000000001000000ff")) + ); + assert_eq!( + encode!(4294967295), + H160::from(hex!("00000000000000000000000000000001ffffffff")) + ); +} diff --git a/runtime/hydradx/src/evm/precompiles/tests/mod.rs b/runtime/hydradx/src/evm/precompiles/tests/mod.rs new file mode 100644 index 000000000..3fff4dca3 --- /dev/null +++ b/runtime/hydradx/src/evm/precompiles/tests/mod.rs @@ -0,0 +1 @@ +mod erc20_mapping; diff --git a/runtime/hydradx/src/lib.rs b/runtime/hydradx/src/lib.rs index 9a1bc6173..f2eaf84bc 100644 --- a/runtime/hydradx/src/lib.rs +++ b/runtime/hydradx/src/lib.rs @@ -32,6 +32,7 @@ mod migrations; pub mod weights; mod assets; +pub mod evm; mod governance; mod system; mod xcm; @@ -41,14 +42,17 @@ pub use governance::*; pub use system::*; pub use xcm::*; +use crate::sp_api_hidden_includes_construct_runtime::hidden_include::dispatch::Dispatchable; use codec::{Decode, Encode}; use sp_api::impl_runtime_apis; -use sp_core::{ConstU128, OpaqueMetadata}; +use sp_core::{ConstU128, Get, OpaqueMetadata, H160, H256, U256}; use sp_runtime::{ create_runtime_str, generic, impl_opaque_keys, - traits::{AccountIdConversion, BlakeTwo256, Block as BlockT}, - transaction_validity::{TransactionSource, TransactionValidity}, - ApplyExtrinsicResult, + traits::{ + AccountIdConversion, BlakeTwo256, Block as BlockT, DispatchInfoOf, PostDispatchInfoOf, UniqueSaturatedInto, + }, + transaction_validity::{TransactionSource, TransactionValidity, TransactionValidityError}, + ApplyExtrinsicResult, Permill, }; use sp_std::convert::From; @@ -59,14 +63,15 @@ use sp_version::RuntimeVersion; // A few exports that help ease life for downstream crates. use frame_support::{construct_runtime, weights::Weight}; pub use hex_literal::hex; +/// Import HydraDX pallets +pub use pallet_claims; +use pallet_ethereum::{Transaction as EthereumTransaction, TransactionStatus}; +use pallet_evm::{Account as EVMAccount, FeeCalculator, Runner}; pub use primitives::{ AccountId, Amount, AssetId, Balance, BlockNumber, CollectionId, Hash, Index, ItemId, Price, Signature, }; pub use sp_consensus_aura::sr25519::AuthorityId as AuraId; -/// Import HydraDX pallets -pub use pallet_claims; - /// Opaque types. These are used by the CLI to instantiate machinery that don't need to know /// the specifics of the runtime. They can then be made to be agnostic over specific formats /// of data like extrinsics, allowing for them to continue syncing the network through upgrades @@ -168,6 +173,11 @@ construct_runtime!( Currencies: pallet_currencies = 79, Vesting: orml_vesting = 81, + // Frontier + EVM: pallet_evm = 90, + EVMChainId: pallet_evm_chain_id = 91, + Ethereum: pallet_ethereum = 92, + // Parachain ParachainSystem: cumulus_pallet_parachain_system exclude_parts { Config } = 103, ParachainInfo: parachain_info = 105, @@ -226,9 +236,10 @@ pub type SignedExtra = ( pallet_claims::ValidateClaim, ); /// 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; +pub type CheckedExtrinsic = fp_self_contained::CheckedExtrinsic; /// Executive: handles dispatch to the various modules. pub type Executive = frame_executive::Executive< Runtime, @@ -373,6 +384,132 @@ impl_runtime_apis! { } } + // Frontier RPC support + 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 mut config = ::config().clone(); + config.estimate = estimate; + + 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, + ) + .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 { + Err(sp_runtime::DispatchError::Other( + "Creating contracts is not currently supported", + )) + } + + 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 { + RuntimeCall::Ethereum(pallet_ethereum::Call::transact { transaction }) => Some(transaction), + _ => None, + }) + .collect::>() + } + + fn elasticity() -> Option { + None + } + + fn gas_limit_multiplier_support() {} + } + + impl fp_rpc::ConvertTransactionRuntimeApi for Runtime { + fn convert_transaction(transaction: EthereumTransaction) -> ::Extrinsic { + UncheckedExtrinsic::new_unsigned(pallet_ethereum::Call::::transact { transaction }.into()) + } + } + #[cfg(feature = "runtime-benchmarks")] impl frame_benchmarking::Benchmark for Runtime { fn benchmark_metadata(extra: bool) -> ( @@ -530,3 +667,74 @@ cumulus_pallet_parachain_system::register_validate_block! { BlockExecutor = cumulus_pallet_aura_ext::BlockExecutor::, CheckInherents = CheckInherents, } + +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, + } + } +} + +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) -> sp_runtime::OpaqueExtrinsic { + let extrinsic = + UncheckedExtrinsic::new_unsigned(pallet_ethereum::Call::::transact { transaction }.into()); + let encoded = extrinsic.encode(); + sp_runtime::OpaqueExtrinsic::decode(&mut &encoded[..]).expect("Encoded extrinsic is always valid") + } +} diff --git a/runtime/hydradx/src/migrations.rs b/runtime/hydradx/src/migrations.rs index 7bb4291fb..969c2ba36 100644 --- a/runtime/hydradx/src/migrations.rs +++ b/runtime/hydradx/src/migrations.rs @@ -1,8 +1,12 @@ -use frame_support::{traits::OnRuntimeUpgrade, weights::Weight}; -#[cfg(feature = "try-runtime")] -use sp_std::prelude::*; +#![allow(unused_imports)] +use crate::Vec; +use frame_support::{codec::alloc::vec, traits::OnRuntimeUpgrade, weights::Weight}; pub struct OnRuntimeUpgradeMigration; + +use crate::Runtime; +use pallet_evm_chain_id::ChainId; + impl OnRuntimeUpgrade for OnRuntimeUpgradeMigration { #[cfg(feature = "try-runtime")] fn pre_upgrade() -> Result, &'static str> { @@ -10,7 +14,9 @@ impl OnRuntimeUpgrade for OnRuntimeUpgradeMigration { } fn on_runtime_upgrade() -> Weight { - Weight::zero() + let evm_id: u64 = 222_222u64; + ChainId::::put(evm_id); + ::DbWeight::get().reads_writes(0, 1) } #[cfg(feature = "try-runtime")] diff --git a/traits/Cargo.toml b/traits/Cargo.toml index 2842daea3..15e5cfa74 100644 --- a/traits/Cargo.toml +++ b/traits/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "hydradx-traits" -version = "2.7.1" +version = "2.8.0" description = "Shared traits" authors = ["GalacticCouncil"] edition = "2021" diff --git a/traits/src/registry.rs b/traits/src/registry.rs index 76f21f972..b2b25d1bd 100644 --- a/traits/src/registry.rs +++ b/traits/src/registry.rs @@ -1,5 +1,4 @@ use sp_std::vec::Vec; - pub trait Registry { fn exists(name: AssetId) -> bool; @@ -17,7 +16,6 @@ pub trait Registry { } } } - // Use CreateRegistry if possible pub trait ShareTokenRegistry: Registry { fn retrieve_shared_asset(name: &AssetName, assets: &[AssetId]) -> Result; @@ -44,6 +42,8 @@ pub trait ShareTokenRegistry: Registry { fn exists(asset_id: AssetId) -> bool; fn decimals(asset_id: AssetId) -> Option; + fn asset_name(asset_id: AssetId) -> Option>; + fn asset_symbol(asset_id: AssetId) -> Option>; } #[derive(Eq, PartialEq, Copy, Clone)]