--- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -13,8 +13,8 @@ [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" && \ nvm install v16.2.0 && \ npm install -g yarn && \ - rustup toolchain install nightly-2021-06-28 && \ - rustup default nightly-2021-06-28 && \ + rustup toolchain install nightly-2021-11-11 && \ + rustup default nightly-2021-11-11 && \ rustup target add wasm32-unknown-unknown && \ rustup component add rustfmt clippy && \ cargo install cargo-expand cargo-edit cargo-contract --- a/.env +++ b/.env @@ -1,4 +1,4 @@ -RUST_TOOLCHAIN=nightly-2021-06-28 +RUST_TOOLCHAIN=nightly-2021-11-11 RUST_C=1.55.0-nightly POLKA_VERSION=v0.9.12 UNIQUE_BRANCH=develop --- a/.maintain/frame-weight-template.hbs +++ b/.maintain/frame-weight-template.hbs @@ -14,6 +14,7 @@ #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] #![allow(unused_imports)] +#![allow(clippy::unnecessary_cast)] use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; use sp_std::marker::PhantomData; --- a/Cargo.lock +++ b/Cargo.lock @@ -117,9 +117,9 @@ [[package]] name = "anyhow" -version = "1.0.44" +version = "1.0.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61604a8f862e1d5c3229fdd78f8b02c68dcf73a4c4b05fd636d12240aaa242c1" +checksum = "62e1f47f7dc0422027a4e370dd4548d4d66b26782e513e98dca1e689e058a80e" [[package]] name = "approx" @@ -259,9 +259,9 @@ [[package]] name = "async-process" -version = "1.2.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b21b63ab5a0db0369deb913540af2892750e42d949faacc7a61495ac418a1692" +checksum = "83137067e3a2a6a06d67168e49e68a0957d215410473a740cea95a2425c0b7c6" dependencies = [ "async-io", "blocking", @@ -362,9 +362,9 @@ [[package]] name = "atomic" -version = "0.5.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3410529e8288c463bedb5930f82833bc0c90e5d2fe639a56582a4d09220b281" +checksum = "b88d82667eca772c4aa12f0f1348b3ae643424c8876448f3f7bd5787032e234c" dependencies = [ "autocfg", ] @@ -460,7 +460,7 @@ dependencies = [ "beefy-primitives", "fnv", - "futures 0.3.17", + "futures 0.3.18", "log", "parity-scale-codec", "parking_lot 0.11.2", @@ -488,7 +488,7 @@ dependencies = [ "beefy-gadget", "beefy-primitives", - "futures 0.3.17", + "futures 0.3.18", "jsonrpc-core", "jsonrpc-core-client", "jsonrpc-derive", @@ -531,9 +531,9 @@ [[package]] name = "bindgen" -version = "0.59.1" +version = "0.59.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "453c49e5950bb0eb63bb3df640e31618846c89d5b7faa54040d76e98e0134375" +checksum = "2bd2a9a458e8f4304c52c43ebb0cfbd520289f8379a52e329a38afda99bf8eb8" dependencies = [ "bitflags", "cexpr", @@ -556,24 +556,12 @@ [[package]] name = "bitvec" -version = "0.19.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8942c8d352ae1838c9dda0b0ca2ab657696ef2232a20147cf1b30ae1a9cb4321" -dependencies = [ - "funty", - "radium 0.5.3", - "tap", - "wyz", -] - -[[package]] -name = "bitvec" version = "0.20.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7774144344a4faa177370406a7ff5f1da24303817368584c6206c8303eb07848" dependencies = [ "funty", - "radium 0.6.2", + "radium", "tap", "wyz", ] @@ -675,9 +663,9 @@ [[package]] name = "blocking" -version = "1.0.2" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5e170dbede1f740736619b776d7251cb1b9095c435c34d8ca9f57fcd2f335e9" +checksum = "046e47d4b2d391b1f6f8b407b1deb8dee56c1852ccd868becf2710f601b5f427" dependencies = [ "async-channel", "async-task", @@ -729,11 +717,11 @@ version = "0.1.0" source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.12#5feed981cf0fe671447eabaa9c0d235a8dd0003e" dependencies = [ - "bitvec 0.20.4", + "bitvec", "bp-runtime", "frame-support", "frame-system", - "impl-trait-for-tuples 0.2.1", + "impl-trait-for-tuples", "parity-scale-codec", "scale-info", "serde", @@ -971,18 +959,18 @@ [[package]] name = "cc" -version = "1.0.71" +version = "1.0.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79c2681d6594606957bbb8631c4b90a7fcaaa72cdb714743a437b156d6a7eedd" +checksum = "22a9137b95ea06864e018375b72adfb7db6e6f68cfc8df5a04d00288050485ee" dependencies = [ "jobserver", ] [[package]] name = "cexpr" -version = "0.5.0" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db507a7679252d2276ed0dd8113c6875ec56d3089f9225b2b42c30cc1f8e5c89" +checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" dependencies = [ "nom", ] @@ -1080,7 +1068,7 @@ dependencies = [ "glob", "libc", - "libloading 0.7.1", + "libloading 0.7.2", ] [[package]] @@ -1146,9 +1134,9 @@ [[package]] name = "cpp_demangle" -version = "0.3.3" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ea47428dc9d2237f3c6bc134472edfd63ebba0af932e783506dcfd66f10d18a" +checksum = "931ab2a3e6330a07900b8e7ca4e106cdcbb93f2b9a52df55e54ee53d8305b55d" dependencies = [ "cfg-if 1.0.0", ] @@ -1263,9 +1251,9 @@ [[package]] name = "crc32fast" -version = "1.2.1" +version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81156fece84ab6a9f2afdb109ce3ae577e42b1228441eded99bd77f627953b1a" +checksum = "3825b1e8580894917dc4468cb634a1b4e9745fddc854edad72d9c04644c0319f" dependencies = [ "cfg-if 1.0.0", ] @@ -1392,7 +1380,7 @@ [[package]] name = "cumulus-client-cli" version = "0.1.0" -source = "git+https://github.com/paritytech/cumulus.git?branch=polkadot-v0.9.12#f5926c2f50df73bf36171b138241437131d76fff" +source = "git+https://github.com/paritytech/cumulus.git?branch=polkadot-v0.9.12#c02514d8cb66d6860e597f75d53ca07119dbbf32" dependencies = [ "sc-cli", "sc-service", @@ -1402,12 +1390,12 @@ [[package]] name = "cumulus-client-collator" version = "0.1.0" -source = "git+https://github.com/paritytech/cumulus.git?branch=polkadot-v0.9.12#f5926c2f50df73bf36171b138241437131d76fff" +source = "git+https://github.com/paritytech/cumulus.git?branch=polkadot-v0.9.12#c02514d8cb66d6860e597f75d53ca07119dbbf32" dependencies = [ "cumulus-client-consensus-common", "cumulus-client-network", "cumulus-primitives-core", - "futures 0.3.17", + "futures 0.3.18", "parity-scale-codec", "parking_lot 0.10.2", "polkadot-node-primitives", @@ -1425,12 +1413,12 @@ [[package]] name = "cumulus-client-consensus-aura" version = "0.1.0" -source = "git+https://github.com/paritytech/cumulus.git?branch=polkadot-v0.9.12#f5926c2f50df73bf36171b138241437131d76fff" +source = "git+https://github.com/paritytech/cumulus.git?branch=polkadot-v0.9.12#c02514d8cb66d6860e597f75d53ca07119dbbf32" dependencies = [ "async-trait", "cumulus-client-consensus-common", "cumulus-primitives-core", - "futures 0.3.17", + "futures 0.3.18", "parity-scale-codec", "polkadot-client", "sc-client-api", @@ -1455,11 +1443,11 @@ [[package]] name = "cumulus-client-consensus-common" version = "0.1.0" -source = "git+https://github.com/paritytech/cumulus.git?branch=polkadot-v0.9.12#f5926c2f50df73bf36171b138241437131d76fff" +source = "git+https://github.com/paritytech/cumulus.git?branch=polkadot-v0.9.12#c02514d8cb66d6860e597f75d53ca07119dbbf32" dependencies = [ "async-trait", "dyn-clone", - "futures 0.3.17", + "futures 0.3.18", "parity-scale-codec", "polkadot-primitives", "sc-client-api", @@ -1475,10 +1463,10 @@ [[package]] name = "cumulus-client-network" version = "0.1.0" -source = "git+https://github.com/paritytech/cumulus.git?branch=polkadot-v0.9.12#f5926c2f50df73bf36171b138241437131d76fff" +source = "git+https://github.com/paritytech/cumulus.git?branch=polkadot-v0.9.12#c02514d8cb66d6860e597f75d53ca07119dbbf32" dependencies = [ "derive_more", - "futures 0.3.17", + "futures 0.3.18", "futures-timer 3.0.2", "parity-scale-codec", "parking_lot 0.10.2", @@ -1498,10 +1486,10 @@ [[package]] name = "cumulus-client-pov-recovery" version = "0.1.0" -source = "git+https://github.com/paritytech/cumulus.git?branch=polkadot-v0.9.12#f5926c2f50df73bf36171b138241437131d76fff" +source = "git+https://github.com/paritytech/cumulus.git?branch=polkadot-v0.9.12#c02514d8cb66d6860e597f75d53ca07119dbbf32" dependencies = [ "cumulus-primitives-core", - "futures 0.3.17", + "futures 0.3.18", "futures-timer 3.0.2", "parity-scale-codec", "polkadot-node-primitives", @@ -1521,7 +1509,7 @@ [[package]] name = "cumulus-client-service" version = "0.1.0" -source = "git+https://github.com/paritytech/cumulus.git?branch=polkadot-v0.9.12#f5926c2f50df73bf36171b138241437131d76fff" +source = "git+https://github.com/paritytech/cumulus.git?branch=polkadot-v0.9.12#c02514d8cb66d6860e597f75d53ca07119dbbf32" dependencies = [ "cumulus-client-collator", "cumulus-client-consensus-common", @@ -1550,7 +1538,7 @@ [[package]] name = "cumulus-pallet-aura-ext" version = "0.1.0" -source = "git+https://github.com/paritytech/cumulus.git?branch=polkadot-v0.9.12#f5926c2f50df73bf36171b138241437131d76fff" +source = "git+https://github.com/paritytech/cumulus.git?branch=polkadot-v0.9.12#c02514d8cb66d6860e597f75d53ca07119dbbf32" dependencies = [ "frame-executive", "frame-support", @@ -1568,7 +1556,7 @@ [[package]] name = "cumulus-pallet-dmp-queue" version = "0.1.0" -source = "git+https://github.com/paritytech/cumulus.git?branch=polkadot-v0.9.12#f5926c2f50df73bf36171b138241437131d76fff" +source = "git+https://github.com/paritytech/cumulus.git?branch=polkadot-v0.9.12#c02514d8cb66d6860e597f75d53ca07119dbbf32" dependencies = [ "cumulus-primitives-core", "frame-support", @@ -1586,7 +1574,7 @@ [[package]] name = "cumulus-pallet-parachain-system" version = "0.1.0" -source = "git+https://github.com/paritytech/cumulus.git?branch=polkadot-v0.9.12#f5926c2f50df73bf36171b138241437131d76fff" +source = "git+https://github.com/paritytech/cumulus.git?branch=polkadot-v0.9.12#c02514d8cb66d6860e597f75d53ca07119dbbf32" dependencies = [ "cumulus-pallet-parachain-system-proc-macro", "cumulus-primitives-core", @@ -1615,7 +1603,7 @@ [[package]] name = "cumulus-pallet-parachain-system-proc-macro" version = "0.1.0" -source = "git+https://github.com/paritytech/cumulus.git?branch=polkadot-v0.9.12#f5926c2f50df73bf36171b138241437131d76fff" +source = "git+https://github.com/paritytech/cumulus.git?branch=polkadot-v0.9.12#c02514d8cb66d6860e597f75d53ca07119dbbf32" dependencies = [ "proc-macro-crate 1.1.0", "proc-macro2", @@ -1626,7 +1614,7 @@ [[package]] name = "cumulus-pallet-xcm" version = "0.1.0" -source = "git+https://github.com/paritytech/cumulus.git?branch=polkadot-v0.9.12#f5926c2f50df73bf36171b138241437131d76fff" +source = "git+https://github.com/paritytech/cumulus.git?branch=polkadot-v0.9.12#c02514d8cb66d6860e597f75d53ca07119dbbf32" dependencies = [ "cumulus-primitives-core", "frame-support", @@ -1643,7 +1631,7 @@ [[package]] name = "cumulus-pallet-xcmp-queue" version = "0.1.0" -source = "git+https://github.com/paritytech/cumulus.git?branch=polkadot-v0.9.12#f5926c2f50df73bf36171b138241437131d76fff" +source = "git+https://github.com/paritytech/cumulus.git?branch=polkadot-v0.9.12#c02514d8cb66d6860e597f75d53ca07119dbbf32" dependencies = [ "cumulus-primitives-core", "frame-support", @@ -1661,10 +1649,10 @@ [[package]] name = "cumulus-primitives-core" version = "0.1.0" -source = "git+https://github.com/paritytech/cumulus.git?branch=polkadot-v0.9.12#f5926c2f50df73bf36171b138241437131d76fff" +source = "git+https://github.com/paritytech/cumulus.git?branch=polkadot-v0.9.12#c02514d8cb66d6860e597f75d53ca07119dbbf32" dependencies = [ "frame-support", - "impl-trait-for-tuples 0.2.1", + "impl-trait-for-tuples", "parity-scale-codec", "polkadot-core-primitives", "polkadot-parachain", @@ -1678,7 +1666,7 @@ [[package]] name = "cumulus-primitives-parachain-inherent" version = "0.1.0" -source = "git+https://github.com/paritytech/cumulus.git?branch=polkadot-v0.9.12#f5926c2f50df73bf36171b138241437131d76fff" +source = "git+https://github.com/paritytech/cumulus.git?branch=polkadot-v0.9.12#c02514d8cb66d6860e597f75d53ca07119dbbf32" dependencies = [ "async-trait", "cumulus-primitives-core", @@ -1700,7 +1688,7 @@ [[package]] name = "cumulus-primitives-timestamp" version = "0.1.0" -source = "git+https://github.com/paritytech/cumulus.git?branch=polkadot-v0.9.12#f5926c2f50df73bf36171b138241437131d76fff" +source = "git+https://github.com/paritytech/cumulus.git?branch=polkadot-v0.9.12#c02514d8cb66d6860e597f75d53ca07119dbbf32" dependencies = [ "cumulus-primitives-core", "sp-inherents", @@ -1711,7 +1699,7 @@ [[package]] name = "cumulus-primitives-utility" version = "0.1.0" -source = "git+https://github.com/paritytech/cumulus.git?branch=polkadot-v0.9.12#f5926c2f50df73bf36171b138241437131d76fff" +source = "git+https://github.com/paritytech/cumulus.git?branch=polkadot-v0.9.12#c02514d8cb66d6860e597f75d53ca07119dbbf32" dependencies = [ "cumulus-primitives-core", "frame-support", @@ -1728,7 +1716,7 @@ [[package]] name = "cumulus-test-relay-sproof-builder" version = "0.1.0" -source = "git+https://github.com/paritytech/cumulus.git?branch=polkadot-v0.9.12#f5926c2f50df73bf36171b138241437131d76fff" +source = "git+https://github.com/paritytech/cumulus.git?branch=polkadot-v0.9.12#c02514d8cb66d6860e597f75d53ca07119dbbf32" dependencies = [ "cumulus-primitives-core", "parity-scale-codec", @@ -1953,9 +1941,9 @@ [[package]] name = "ed25519" -version = "1.2.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4620d40f6d2601794401d6dd95a5cf69b6c157852539470eeda433a99b3c0efc" +checksum = "74e1069e39f1454367eb2de793ed062fac4c35c2934b76a81d90dd9abcd28816" dependencies = [ "signature", ] @@ -2111,8 +2099,9 @@ [[package]] name = "ethereum" -version = "0.9.0" -source = "git+https://github.com/purestake/ethereum?branch=joshy-scale-info#2b98173bd88c05bfeefad421d260101b9008497b" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81fb916554a4dba293ea69c69ad5653e21d770a9d0c2496b5fa0a1f5a3946d87" dependencies = [ "bytes 1.1.0", "ethereum-types", @@ -2151,11 +2140,11 @@ [[package]] name = "evm" -version = "0.30.0" -source = "git+https://github.com/uniquenetwork/evm.git?branch=precompile-output-parachain#bed08923a76339880e05df25a52c5334e9997bb2" +version = "0.33.0" +source = "git+https://github.com/uniquenetwork/evm.git?branch=unique-weights#3113ac1ced53bf27e9845107fd30901708824cc4" dependencies = [ "environmental", - "ethereum 0.9.0 (git+https://github.com/purestake/ethereum?branch=joshy-scale-info)", + "ethereum 0.10.0", "evm-core", "evm-gasometer", "evm-runtime", @@ -2172,12 +2161,12 @@ name = "evm-coder" version = "0.1.0" dependencies = [ - "ethereum 0.9.0 (git+https://github.com/purestake/ethereum?branch=joshy-scale-info)", + "ethereum 0.10.0", "evm-coder-macros", "evm-core", "hex", "hex-literal", - "impl-trait-for-tuples 0.2.1", + "impl-trait-for-tuples", "primitive-types 0.10.1", ] @@ -2196,8 +2185,8 @@ [[package]] name = "evm-core" -version = "0.30.0" -source = "git+https://github.com/uniquenetwork/evm.git?branch=precompile-output-parachain#bed08923a76339880e05df25a52c5334e9997bb2" +version = "0.33.0" +source = "git+https://github.com/uniquenetwork/evm.git?branch=unique-weights#3113ac1ced53bf27e9845107fd30901708824cc4" dependencies = [ "funty", "parity-scale-codec", @@ -2208,8 +2197,8 @@ [[package]] name = "evm-gasometer" -version = "0.30.0" -source = "git+https://github.com/uniquenetwork/evm.git?branch=precompile-output-parachain#bed08923a76339880e05df25a52c5334e9997bb2" +version = "0.33.0" +source = "git+https://github.com/uniquenetwork/evm.git?branch=unique-weights#3113ac1ced53bf27e9845107fd30901708824cc4" dependencies = [ "environmental", "evm-core", @@ -2219,8 +2208,8 @@ [[package]] name = "evm-runtime" -version = "0.30.0" -source = "git+https://github.com/uniquenetwork/evm.git?branch=precompile-output-parachain#bed08923a76339880e05df25a52c5334e9997bb2" +version = "0.33.0" +source = "git+https://github.com/uniquenetwork/evm.git?branch=unique-weights#3113ac1ced53bf27e9845107fd30901708824cc4" dependencies = [ "environmental", "evm-core", @@ -2234,7 +2223,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e43f2f1833d64e33f15592464d6fdd70f349dda7b1a53088eb83cd94014008c5" dependencies = [ - "futures 0.3.17", + "futures 0.3.18", ] [[package]] @@ -2261,14 +2250,14 @@ [[package]] name = "fc-consensus" version = "2.0.0-dev" -source = "git+https://github.com/uniquenetwork/frontier.git?branch=unique-polkadot-v0.9.12#43ce3be6274eceaf47d9664ddc71cba68a990923" +source = "git+https://github.com/uniquenetwork/frontier.git?branch=unique-polkadot-v0.9.12-weights#0134806e399412bf896f881f1e3bc284916a1432" dependencies = [ "async-trait", "derive_more", "fc-db", "fp-consensus", "fp-rpc", - "futures 0.3.17", + "futures 0.3.18", "log", "parity-scale-codec", "sc-client-api", @@ -2288,7 +2277,7 @@ [[package]] name = "fc-db" version = "2.0.0-dev" -source = "git+https://github.com/uniquenetwork/frontier.git?branch=unique-polkadot-v0.9.12#43ce3be6274eceaf47d9664ddc71cba68a990923" +source = "git+https://github.com/uniquenetwork/frontier.git?branch=unique-polkadot-v0.9.12-weights#0134806e399412bf896f881f1e3bc284916a1432" dependencies = [ "fp-storage", "kvdb", @@ -2304,13 +2293,13 @@ [[package]] name = "fc-mapping-sync" version = "2.0.0-dev" -source = "git+https://github.com/uniquenetwork/frontier.git?branch=unique-polkadot-v0.9.12#43ce3be6274eceaf47d9664ddc71cba68a990923" +source = "git+https://github.com/uniquenetwork/frontier.git?branch=unique-polkadot-v0.9.12-weights#0134806e399412bf896f881f1e3bc284916a1432" dependencies = [ "fc-consensus", "fc-db", "fp-consensus", "fp-rpc", - "futures 0.3.17", + "futures 0.3.18", "futures-timer 3.0.2", "log", "sc-client-api", @@ -2322,9 +2311,9 @@ [[package]] name = "fc-rpc" version = "2.0.0-dev" -source = "git+https://github.com/uniquenetwork/frontier.git?branch=unique-polkadot-v0.9.12#43ce3be6274eceaf47d9664ddc71cba68a990923" +source = "git+https://github.com/uniquenetwork/frontier.git?branch=unique-polkadot-v0.9.12-weights#0134806e399412bf896f881f1e3bc284916a1432" dependencies = [ - "ethereum 0.9.0 (git+https://github.com/purestake/ethereum?branch=joshy-scale-info)", + "ethereum 0.10.0", "ethereum-types", "evm", "fc-consensus", @@ -2334,7 +2323,7 @@ "fp-evm", "fp-rpc", "fp-storage", - "futures 0.3.17", + "futures 0.3.18", "futures-util", "jsonrpc-core", "jsonrpc-pubsub", @@ -2366,7 +2355,7 @@ [[package]] name = "fc-rpc-core" version = "1.1.0-dev" -source = "git+https://github.com/uniquenetwork/frontier.git?branch=unique-polkadot-v0.9.12#43ce3be6274eceaf47d9664ddc71cba68a990923" +source = "git+https://github.com/uniquenetwork/frontier.git?branch=unique-polkadot-v0.9.12-weights#0134806e399412bf896f881f1e3bc284916a1432" dependencies = [ "ethereum-types", "jsonrpc-core", @@ -2404,7 +2393,7 @@ checksum = "e8ac3ff5224ef91f3c97e03eb1de2db82743427e91aaa5ac635f454f0b164f5a" dependencies = [ "either", - "futures 0.3.17", + "futures 0.3.18", "futures-timer 3.0.2", "log", "num-traits", @@ -2487,9 +2476,9 @@ [[package]] name = "fp-consensus" version = "2.0.0-dev" -source = "git+https://github.com/uniquenetwork/frontier.git?branch=unique-polkadot-v0.9.12#43ce3be6274eceaf47d9664ddc71cba68a990923" +source = "git+https://github.com/uniquenetwork/frontier.git?branch=unique-polkadot-v0.9.12-weights#0134806e399412bf896f881f1e3bc284916a1432" dependencies = [ - "ethereum 0.9.0 (git+https://github.com/purestake/ethereum?branch=joshy-scale-info)", + "ethereum 0.10.0", "parity-scale-codec", "rlp", "sha3 0.8.2", @@ -2501,10 +2490,10 @@ [[package]] name = "fp-evm" version = "3.0.0-dev" -source = "git+https://github.com/uniquenetwork/frontier.git?branch=unique-polkadot-v0.9.12#43ce3be6274eceaf47d9664ddc71cba68a990923" +source = "git+https://github.com/uniquenetwork/frontier.git?branch=unique-polkadot-v0.9.12-weights#0134806e399412bf896f881f1e3bc284916a1432" dependencies = [ "evm", - "impl-trait-for-tuples 0.1.3", + "impl-trait-for-tuples", "parity-scale-codec", "scale-info", "serde", @@ -2515,9 +2504,9 @@ [[package]] name = "fp-rpc" version = "3.0.0-dev" -source = "git+https://github.com/uniquenetwork/frontier.git?branch=unique-polkadot-v0.9.12#43ce3be6274eceaf47d9664ddc71cba68a990923" +source = "git+https://github.com/uniquenetwork/frontier.git?branch=unique-polkadot-v0.9.12-weights#0134806e399412bf896f881f1e3bc284916a1432" dependencies = [ - "ethereum 0.9.0 (git+https://github.com/purestake/ethereum?branch=joshy-scale-info)", + "ethereum 0.10.0", "ethereum-types", "fp-evm", "parity-scale-codec", @@ -2532,9 +2521,9 @@ [[package]] name = "fp-self-contained" version = "1.0.0-dev" -source = "git+https://github.com/uniquenetwork/frontier.git?branch=unique-polkadot-v0.9.12#43ce3be6274eceaf47d9664ddc71cba68a990923" +source = "git+https://github.com/uniquenetwork/frontier.git?branch=unique-polkadot-v0.9.12-weights#0134806e399412bf896f881f1e3bc284916a1432" dependencies = [ - "ethereum 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ethereum 0.9.0", "frame-support", "parity-scale-codec", "parity-util-mem", @@ -2549,7 +2538,7 @@ [[package]] name = "fp-storage" version = "2.0.0" -source = "git+https://github.com/uniquenetwork/frontier.git?branch=unique-polkadot-v0.9.12#43ce3be6274eceaf47d9664ddc71cba68a990923" +source = "git+https://github.com/uniquenetwork/frontier.git?branch=unique-polkadot-v0.9.12-weights#0134806e399412bf896f881f1e3bc284916a1432" [[package]] name = "frame-benchmarking" @@ -2629,9 +2618,9 @@ [[package]] name = "frame-metadata" -version = "14.0.0" +version = "14.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96616f82e069102b95a72c87de4c84d2f87ef7f0f20630e78ce3824436483110" +checksum = "37ed5e5c346de62ca5c184b4325a6600d1eaca210666e4606fe4e449574978d0" dependencies = [ "cfg-if 1.0.0", "parity-scale-codec", @@ -2647,7 +2636,7 @@ "bitflags", "frame-metadata", "frame-support-procedural", - "impl-trait-for-tuples 0.2.1", + "impl-trait-for-tuples", "log", "once_cell", "parity-scale-codec", @@ -2810,9 +2799,9 @@ [[package]] name = "futures" -version = "0.3.17" +version = "0.3.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a12aa0eb539080d55c3f2d45a67c3b58b6b0773c1a3ca2dfec66d58c97fd66ca" +checksum = "8cd0210d8c325c245ff06fd95a3b13689a1a276ac8cfa8e8720cb840bfb84b9e" dependencies = [ "futures-channel", "futures-core", @@ -2825,9 +2814,9 @@ [[package]] name = "futures-channel" -version = "0.3.17" +version = "0.3.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5da6ba8c3bb3c165d3c7319fc1cc8304facf1fb8db99c5de877183c08a273888" +checksum = "7fc8cd39e3dbf865f7340dce6a2d401d24fd37c6fe6c4f0ee0de8bfca2252d27" dependencies = [ "futures-core", "futures-sink", @@ -2835,15 +2824,15 @@ [[package]] name = "futures-core" -version = "0.3.17" +version = "0.3.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88d1c26957f23603395cd326b0ffe64124b818f4449552f960d815cfba83a53d" +checksum = "629316e42fe7c2a0b9a65b47d159ceaa5453ab14e8f0a3c5eedbb8cd55b4a445" [[package]] name = "futures-executor" -version = "0.3.17" +version = "0.3.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45025be030969d763025784f7f355043dc6bc74093e4ecc5000ca4dc50d8745c" +checksum = "7b808bf53348a36cab739d7e04755909b9fcaaa69b7d7e588b37b6ec62704c97" dependencies = [ "futures-core", "futures-task", @@ -2853,9 +2842,9 @@ [[package]] name = "futures-io" -version = "0.3.17" +version = "0.3.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "522de2a0fe3e380f1bc577ba0474108faf3f6b18321dbf60b3b9c39a75073377" +checksum = "e481354db6b5c353246ccf6a728b0c5511d752c08da7260546fc0933869daa11" [[package]] name = "futures-lite" @@ -2874,12 +2863,10 @@ [[package]] name = "futures-macro" -version = "0.3.17" +version = "0.3.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18e4a4b95cea4b4ccbcf1c5675ca7c4ee4e9e75eb79944d07defde18068f79bb" +checksum = "a89f17b21645bc4ed773c69af9c9a0effd4a3f1a3876eadd453469f8854e7fdd" dependencies = [ - "autocfg", - "proc-macro-hack", "proc-macro2", "quote", "syn", @@ -2898,15 +2885,15 @@ [[package]] name = "futures-sink" -version = "0.3.17" +version = "0.3.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36ea153c13024fe480590b3e3d4cad89a0cfacecc24577b68f86c6ced9c2bc11" +checksum = "996c6442437b62d21a32cd9906f9c41e7dc1e19a9579843fad948696769305af" [[package]] name = "futures-task" -version = "0.3.17" +version = "0.3.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d3d00f4eddb73e498a54394f228cd55853bdf059259e8e7bc6e69d408892e99" +checksum = "dabf1872aaab32c886832f2276d2f5399887e2bd613698a02359e4ea83f8de12" [[package]] name = "futures-timer" @@ -2922,11 +2909,10 @@ [[package]] name = "futures-util" -version = "0.3.17" +version = "0.3.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36568465210a3a6ee45e1f165136d68671471a501e632e9a98d96872222b5481" +checksum = "41d22213122356472061ac0f1ab2cee28d2bac8491410fd68c2af53d1cedb83e" dependencies = [ - "autocfg", "futures 0.1.31", "futures-channel", "futures-core", @@ -2937,8 +2923,6 @@ "memchr", "pin-project-lite 0.2.7", "pin-utils", - "proc-macro-hack", - "proc-macro-nested", "slab", ] @@ -3108,9 +3092,9 @@ [[package]] name = "hex-literal" -version = "0.3.3" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21e4590e13640f19f249fe3e4eca5113bc4289f2497710378190e7f4bd96f45b" +checksum = "7ebdb29d2ea9ed0083cd8cece49bbd968021bd99b0849edb4a9a7ee0fdf6a4e0" [[package]] name = "hex_fmt" @@ -3211,9 +3195,9 @@ [[package]] name = "httpdate" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6456b8a6c8f33fee7d958fcd1b60d55b11940a79e63ae87013e6d22e26034440" +checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" [[package]] name = "humantime" @@ -3232,9 +3216,9 @@ [[package]] name = "hyper" -version = "0.14.14" +version = "0.14.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b91bb1f221b6ea1f1e4371216b70f40748774c2fb5971b450c07773fb92d26b" +checksum = "436ec0091e4f20e655156a30a0df3770fe2900aa301e548e08446ec794b6953c" dependencies = [ "bytes 1.1.0", "futures-channel", @@ -3247,7 +3231,7 @@ "itoa", "pin-project-lite 0.2.7", "socket2 0.4.2", - "tokio 1.13.0", + "tokio 1.14.0", "tower-service", "tracing", "want", @@ -3265,7 +3249,7 @@ "log", "rustls", "rustls-native-certs", - "tokio 1.13.0", + "tokio 1.14.0", "tokio-rustls", "webpki", ] @@ -3300,9 +3284,9 @@ [[package]] name = "if-addrs" -version = "0.6.6" +version = "0.6.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9a83ec4af652890ac713ffd8dc859e650420a5ef47f7b9be29b6664ab50fbc8" +checksum = "2273e421f7c4f0fc99e1934fe4776f59d8df2972f4199d703fc0da9f2a9f73de" dependencies = [ "if-addrs-sys", "libc", @@ -3326,7 +3310,7 @@ checksum = "ae8ab7f67bad3240049cb24fb9cb0b4c2c6af4c245840917fbbdededeee91179" dependencies = [ "async-io", - "futures 0.3.17", + "futures 0.3.18", "futures-lite", "if-addrs", "ipnet", @@ -3355,22 +3339,11 @@ [[package]] name = "impl-serde" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b47ca4d2b6931707a55fce5cf66aff80e2178c8b63bbb4ecb5695cbc870ddf6f" +checksum = "4551f042f3438e64dbd6226b20527fc84a6e1fe65688b58746a2f53623f25f5c" dependencies = [ "serde", -] - -[[package]] -name = "impl-trait-for-tuples" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ef5550a42e3740a0e71f909d4c861056a284060af885ae7aa6242820f920d9d" -dependencies = [ - "proc-macro2", - "quote", - "syn", ] [[package]] @@ -3425,7 +3398,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "64fa110ec7b8f493f416eed552740d10e7030ad5f63b2308f82c9608ec2df275" dependencies = [ - "futures 0.3.17", + "futures 0.3.18", "futures-timer 2.0.2", ] @@ -3440,9 +3413,9 @@ [[package]] name = "ip_network" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09b746553d2f4a1ca26fab939943ddfb217a091f34f53571620a8e3d30691303" +checksum = "aa2f047c0a98b2f299aa5d6d7088443570faae494e9ae1305e48be000c9e0eb1" [[package]] name = "ipconfig" @@ -3502,7 +3475,7 @@ checksum = "d2b99d4207e2a04fb4581746903c2bb7eb376f88de9c699d0f3e10feeac0cd3a" dependencies = [ "derive_more", - "futures 0.3.17", + "futures 0.3.18", "jsonrpc-core", "jsonrpc-pubsub", "log", @@ -3517,7 +3490,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "14f7f76aef2d054868398427f6c54943cf3d1caa9a7ec7d0c38d69df97a965eb" dependencies = [ - "futures 0.3.17", + "futures 0.3.18", "futures-executor", "futures-util", "log", @@ -3532,7 +3505,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b51da17abecbdab3e3d4f26b01c5ec075e88d3abe3ab3b05dc9aa69392764ec0" dependencies = [ - "futures 0.3.17", + "futures 0.3.18", "jsonrpc-client-transports", ] @@ -3554,7 +3527,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e1dea6e07251d9ce6a552abfb5d7ad6bc290a4596c8dcc3d795fae2bbdc1f3ff" dependencies = [ - "futures 0.3.17", + "futures 0.3.18", "hyper", "jsonrpc-core", "jsonrpc-server-utils", @@ -3570,7 +3543,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "382bb0206323ca7cda3dcd7e245cea86d37d02457a02a975e3378fb149a48845" dependencies = [ - "futures 0.3.17", + "futures 0.3.18", "jsonrpc-core", "jsonrpc-server-utils", "log", @@ -3585,7 +3558,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "240f87695e6c6f62fb37f05c02c04953cf68d6408b8c1c89de85c7a0125b1011" dependencies = [ - "futures 0.3.17", + "futures 0.3.18", "jsonrpc-core", "lazy_static", "log", @@ -3601,12 +3574,12 @@ checksum = "fa4fdea130485b572c39a460d50888beb00afb3e35de23ccd7fad8ff19f0e0d4" dependencies = [ "bytes 1.1.0", - "futures 0.3.17", + "futures 0.3.18", "globset", "jsonrpc-core", "lazy_static", "log", - "tokio 1.13.0", + "tokio 1.14.0", "tokio-stream", "tokio-util", "unicase", @@ -3618,7 +3591,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f892c7d766369475ab7b0669f417906302d7c0fb521285c0a0c92e52e7c8e946" dependencies = [ - "futures 0.3.17", + "futures 0.3.18", "jsonrpc-core", "jsonrpc-server-utils", "log", @@ -3667,7 +3640,7 @@ dependencies = [ "async-trait", "fnv", - "futures 0.3.17", + "futures 0.3.18", "jsonrpsee-types", "log", "pin-project 1.0.8", @@ -3677,7 +3650,7 @@ "serde_json", "soketto 0.6.0", "thiserror", - "tokio 1.13.0", + "tokio 1.14.0", "tokio-rustls", "tokio-util", "url 2.2.2", @@ -3705,7 +3678,7 @@ source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.12#5feed981cf0fe671447eabaa9c0d235a8dd0003e" dependencies = [ "beefy-primitives", - "bitvec 0.20.4", + "bitvec", "frame-benchmarking", "frame-election-provider-support", "frame-executive", @@ -3847,9 +3820,9 @@ [[package]] name = "libc" -version = "0.2.106" +version = "0.2.108" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a60553f9a9e039a333b4e9b20573b9e9b9c0bb3a11e201ccc48ef4283456d673" +checksum = "8521a1b57e76b1ec69af7599e75e38e7b7fad6610f037db8c79b127201b5d119" [[package]] name = "libloading" @@ -3863,9 +3836,9 @@ [[package]] name = "libloading" -version = "0.7.1" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0cf036d15402bea3c5d4de17b3fce76b3e4a56ebc1f577be0e7a72f7c607cf0" +checksum = "afe203d669ec979b7128619bae5a63b7b42e9203c1b29146079ee05e2f604b52" dependencies = [ "cfg-if 1.0.0", "winapi 0.3.9", @@ -3885,7 +3858,7 @@ dependencies = [ "atomic", "bytes 1.1.0", - "futures 0.3.17", + "futures 0.3.18", "lazy_static", "libp2p-core", "libp2p-deflate", @@ -3927,7 +3900,7 @@ "ed25519-dalek", "either", "fnv", - "futures 0.3.17", + "futures 0.3.18", "futures-timer 3.0.2", "lazy_static", "libsecp256k1 0.5.0", @@ -3945,7 +3918,7 @@ "sha2 0.9.8", "smallvec", "thiserror", - "unsigned-varint 0.7.0", + "unsigned-varint 0.7.1", "void", "zeroize", ] @@ -3957,7 +3930,7 @@ checksum = "66097fccc0b7f8579f90a03ea76ba6196332ea049fd07fd969490a06819dcdc8" dependencies = [ "flate2", - "futures 0.3.17", + "futures 0.3.18", "libp2p-core", ] @@ -3968,7 +3941,7 @@ checksum = "58ff08b3196b85a17f202d80589e93b1660a574af67275706657fdc762e42c32" dependencies = [ "async-std-resolver", - "futures 0.3.17", + "futures 0.3.18", "libp2p-core", "log", "smallvec", @@ -3983,7 +3956,7 @@ dependencies = [ "cuckoofilter", "fnv", - "futures 0.3.17", + "futures 0.3.18", "libp2p-core", "libp2p-swarm", "log", @@ -4004,7 +3977,7 @@ "byteorder", "bytes 1.1.0", "fnv", - "futures 0.3.17", + "futures 0.3.18", "hex_fmt", "libp2p-core", "libp2p-swarm", @@ -4015,7 +3988,7 @@ "regex", "sha2 0.9.8", "smallvec", - "unsigned-varint 0.7.0", + "unsigned-varint 0.7.1", "wasm-timer", ] @@ -4025,7 +3998,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a7b61f6cf07664fb97016c318c4d4512b3dd4cc07238607f3f0163245f99008e" dependencies = [ - "futures 0.3.17", + "futures 0.3.18", "libp2p-core", "libp2p-swarm", "log", @@ -4046,7 +4019,7 @@ "bytes 1.1.0", "either", "fnv", - "futures 0.3.17", + "futures 0.3.18", "libp2p-core", "libp2p-swarm", "log", @@ -4056,7 +4029,7 @@ "sha2 0.9.8", "smallvec", "uint", - "unsigned-varint 0.7.0", + "unsigned-varint 0.7.1", "void", "wasm-timer", ] @@ -4070,7 +4043,7 @@ "async-io", "data-encoding", "dns-parser", - "futures 0.3.17", + "futures 0.3.18", "if-watch", "lazy_static", "libp2p-core", @@ -4090,14 +4063,14 @@ dependencies = [ "asynchronous-codec 0.6.0", "bytes 1.1.0", - "futures 0.3.17", + "futures 0.3.18", "libp2p-core", "log", "nohash-hasher", "parking_lot 0.11.2", "rand 0.7.3", "smallvec", - "unsigned-varint 0.7.0", + "unsigned-varint 0.7.1", ] [[package]] @@ -4108,7 +4081,7 @@ dependencies = [ "bytes 1.1.0", "curve25519-dalek 3.2.0", - "futures 0.3.17", + "futures 0.3.18", "lazy_static", "libp2p-core", "log", @@ -4128,7 +4101,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2482cfd9eb0b7a0baaf3e7b329dc4f2785181a161b1a47b7192f8d758f54a439" dependencies = [ - "futures 0.3.17", + "futures 0.3.18", "libp2p-core", "libp2p-swarm", "log", @@ -4145,12 +4118,12 @@ dependencies = [ "asynchronous-codec 0.6.0", "bytes 1.1.0", - "futures 0.3.17", + "futures 0.3.18", "libp2p-core", "log", "prost", "prost-build", - "unsigned-varint 0.7.0", + "unsigned-varint 0.7.1", "void", ] @@ -4160,7 +4133,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "07cb4dd4b917e5b40ddefe49b96b07adcd8d342e0317011d175b7b2bb1dcc974" dependencies = [ - "futures 0.3.17", + "futures 0.3.18", "log", "pin-project 1.0.8", "rand 0.7.3", @@ -4176,7 +4149,7 @@ dependencies = [ "asynchronous-codec 0.6.0", "bytes 1.1.0", - "futures 0.3.17", + "futures 0.3.18", "futures-timer 3.0.2", "libp2p-core", "libp2p-swarm", @@ -4186,7 +4159,7 @@ "prost-build", "rand 0.7.3", "smallvec", - "unsigned-varint 0.7.0", + "unsigned-varint 0.7.1", "void", "wasm-timer", ] @@ -4199,7 +4172,7 @@ dependencies = [ "async-trait", "bytes 1.1.0", - "futures 0.3.17", + "futures 0.3.18", "libp2p-core", "libp2p-swarm", "log", @@ -4207,7 +4180,7 @@ "minicbor", "rand 0.7.3", "smallvec", - "unsigned-varint 0.7.0", + "unsigned-varint 0.7.1", "wasm-timer", ] @@ -4218,7 +4191,7 @@ checksum = "7083861341e1555467863b4cd802bea1e8c4787c0f7b5110097d0f1f3248f9a9" dependencies = [ "either", - "futures 0.3.17", + "futures 0.3.18", "libp2p-core", "log", "rand 0.7.3", @@ -4244,7 +4217,7 @@ checksum = "79edd26b6b4bb5feee210dcda562dca186940dfecb0024b979c3f50824b3bf28" dependencies = [ "async-io", - "futures 0.3.17", + "futures 0.3.18", "futures-timer 3.0.2", "if-watch", "ipnet", @@ -4261,7 +4234,7 @@ checksum = "280e793440dd4e9f273d714f4497325c72cddb0fe85a49f9a03c88f41dd20182" dependencies = [ "async-std", - "futures 0.3.17", + "futures 0.3.18", "libp2p-core", "log", ] @@ -4272,7 +4245,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f553b7140fad3d7a76f50497b0ea591e26737d9607428a75509fc191e4d1b1f6" dependencies = [ - "futures 0.3.17", + "futures 0.3.18", "js-sys", "libp2p-core", "parity-send-wrapper", @@ -4287,7 +4260,7 @@ checksum = "ddf99dcbf5063e9d59087f61b1e85c686ceab2f5abedb472d32288065c0e5e27" dependencies = [ "either", - "futures 0.3.17", + "futures 0.3.18", "futures-rustls", "libp2p-core", "log", @@ -4304,7 +4277,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "214cc0dd9c37cbed27f0bb1eba0c41bbafdb93a8be5e9d6ae1e6b4b42cd044bf" dependencies = [ - "futures 0.3.17", + "futures 0.3.18", "libp2p-core", "parking_lot 0.11.2", "thiserror", @@ -4603,9 +4576,9 @@ [[package]] name = "matrixmultiply" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a8a15b776d9dfaecd44b03c5828c2199cddff5247215858aac14624f8d6b741" +checksum = "add85d4dd35074e6fedc608f8c8f513a3548619a9024b751949ef0e8e45a4d84" dependencies = [ "rawpointer", ] @@ -4678,7 +4651,7 @@ source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.12#5feed981cf0fe671447eabaa9c0d235a8dd0003e" dependencies = [ "derive_more", - "futures 0.3.17", + "futures 0.3.18", "futures-timer 3.0.2", "thiserror", "tracing", @@ -4686,11 +4659,11 @@ [[package]] name = "mick-jaeger" -version = "0.1.4" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c023c3f16109e7f33aa451f773fd61070e265b4977d0b6e344a51049296dd7df" +checksum = "eaa77fad8461bb1e0d01be11299e24c6e544007715ed442bfec29f165dc487ae" dependencies = [ - "futures 0.3.17", + "futures 0.3.18", "rand 0.7.3", "thrift", ] @@ -4716,6 +4689,12 @@ ] [[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + +[[package]] name = "miniz_oxide" version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -4792,9 +4771,9 @@ [[package]] name = "more-asserts" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0debeb9fcf88823ea64d64e4a815ab1643f33127d995978e099942ce38f25238" +checksum = "7843ec2de400bcbc6a6328c958dc38e5359da6e93e72e37bc5246bf1ae776389" [[package]] name = "multiaddr" @@ -4810,7 +4789,7 @@ "percent-encoding 2.1.0", "serde", "static_assertions", - "unsigned-varint 0.7.0", + "unsigned-varint 0.7.1", "url 2.2.2", ] @@ -4852,7 +4831,7 @@ "generic-array 0.14.4", "multihash-derive", "sha2 0.9.8", - "unsigned-varint 0.7.0", + "unsigned-varint 0.7.1", ] [[package]] @@ -4882,11 +4861,11 @@ checksum = "56a336acba8bc87c8876f6425407dbbe6c417bf478b22015f8fb0994ef3bc0ab" dependencies = [ "bytes 1.1.0", - "futures 0.3.17", + "futures 0.3.18", "log", "pin-project 1.0.8", "smallvec", - "unsigned-varint 0.7.0", + "unsigned-varint 0.7.1", ] [[package]] @@ -4952,13 +4931,12 @@ [[package]] name = "nom" -version = "6.1.2" +version = "7.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7413f999671bd4745a7b624bd370a569fb6bc574b23c83a3c5ed2e453f3d5e2" +checksum = "1b1d11e1ef389c76fe5b81bcaf2ea32cf88b62bc494e19f493d0b30e7a930109" dependencies = [ - "bitvec 0.19.5", - "funty", "memchr", + "minimal-lexical", "version_check", ] @@ -5160,7 +5138,7 @@ dependencies = [ "frame-support", "frame-system", - "impl-trait-for-tuples 0.2.1", + "impl-trait-for-tuples", "parity-scale-codec", "scale-info", "sp-authorship", @@ -5330,7 +5308,7 @@ version = "0.1.0" source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.12#5feed981cf0fe671447eabaa9c0d235a8dd0003e" dependencies = [ - "bitvec 0.20.4", + "bitvec", "bp-message-dispatch", "bp-messages", "bp-rialto", @@ -5509,9 +5487,9 @@ [[package]] name = "pallet-ethereum" version = "4.0.0-dev" -source = "git+https://github.com/uniquenetwork/frontier.git?branch=unique-polkadot-v0.9.12#43ce3be6274eceaf47d9664ddc71cba68a990923" +source = "git+https://github.com/uniquenetwork/frontier.git?branch=unique-polkadot-v0.9.12-weights#0134806e399412bf896f881f1e3bc284916a1432" dependencies = [ - "ethereum 0.9.0 (git+https://github.com/purestake/ethereum?branch=joshy-scale-info)", + "ethereum 0.10.0", "ethereum-types", "evm", "fp-consensus", @@ -5538,7 +5516,7 @@ [[package]] name = "pallet-evm" version = "6.0.0-dev" -source = "git+https://github.com/uniquenetwork/frontier.git?branch=unique-polkadot-v0.9.12#43ce3be6274eceaf47d9664ddc71cba68a990923" +source = "git+https://github.com/uniquenetwork/frontier.git?branch=unique-polkadot-v0.9.12-weights#0134806e399412bf896f881f1e3bc284916a1432" dependencies = [ "evm", "evm-gasometer", @@ -5548,7 +5526,7 @@ "frame-support", "frame-system", "hex", - "impl-trait-for-tuples 0.2.1", + "impl-trait-for-tuples", "log", "pallet-balances", "pallet-timestamp", @@ -5568,8 +5546,9 @@ name = "pallet-evm-coder-substrate" version = "0.1.0" dependencies = [ - "ethereum 0.9.0 (git+https://github.com/purestake/ethereum?branch=joshy-scale-info)", + "ethereum 0.10.0", "evm-coder", + "frame-benchmarking", "frame-support", "frame-system", "pallet-ethereum", @@ -5638,7 +5617,7 @@ name = "pallet-fungible" version = "0.1.0" dependencies = [ - "ethereum 0.9.0 (git+https://github.com/purestake/ethereum?branch=joshy-scale-info)", + "ethereum 0.10.0", "evm-coder", "frame-benchmarking", "frame-support", @@ -5864,7 +5843,7 @@ name = "pallet-nonfungible" version = "0.1.0" dependencies = [ - "ethereum 0.9.0 (git+https://github.com/purestake/ethereum?branch=joshy-scale-info)", + "ethereum 0.10.0", "evm-coder", "frame-benchmarking", "frame-support", @@ -6001,7 +5980,7 @@ dependencies = [ "frame-support", "frame-system", - "impl-trait-for-tuples 0.2.1", + "impl-trait-for-tuples", "log", "pallet-timestamp", "parity-scale-codec", @@ -6212,7 +6191,7 @@ "frame-benchmarking", "frame-support", "frame-system", - "impl-trait-for-tuples 0.2.1", + "impl-trait-for-tuples", "pallet-balances", "parity-scale-codec", "scale-info", @@ -6225,7 +6204,7 @@ name = "pallet-unique" version = "0.1.0" dependencies = [ - "ethereum 0.9.0 (git+https://github.com/purestake/ethereum?branch=joshy-scale-info)", + "ethereum 0.10.0", "evm-coder", "fp-evm", "frame-benchmarking", @@ -6346,7 +6325,7 @@ [[package]] name = "parachain-info" version = "0.1.0" -source = "git+https://github.com/paritytech/cumulus.git?branch=polkadot-v0.9.12#f5926c2f50df73bf36171b138241437131d76fff" +source = "git+https://github.com/paritytech/cumulus.git?branch=polkadot-v0.9.12#c02514d8cb66d6860e597f75d53ca07119dbbf32" dependencies = [ "cumulus-primitives-core", "frame-support", @@ -6358,9 +6337,9 @@ [[package]] name = "parity-db" -version = "0.3.3" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7ccc4a8687027deb53d45c5434a1f1b330c9d1069a59cfe80a62aa9a1da25ae" +checksum = "78a95abf24f1097c6e3181abbbbfc3630b3b5e681470940f719b69acb4911c7f" dependencies = [ "blake2-rfc", "crc32fast", @@ -6382,9 +6361,9 @@ checksum = "373b1a4c1338d9cd3d1fa53b3a11bdab5ab6bd80a20f7f7becd76953ae2be909" dependencies = [ "arrayvec 0.7.2", - "bitvec 0.20.4", + "bitvec", "byte-slice-cast", - "impl-trait-for-tuples 0.2.1", + "impl-trait-for-tuples", "parity-scale-codec-derive", "serde", ] @@ -6413,11 +6392,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9981e32fb75e004cc148f5fb70342f393830e0a4aa62e3cc93b50976218d42b6" dependencies = [ - "futures 0.3.17", + "futures 0.3.18", "libc", "log", "rand 0.7.3", - "tokio 1.13.0", + "tokio 1.14.0", "winapi 0.3.9", ] @@ -6430,7 +6409,7 @@ "cfg-if 1.0.0", "ethereum-types", "hashbrown", - "impl-trait-for-tuples 0.2.1", + "impl-trait-for-tuples", "lru 0.6.6", "parity-util-mem-derive", "parking_lot 0.11.2", @@ -6540,9 +6519,9 @@ [[package]] name = "paste" -version = "1.0.5" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acbf547ad0c65e31259204bd90935776d1c693cec2f4ff7abb7a1bbbd40dfe58" +checksum = "0744126afe1a6dd7f394cb50a716dbe086cb06e255e53d8d0185d82828358fb5" [[package]] name = "pbkdf2" @@ -6708,7 +6687,7 @@ version = "0.9.12" source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.12#5feed981cf0fe671447eabaa9c0d235a8dd0003e" dependencies = [ - "futures 0.3.17", + "futures 0.3.18", "polkadot-node-network-protocol", "polkadot-node-primitives", "polkadot-node-subsystem", @@ -6722,7 +6701,7 @@ version = "0.9.12" source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.12#5feed981cf0fe671447eabaa9c0d235a8dd0003e" dependencies = [ - "futures 0.3.17", + "futures 0.3.18", "polkadot-node-network-protocol", "polkadot-node-subsystem", "polkadot-node-subsystem-util", @@ -6736,7 +6715,7 @@ source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.12#5feed981cf0fe671447eabaa9c0d235a8dd0003e" dependencies = [ "derive_more", - "futures 0.3.17", + "futures 0.3.18", "lru 0.7.0", "parity-scale-codec", "polkadot-erasure-coding", @@ -6757,7 +6736,7 @@ version = "0.9.12" source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.12#5feed981cf0fe671447eabaa9c0d235a8dd0003e" dependencies = [ - "futures 0.3.17", + "futures 0.3.18", "lru 0.7.0", "parity-scale-codec", "polkadot-erasure-coding", @@ -6778,7 +6757,7 @@ source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.12#5feed981cf0fe671447eabaa9c0d235a8dd0003e" dependencies = [ "frame-benchmarking-cli", - "futures 0.3.17", + "futures 0.3.18", "log", "polkadot-node-core-pvf", "polkadot-service", @@ -6829,7 +6808,7 @@ dependencies = [ "always-assert", "derive_more", - "futures 0.3.17", + "futures 0.3.18", "futures-timer 3.0.2", "polkadot-node-network-protocol", "polkadot-node-primitives", @@ -6862,7 +6841,7 @@ source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.12#5feed981cf0fe671447eabaa9c0d235a8dd0003e" dependencies = [ "derive_more", - "futures 0.3.17", + "futures 0.3.18", "lru 0.7.0", "parity-scale-codec", "polkadot-erasure-coding", @@ -6897,7 +6876,7 @@ version = "0.9.12" source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.12#5feed981cf0fe671447eabaa9c0d235a8dd0003e" dependencies = [ - "futures 0.3.17", + "futures 0.3.18", "futures-timer 3.0.2", "polkadot-node-network-protocol", "polkadot-node-subsystem", @@ -6918,7 +6897,7 @@ source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.12#5feed981cf0fe671447eabaa9c0d235a8dd0003e" dependencies = [ "async-trait", - "futures 0.3.17", + "futures 0.3.18", "parity-scale-codec", "parking_lot 0.11.2", "polkadot-node-network-protocol", @@ -6936,7 +6915,7 @@ version = "0.9.12" source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.12#5feed981cf0fe671447eabaa9c0d235a8dd0003e" dependencies = [ - "futures 0.3.17", + "futures 0.3.18", "parity-scale-codec", "polkadot-erasure-coding", "polkadot-node-primitives", @@ -6954,9 +6933,9 @@ version = "0.9.12" source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.12#5feed981cf0fe671447eabaa9c0d235a8dd0003e" dependencies = [ - "bitvec 0.20.4", + "bitvec", "derive_more", - "futures 0.3.17", + "futures 0.3.18", "futures-timer 3.0.2", "kvdb", "lru 0.7.0", @@ -6982,8 +6961,8 @@ version = "0.9.12" source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.12#5feed981cf0fe671447eabaa9c0d235a8dd0003e" dependencies = [ - "bitvec 0.20.4", - "futures 0.3.17", + "bitvec", + "futures 0.3.18", "futures-timer 3.0.2", "kvdb", "parity-scale-codec", @@ -7002,8 +6981,8 @@ version = "0.9.12" source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.12#5feed981cf0fe671447eabaa9c0d235a8dd0003e" dependencies = [ - "bitvec 0.20.4", - "futures 0.3.17", + "bitvec", + "futures 0.3.18", "polkadot-erasure-coding", "polkadot-node-primitives", "polkadot-node-subsystem", @@ -7020,7 +6999,7 @@ version = "0.9.12" source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.12#5feed981cf0fe671447eabaa9c0d235a8dd0003e" dependencies = [ - "futures 0.3.17", + "futures 0.3.18", "polkadot-node-subsystem", "polkadot-node-subsystem-util", "polkadot-primitives", @@ -7036,7 +7015,7 @@ source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.12#5feed981cf0fe671447eabaa9c0d235a8dd0003e" dependencies = [ "async-trait", - "futures 0.3.17", + "futures 0.3.18", "parity-scale-codec", "polkadot-node-core-pvf", "polkadot-node-primitives", @@ -7053,7 +7032,7 @@ version = "0.9.12" source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.12#5feed981cf0fe671447eabaa9c0d235a8dd0003e" dependencies = [ - "futures 0.3.17", + "futures 0.3.18", "polkadot-node-subsystem", "polkadot-node-subsystem-util", "polkadot-primitives", @@ -7068,7 +7047,7 @@ version = "0.9.12" source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.12#5feed981cf0fe671447eabaa9c0d235a8dd0003e" dependencies = [ - "futures 0.3.17", + "futures 0.3.18", "futures-timer 3.0.2", "kvdb", "parity-scale-codec", @@ -7085,9 +7064,9 @@ version = "0.9.12" source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.12#5feed981cf0fe671447eabaa9c0d235a8dd0003e" dependencies = [ - "bitvec 0.20.4", + "bitvec", "derive_more", - "futures 0.3.17", + "futures 0.3.18", "kvdb", "parity-scale-codec", "polkadot-node-primitives", @@ -7104,7 +7083,7 @@ version = "0.9.12" source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.12#5feed981cf0fe671447eabaa9c0d235a8dd0003e" dependencies = [ - "futures 0.3.17", + "futures 0.3.18", "polkadot-node-primitives", "polkadot-node-subsystem", "polkadot-primitives", @@ -7118,7 +7097,7 @@ source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.12#5feed981cf0fe671447eabaa9c0d235a8dd0003e" dependencies = [ "async-trait", - "futures 0.3.17", + "futures 0.3.18", "futures-timer 3.0.2", "polkadot-node-subsystem", "polkadot-primitives", @@ -7134,8 +7113,8 @@ version = "0.9.12" source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.12#5feed981cf0fe671447eabaa9c0d235a8dd0003e" dependencies = [ - "bitvec 0.20.4", - "futures 0.3.17", + "bitvec", + "futures 0.3.18", "futures-timer 3.0.2", "polkadot-node-subsystem", "polkadot-node-subsystem-util", @@ -7153,7 +7132,7 @@ "assert_matches", "async-process", "async-std", - "futures 0.3.17", + "futures 0.3.18", "futures-timer 3.0.2", "libc", "parity-scale-codec", @@ -7180,7 +7159,7 @@ version = "0.9.12" source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.12#5feed981cf0fe671447eabaa9c0d235a8dd0003e" dependencies = [ - "futures 0.3.17", + "futures 0.3.18", "memory-lru", "parity-util-mem", "polkadot-node-subsystem", @@ -7216,7 +7195,7 @@ version = "0.9.12" source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.12#5feed981cf0fe671447eabaa9c0d235a8dd0003e" dependencies = [ - "futures 0.3.17", + "futures 0.3.18", "futures-timer 3.0.2", "metered-channel", "substrate-prometheus-endpoint", @@ -7229,7 +7208,7 @@ dependencies = [ "async-trait", "derive_more", - "futures 0.3.17", + "futures 0.3.18", "parity-scale-codec", "polkadot-node-jaeger", "polkadot-node-primitives", @@ -7246,7 +7225,7 @@ source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.12#5feed981cf0fe671447eabaa9c0d235a8dd0003e" dependencies = [ "bounded-vec", - "futures 0.3.17", + "futures 0.3.18", "parity-scale-codec", "polkadot-parachain", "polkadot-primitives", @@ -7278,7 +7257,7 @@ source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.12#5feed981cf0fe671447eabaa9c0d235a8dd0003e" dependencies = [ "derive_more", - "futures 0.3.17", + "futures 0.3.18", "polkadot-node-jaeger", "polkadot-node-network-protocol", "polkadot-node-primitives", @@ -7298,7 +7277,7 @@ dependencies = [ "async-trait", "derive_more", - "futures 0.3.17", + "futures 0.3.18", "itertools", "lru 0.7.0", "metered-channel", @@ -7323,7 +7302,7 @@ version = "0.9.12" source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.12#5feed981cf0fe671447eabaa9c0d235a8dd0003e" dependencies = [ - "futures 0.3.17", + "futures 0.3.18", "futures-timer 3.0.2", "lru 0.7.0", "parity-util-mem", @@ -7345,7 +7324,7 @@ source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.12#5feed981cf0fe671447eabaa9c0d235a8dd0003e" dependencies = [ "async-trait", - "futures 0.3.17", + "futures 0.3.18", "futures-timer 3.0.2", "metered-channel", "pin-project 1.0.8", @@ -7389,7 +7368,7 @@ version = "0.9.12" source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.12#5feed981cf0fe671447eabaa9c0d235a8dd0003e" dependencies = [ - "bitvec 0.20.4", + "bitvec", "frame-system", "hex-literal", "parity-scale-codec", @@ -7451,7 +7430,7 @@ source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.12#5feed981cf0fe671447eabaa9c0d235a8dd0003e" dependencies = [ "beefy-primitives", - "bitvec 0.20.4", + "bitvec", "frame-benchmarking", "frame-election-provider-support", "frame-executive", @@ -7528,12 +7507,12 @@ source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.12#5feed981cf0fe671447eabaa9c0d235a8dd0003e" dependencies = [ "beefy-primitives", - "bitvec 0.20.4", + "bitvec", "frame-benchmarking", "frame-election-provider-support", "frame-support", "frame-system", - "impl-trait-for-tuples 0.2.1", + "impl-trait-for-tuples", "libsecp256k1 0.7.0", "log", "pallet-authorship", @@ -7575,7 +7554,7 @@ source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.12#5feed981cf0fe671447eabaa9c0d235a8dd0003e" dependencies = [ "bitflags", - "bitvec 0.20.4", + "bitvec", "derive_more", "frame-benchmarking", "frame-support", @@ -7617,7 +7596,7 @@ "beefy-gadget", "beefy-primitives", "frame-system-rpc-runtime-api", - "futures 0.3.17", + "futures 0.3.18", "hex-literal", "kusama-runtime", "kvdb", @@ -7713,7 +7692,7 @@ dependencies = [ "arrayvec 0.5.2", "derive_more", - "futures 0.3.17", + "futures 0.3.18", "indexmap", "parity-scale-codec", "polkadot-node-network-protocol", @@ -7743,7 +7722,7 @@ source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.12#5feed981cf0fe671447eabaa9c0d235a8dd0003e" dependencies = [ "beefy-primitives", - "bitvec 0.20.4", + "bitvec", "frame-election-provider-support", "frame-executive", "frame-support", @@ -7806,7 +7785,7 @@ "frame-benchmarking", "frame-system", "futures 0.1.31", - "futures 0.3.17", + "futures 0.3.18", "hex", "pallet-balances", "pallet-staking", @@ -7847,15 +7826,15 @@ "sp-state-machine", "substrate-test-client", "tempfile", - "tokio 1.13.0", + "tokio 1.14.0", "tracing", ] [[package]] name = "polling" -version = "2.1.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92341d779fa34ea8437ef4d82d440d5e1ce3f3ff7f824aa64424cd481f9a1f25" +checksum = "685404d509889fade3e86fe3a5803bca2ec09b0c0778d5ada6ec8bf7a8de5259" dependencies = [ "cfg-if 1.0.0", "libc", @@ -7987,20 +7966,8 @@ "quote", "version_check", ] - -[[package]] -name = "proc-macro-hack" -version = "0.5.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5" [[package]] -name = "proc-macro-nested" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc881b2c22681370c6a780e47af9840ef841837bc98118431d4e1868bd0c1086" - -[[package]] name = "proc-macro2" version = "1.0.32" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -8125,12 +8092,6 @@ dependencies = [ "proc-macro2", ] - -[[package]] -name = "radium" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "941ba9d78d8e2f7ce474c015eea4d9c6d25b6a3327f9832ee29a4de27f91bbb8" [[package]] name = "radium" @@ -8617,7 +8578,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4da5fcb054c46f5a5dff833b129285a93d3f0179531735e6c866e8cc307d2020" dependencies = [ - "futures 0.3.17", + "futures 0.3.18", "pin-project 0.4.28", "static_assertions", ] @@ -8673,7 +8634,7 @@ dependencies = [ "async-trait", "derive_more", - "futures 0.3.17", + "futures 0.3.18", "futures-timer 3.0.2", "ip_network", "libp2p", @@ -8698,7 +8659,7 @@ version = "0.10.0-dev" source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.12#d76f39995315ec36980908e4b99709bd14927044" dependencies = [ - "futures 0.3.17", + "futures 0.3.18", "futures-timer 3.0.2", "log", "parity-scale-codec", @@ -8737,7 +8698,7 @@ version = "4.0.0-dev" source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.12#d76f39995315ec36980908e4b99709bd14927044" dependencies = [ - "impl-trait-for-tuples 0.2.1", + "impl-trait-for-tuples", "parity-scale-codec", "sc-chain-spec-derive", "sc-network", @@ -8766,7 +8727,7 @@ dependencies = [ "chrono", "fdlimit", - "futures 0.3.17", + "futures 0.3.18", "hex", "libp2p", "log", @@ -8794,7 +8755,7 @@ "structopt", "thiserror", "tiny-bip39", - "tokio 1.13.0", + "tokio 1.14.0", ] [[package]] @@ -8803,7 +8764,7 @@ source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.12#d76f39995315ec36980908e4b99709bd14927044" dependencies = [ "fnv", - "futures 0.3.17", + "futures 0.3.18", "hash-db", "log", "parity-scale-codec", @@ -8856,7 +8817,7 @@ source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.12#d76f39995315ec36980908e4b99709bd14927044" dependencies = [ "async-trait", - "futures 0.3.17", + "futures 0.3.18", "futures-timer 3.0.2", "libp2p", "log", @@ -8881,7 +8842,7 @@ dependencies = [ "async-trait", "derive_more", - "futures 0.3.17", + "futures 0.3.18", "log", "parity-scale-codec", "sc-block-builder", @@ -8911,7 +8872,7 @@ "async-trait", "derive_more", "fork-tree", - "futures 0.3.17", + "futures 0.3.18", "log", "merlin", "num-bigint", @@ -8952,7 +8913,7 @@ source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.12#d76f39995315ec36980908e4b99709bd14927044" dependencies = [ "derive_more", - "futures 0.3.17", + "futures 0.3.18", "jsonrpc-core", "jsonrpc-core-client", "jsonrpc-derive", @@ -8989,7 +8950,7 @@ source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.12#d76f39995315ec36980908e4b99709bd14927044" dependencies = [ "async-trait", - "futures 0.3.17", + "futures 0.3.18", "futures-timer 3.0.2", "log", "parity-scale-codec", @@ -9108,7 +9069,7 @@ "dyn-clone", "finality-grandpa", "fork-tree", - "futures 0.3.17", + "futures 0.3.18", "futures-timer 3.0.2", "log", "parity-scale-codec", @@ -9142,7 +9103,7 @@ dependencies = [ "derive_more", "finality-grandpa", - "futures 0.3.17", + "futures 0.3.18", "jsonrpc-core", "jsonrpc-core-client", "jsonrpc-derive", @@ -9165,7 +9126,7 @@ source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.12#d76f39995315ec36980908e4b99709bd14927044" dependencies = [ "ansi_term 0.12.1", - "futures 0.3.17", + "futures 0.3.18", "futures-timer 3.0.2", "log", "parity-util-mem", @@ -9224,7 +9185,7 @@ "either", "fnv", "fork-tree", - "futures 0.3.17", + "futures 0.3.18", "futures-timer 3.0.2", "hex", "ip_network", @@ -9265,7 +9226,7 @@ version = "0.10.0-dev" source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.12#d76f39995315ec36980908e4b99709bd14927044" dependencies = [ - "futures 0.3.17", + "futures 0.3.18", "futures-timer 3.0.2", "libp2p", "log", @@ -9283,7 +9244,7 @@ dependencies = [ "bytes 1.1.0", "fnv", - "futures 0.3.17", + "futures 0.3.18", "futures-timer 3.0.2", "hex", "hyper", @@ -9308,7 +9269,7 @@ version = "4.0.0-dev" source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.12#d76f39995315ec36980908e4b99709bd14927044" dependencies = [ - "futures 0.3.17", + "futures 0.3.18", "libp2p", "log", "sc-utils", @@ -9330,7 +9291,7 @@ version = "4.0.0-dev" source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.12#d76f39995315ec36980908e4b99709bd14927044" dependencies = [ - "futures 0.3.17", + "futures 0.3.18", "hash-db", "jsonrpc-core", "jsonrpc-pubsub", @@ -9361,7 +9322,7 @@ version = "0.10.0-dev" source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.12#d76f39995315ec36980908e4b99709bd14927044" dependencies = [ - "futures 0.3.17", + "futures 0.3.18", "jsonrpc-core", "jsonrpc-core-client", "jsonrpc-derive", @@ -9386,7 +9347,7 @@ version = "4.0.0-dev" source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.12#d76f39995315ec36980908e4b99709bd14927044" dependencies = [ - "futures 0.3.17", + "futures 0.3.18", "jsonrpc-core", "jsonrpc-http-server", "jsonrpc-ipc-server", @@ -9395,7 +9356,7 @@ "log", "serde_json", "substrate-prometheus-endpoint", - "tokio 1.13.0", + "tokio 1.14.0", ] [[package]] @@ -9406,7 +9367,7 @@ "async-trait", "directories", "exit-future", - "futures 0.3.17", + "futures 0.3.18", "futures-timer 3.0.2", "hash-db", "jsonrpc-core", @@ -9458,7 +9419,7 @@ "substrate-prometheus-endpoint", "tempfile", "thiserror", - "tokio 1.13.0", + "tokio 1.14.0", "tracing", "tracing-futures", ] @@ -9505,7 +9466,7 @@ source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.12#d76f39995315ec36980908e4b99709bd14927044" dependencies = [ "chrono", - "futures 0.3.17", + "futures 0.3.18", "libp2p", "log", "parking_lot 0.11.2", @@ -9563,7 +9524,7 @@ version = "4.0.0-dev" source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.12#d76f39995315ec36980908e4b99709bd14927044" dependencies = [ - "futures 0.3.17", + "futures 0.3.18", "intervalier", "linked-hash-map", "log", @@ -9591,7 +9552,7 @@ source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.12#d76f39995315ec36980908e4b99709bd14927044" dependencies = [ "derive_more", - "futures 0.3.17", + "futures 0.3.18", "log", "serde", "sp-blockchain", @@ -9604,7 +9565,7 @@ version = "4.0.0-dev" source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.12#d76f39995315ec36980908e4b99709bd14927044" dependencies = [ - "futures 0.3.17", + "futures 0.3.18", "futures-timer 3.0.2", "lazy_static", "prometheus", @@ -9616,7 +9577,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5c55b744399c25532d63a0d2789b109df8d46fc93752d46b0782991a931a782f" dependencies = [ - "bitvec 0.20.4", + "bitvec", "cfg-if 1.0.0", "derive_more", "parity-scale-codec", @@ -9783,9 +9744,9 @@ [[package]] name = "serde_json" -version = "1.0.68" +version = "1.0.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f690853975602e1bfe1ccbf50504d67174e3bcf340f23b5ea9992e0587a52d8" +checksum = "d0ffa0837f2dfa6fb90868c2b5468cad482e175f7dad97e7421951e663f2b527" dependencies = [ "itoa", "ryu", @@ -10006,7 +9967,7 @@ "base64 0.12.3", "bytes 0.5.6", "flate2", - "futures 0.3.17", + "futures 0.3.18", "httparse", "log", "rand 0.7.3", @@ -10021,7 +9982,7 @@ dependencies = [ "base64 0.13.0", "bytes 1.1.0", - "futures 0.3.17", + "futures 0.3.18", "httparse", "log", "rand 0.8.4", @@ -10127,7 +10088,7 @@ version = "4.0.0-dev" source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.12#d76f39995315ec36980908e4b99709bd14927044" dependencies = [ - "futures 0.3.17", + "futures 0.3.18", "log", "lru 0.6.6", "parity-scale-codec", @@ -10146,7 +10107,7 @@ source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.12#d76f39995315ec36980908e4b99709bd14927044" dependencies = [ "async-trait", - "futures 0.3.17", + "futures 0.3.18", "futures-timer 3.0.2", "log", "parity-scale-codec", @@ -10233,7 +10194,7 @@ "byteorder", "dyn-clonable", "ed25519-dalek", - "futures 0.3.17", + "futures 0.3.18", "hash-db", "hash256-std-hasher", "hex", @@ -10323,7 +10284,7 @@ source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.12#d76f39995315ec36980908e4b99709bd14927044" dependencies = [ "async-trait", - "impl-trait-for-tuples 0.2.1", + "impl-trait-for-tuples", "parity-scale-codec", "sp-core", "sp-runtime", @@ -10336,7 +10297,7 @@ version = "4.0.0-dev" source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.12#d76f39995315ec36980908e4b99709bd14927044" dependencies = [ - "futures 0.3.17", + "futures 0.3.18", "hash-db", "libsecp256k1 0.6.0", "log", @@ -10373,7 +10334,7 @@ dependencies = [ "async-trait", "derive_more", - "futures 0.3.17", + "futures 0.3.18", "merlin", "parity-scale-codec", "parking_lot 0.11.2", @@ -10452,7 +10413,7 @@ dependencies = [ "either", "hash256-std-hasher", - "impl-trait-for-tuples 0.2.1", + "impl-trait-for-tuples", "log", "parity-scale-codec", "parity-util-mem", @@ -10472,7 +10433,7 @@ version = "4.0.0-dev" source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.12#d76f39995315ec36980908e4b99709bd14927044" dependencies = [ - "impl-trait-for-tuples 0.2.1", + "impl-trait-for-tuples", "parity-scale-codec", "primitive-types 0.10.1", "sp-externalities", @@ -10698,7 +10659,7 @@ version = "4.0.0-dev" source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.12#d76f39995315ec36980908e4b99709bd14927044" dependencies = [ - "impl-trait-for-tuples 0.2.1", + "impl-trait-for-tuples", "parity-scale-codec", "sp-std", "wasmi", @@ -10712,9 +10673,9 @@ [[package]] name = "ss58-registry" -version = "1.2.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb102b328df61c67f8ccf8471b29c31c7d6da646a867aff95fe8bff386fe7c4d" +checksum = "78abb01d308934b82e34e9cf1f45846d31539246501745b129539176f4f3368d" dependencies = [ "Inflector", "proc-macro2", @@ -10897,7 +10858,7 @@ source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.12#d76f39995315ec36980908e4b99709bd14927044" dependencies = [ "frame-system-rpc-runtime-api", - "futures 0.3.17", + "futures 0.3.18", "jsonrpc-core", "jsonrpc-core-client", "jsonrpc-derive", @@ -10924,7 +10885,7 @@ "hyper", "log", "prometheus", - "tokio 1.13.0", + "tokio 1.14.0", ] [[package]] @@ -10933,7 +10894,7 @@ source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.12#d76f39995315ec36980908e4b99709bd14927044" dependencies = [ "async-trait", - "futures 0.3.17", + "futures 0.3.18", "hex", "parity-scale-codec", "sc-client-api", @@ -10959,9 +10920,9 @@ version = "4.0.0-dev" source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.12#d76f39995315ec36980908e4b99709bd14927044" dependencies = [ - "futures 0.3.17", + "futures 0.3.18", "substrate-test-utils-derive", - "tokio 1.13.0", + "tokio 1.14.0", ] [[package]] @@ -11004,9 +10965,9 @@ [[package]] name = "syn" -version = "1.0.81" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2afee18b8beb5a596ecb4a2dce128c719b4ba399d34126b9e4396e3f9860966" +checksum = "8daf5dd0bb60cbd4137b1b587d2fc0ae729bc07cf01cd70b36a1ed5ade3b9d59" dependencies = [ "proc-macro2", "quote", @@ -11172,9 +11133,9 @@ [[package]] name = "tinyvec" -version = "1.5.0" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f83b2a3d4d9091d0abd7eba4dc2710b1718583bd4d8992e2190720ea38f391f7" +checksum = "2c1c1d5a42b6245520c249549ec267180beaffcc0615401ac8e31853d4b6d8d2" dependencies = [ "tinyvec_macros", ] @@ -11199,9 +11160,9 @@ [[package]] name = "tokio" -version = "1.13.0" +version = "1.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "588b2d10a336da58d877567cd8fb8a14b463e2104910f8132cd054b4b96e29ee" +checksum = "70e992e41e0d2fb9f755b37446f20900f64446ef54874f40a60c78f021ac6144" dependencies = [ "autocfg", "bytes 1.1.0", @@ -11212,7 +11173,7 @@ "once_cell", "pin-project-lite 0.2.7", "signal-hook-registry", - "tokio-macros 1.5.1", + "tokio-macros 1.6.0", "winapi 0.3.9", ] @@ -11229,9 +11190,9 @@ [[package]] name = "tokio-macros" -version = "1.5.1" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "114383b041aa6212c579467afa0075fbbdd0718de036100bc0ba7961d8cb9095" +checksum = "c9efc1aba077437943f7515666aa2b882dfabfbfdf89c819ea75a8d6e9eaba5e" dependencies = [ "proc-macro2", "quote", @@ -11245,7 +11206,7 @@ checksum = "bc6844de72e57df1980054b38be3a9f4702aba4858be64dd700181a8a6d0e1b6" dependencies = [ "rustls", - "tokio 1.13.0", + "tokio 1.14.0", "webpki", ] @@ -11257,7 +11218,7 @@ dependencies = [ "futures-core", "pin-project-lite 0.2.7", - "tokio 1.13.0", + "tokio 1.14.0", ] [[package]] @@ -11272,7 +11233,7 @@ "futures-sink", "log", "pin-project-lite 0.2.7", - "tokio 1.13.0", + "tokio 1.14.0", ] [[package]] @@ -11596,7 +11557,7 @@ "fp-rpc", "frame-benchmarking", "frame-benchmarking-cli", - "futures 0.3.17", + "futures 0.3.18", "jsonrpc-core", "jsonrpc-pubsub", "log", @@ -11660,7 +11621,7 @@ "fc-rpc", "fc-rpc-core", "fp-rpc", - "futures 0.3.17", + "futures 0.3.18", "jsonrpc-core", "jsonrpc-pubsub", "pallet-ethereum", @@ -11800,9 +11761,9 @@ [[package]] name = "unsigned-varint" -version = "0.7.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f8d425fafb8cd76bc3f22aace4af471d3156301d7508f2107e98fbeae10bc7f" +checksum = "d86a8dc7f45e4c1b0d30e43038c38f274e77af056aa5f74b93c2cf9eb3c1c836" dependencies = [ "asynchronous-codec 0.6.0", "bytes 1.1.0", @@ -11857,7 +11818,7 @@ version = "0.1.0" source = "git+https://github.com/UniqueNetwork/pallet-sponsoring#ab8b91e9350a31133f3a3e4f52a84c6de4108e95" dependencies = [ - "impl-trait-for-tuples 0.2.1", + "impl-trait-for-tuples", ] [[package]] @@ -12039,7 +12000,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "be0ecb0db480561e9a7642b5d3e4187c128914e58aa84330b9493e3eb68c5e7f" dependencies = [ - "futures 0.3.17", + "futures 0.3.18", "js-sys", "parking_lot 0.11.2", "pin-utils", @@ -12279,7 +12240,7 @@ source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.12#5feed981cf0fe671447eabaa9c0d235a8dd0003e" dependencies = [ "beefy-primitives", - "bitvec 0.20.4", + "bitvec", "frame-benchmarking", "frame-election-provider-support", "frame-executive", @@ -12459,7 +12420,7 @@ source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.12#5feed981cf0fe671447eabaa9c0d235a8dd0003e" dependencies = [ "derivative", - "impl-trait-for-tuples 0.2.1", + "impl-trait-for-tuples", "log", "parity-scale-codec", "scale-info", @@ -12493,7 +12454,7 @@ dependencies = [ "frame-benchmarking", "frame-support", - "impl-trait-for-tuples 0.2.1", + "impl-trait-for-tuples", "log", "parity-scale-codec", "sp-arithmetic", @@ -12520,7 +12481,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e7d9028f208dd5e63c614be69f115c1b53cacc1111437d4c765185856666c107" dependencies = [ - "futures 0.3.17", + "futures 0.3.18", "log", "nohash-hasher", "parking_lot 0.11.2", @@ -12536,18 +12497,18 @@ [[package]] name = "zeroize" -version = "1.4.2" +version = "1.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf68b08513768deaa790264a7fac27a58cbf2705cfcdc9448362229217d7e970" +checksum = "d68d9dcec5f9b43a30d38c49f91dfedfaac384cb8f085faca366c26207dd1619" dependencies = [ "zeroize_derive", ] [[package]] name = "zeroize_derive" -version = "1.2.0" +version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bdff2024a851a322b08f179173ae2ba620445aef1e838f0c196820eade4ae0c7" +checksum = "65f1a51723ec88c66d5d1fe80c841f17f63587d6691901d66be9bec6c3b51f73" dependencies = [ "proc-macro2", "quote", --- a/Dockerfile-parachain +++ b/Dockerfile-parachain @@ -2,7 +2,7 @@ FROM phusion/baseimage:focal-1.0.0 as rust-builder LABEL maintainer="Unique.Network" -ARG RUST_TOOLCHAIN=nightly-2021-06-28 +ARG RUST_TOOLCHAIN=nightly-2021-11-11 #ARG RUST_C=1.55.0-nightly ARG POLKA_VERSION=v0.9.12 ARG UNIQUE_BRANCH=develop --- a/README.md +++ b/README.md @@ -63,17 +63,17 @@ 2. Remove all installed toolchains with `rustup toolchain list` and `rustup toolchain uninstall `. -3. Install install nightly 2021-06-28 and make it default: +3. Install install nightly 2021-11-11 and make it default: ```bash -rustup toolchain install nightly-2021-06-28 -rustup default nightly-2021-06-28 +rustup toolchain install nightly-2021-11-11 +rustup default nightly-2021-11-11 ``` 4. Add wasm target for nightly toolchain: ```bash -rustup target add wasm32-unknown-unknown --toolchain nightly-2021-06-28 +rustup target add wasm32-unknown-unknown --toolchain nightly-2021-11-11 ``` 5. Build: @@ -135,7 +135,7 @@ ## Building and Running as Parachain locally -Rust toolchain: nightly-2021-06-28 +Rust toolchain: nightly-2021-11-11 Note: checkout this project and polkadot project (see below) in the sibling folders (both under the same folder) ### Build relay @@ -208,12 +208,12 @@ First of all, add rust toolchain and make it default. ```bash -rustup target add wasm32-unknown-unknown --toolchain nightly-2021-06-28 +rustup target add wasm32-unknown-unknown --toolchain nightly-2021-11-11 ``` Then in "/node/src" run build command below ```bash -cargo +nightly-2021-06-28 build --release --features runtime-benchmarks +cargo +nightly-2021-11-11 build --release --features runtime-benchmarks ``` Run benchmark --- a/client/rpc/Cargo.toml +++ b/client/rpc/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "uc-rpc" version = "0.1.0" -edition = "2018" +edition = "2021" [dependencies] pallet-common = { default-features = false, path = '../../pallets/common' } --- a/crates/evm-coder-macros/Cargo.toml +++ b/crates/evm-coder-macros/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "evm-coder-macros" version = "0.1.0" -edition = "2018" +edition = "2021" [lib] proc-macro = true @@ -13,4 +13,4 @@ syn = { version = "1.0", features = ["full"] } hex = "0.4.3" Inflector = "0.11.4" -darling = "0.13.0" \ No newline at end of file +darling = "0.13.0" --- a/crates/evm-coder-macros/src/lib.rs +++ b/crates/evm-coder-macros/src/lib.rs @@ -27,7 +27,7 @@ /// Returns solidity function selector (first 4 bytes of hash) by its /// textual representation /// -/// ```rs +/// ```ignore /// use evm_coder_macros::fn_selector; /// /// assert_eq!(fn_selector!(transfer(address, uint256)), 0xa9059cbb); @@ -55,7 +55,7 @@ /// Returns solidity topic (hash) by its textual representation /// -/// ```rs +/// ```ignore /// use evm_coder_macros::event_topic; /// /// assert_eq!( @@ -184,6 +184,58 @@ Ident::new(&name, ident.span()) } +/// Derives call enum implementing [`evm_coder::Callable`], [`evm_coder::Weighted`] +/// and [`evm_coder::Call`] from impl block +/// +/// ## Macro syntax +/// +/// `#[solidity_interface(name, is, inline_is, events)]` +/// - *name*: used in generated code, and for Call enum name +/// - *is*: used to provide call inheritance, not found methods will be delegated to all contracts +/// specified in is/inline_is +/// - *inline_is*: same as is, but selectors for passed contracts will be used by derived ERC165 +/// implementation +/// +/// `#[weight(value)]` +/// Can be added to every method of impl block, used for deriving [`evm_coder::Weighted`], which +/// is used by substrate bridge +/// - *value*: expression, which evaluates to weight required to call this method. +/// This expression can use call arguments to calculate non-constant execution time. +/// This expression should evaluate faster than actual execution does, and may provide worser case +/// than one is called +/// +/// `#[solidity_interface(rename_selector)]` +/// - *rename_selector*: by default, selector name will be generated by transforming method name +/// from snake_case to camelCase. Use this option, if other naming convention is required. +/// I.e: method `token_uri` will be automatically renamed to `tokenUri` in selector, but name +/// required by ERC721 standard is `tokenURI`, thus we need to specify `rename_selector = "tokenURI"` +/// explicitly +/// +/// Also, any contract method may have doc comments, which will be automatically added to generated +/// solidity interface definitions +/// +/// ## Example +/// +/// ```ignore +/// struct SuperContract; +/// struct InlineContract; +/// struct Contract; +/// +/// #[derive(ToLog)] +/// enum ContractEvents { +/// Event(#[indexed] uint32), +/// } +/// +/// #[solidity_interface(name = "MyContract", is(SuperContract), inline_is(InlineContract))] +/// impl Contract { +/// /// Multiply two numbers +/// #[weight(200 + a + b)] +/// #[solidity_interface(rename_selector = "mul")] +/// fn mul(&mut self, a: uint32, b: uint32) -> Result { +/// Ok(a.checked_mul(b).ok_or("overflow")?) +/// } +/// } +/// ``` #[proc_macro_attribute] pub fn solidity_interface(args: TokenStream, stream: TokenStream) -> TokenStream { let args = parse_macro_input!(args as AttributeArgs); @@ -211,7 +263,15 @@ pub fn solidity(_args: TokenStream, stream: TokenStream) -> TokenStream { stream } +#[proc_macro_attribute] +pub fn weight(_args: TokenStream, stream: TokenStream) -> TokenStream { + stream +} +/// ## Syntax +/// +/// `#[indexed]` +/// Marks this field as indexed, so it will appear in [`ethereum::Log`] topics instead of data #[proc_macro_derive(ToLog, attributes(indexed))] pub fn to_log(value: TokenStream) -> TokenStream { let input = parse_macro_input!(value as DeriveInput); --- a/crates/evm-coder-macros/src/solidity_interface.rs +++ b/crates/evm-coder-macros/src/solidity_interface.rs @@ -6,7 +6,7 @@ use std::fmt::Write; use syn::{ Expr, FnArg, GenericArgument, Generics, Ident, ImplItem, ImplItemMethod, ItemImpl, Lit, Meta, - NestedMeta, PatType, Path, PathArguments, ReturnType, Type, spanned::Spanned, + MetaNameValue, NestedMeta, PatType, Path, PathArguments, ReturnType, Type, spanned::Spanned, }; use crate::{ @@ -30,11 +30,11 @@ }) } - fn expand_call_def(&self) -> proc_macro2::TokenStream { + fn expand_call_def(&self, gen_ref: &proc_macro2::TokenStream) -> proc_macro2::TokenStream { let name = &self.name; let pascal_call_name = &self.pascal_call_name; quote! { - #name(#pascal_call_name) + #name(#pascal_call_name #gen_ref) } } @@ -45,18 +45,32 @@ } } - fn expand_supports_interface(&self) -> proc_macro2::TokenStream { + fn expand_supports_interface( + &self, + generics: &proc_macro2::TokenStream, + ) -> proc_macro2::TokenStream { let pascal_call_name = &self.pascal_call_name; quote! { - #pascal_call_name::supports_interface(interface_id) + <#pascal_call_name #generics>::supports_interface(interface_id) } } - fn expand_variant_call(&self) -> proc_macro2::TokenStream { + fn expand_variant_weight(&self) -> proc_macro2::TokenStream { let name = &self.name; + quote! { + Self::#name(call) => call.weight() + } + } + + fn expand_variant_call( + &self, + call_name: &proc_macro2::Ident, + generics: &proc_macro2::TokenStream, + ) -> proc_macro2::TokenStream { + let name = &self.name; let pascal_call_name = &self.pascal_call_name; quote! { - InternalCall::#name(call) => return >::call(self, Msg { + #call_name::#name(call) => return >::call(self, Msg { call, caller: c.caller, value: c.value, @@ -64,20 +78,20 @@ } } - fn expand_parse(&self) -> proc_macro2::TokenStream { + fn expand_parse(&self, generics: &proc_macro2::TokenStream) -> proc_macro2::TokenStream { let name = &self.name; let pascal_call_name = &self.pascal_call_name; quote! { - if let Some(parsed_call) = #pascal_call_name::parse(method_id, reader)? { + if let Some(parsed_call) = <#pascal_call_name #generics>::parse(method_id, reader)? { return Ok(Some(Self::#name(parsed_call))) } } } - fn expand_generator(&self) -> proc_macro2::TokenStream { + fn expand_generator(&self, generics: &proc_macro2::TokenStream) -> proc_macro2::TokenStream { let pascal_call_name = &self.pascal_call_name; quote! { - #pascal_call_name::generate_solidity_interface(tc, is_impl); + <#pascal_call_name #generics>::generate_solidity_interface(tc, is_impl); } } @@ -212,16 +226,10 @@ } } fn is_value(&self) -> bool { - match self { - Self::Plain(v) if v == "value" => true, - _ => false, - } + matches!(self, Self::Plain(v) if v == "value") } fn is_caller(&self) -> bool { - match self { - Self::Plain(v) if v == "caller" => true, - _ => false, - } + matches!(self, Self::Plain(v) if v == "caller") } fn is_special(&self) -> bool { self.is_caller() || self.is_value() @@ -351,6 +359,25 @@ Pure, } +pub struct WeightAttr(syn::Expr); + +mod keyword { + syn::custom_keyword!(weight); +} + +impl syn::parse::Parse for WeightAttr { + fn parse(input: syn::parse::ParseStream) -> syn::Result { + input.parse::()?; + let content; + syn::bracketed!(content in input); + content.parse::()?; + + let weight_content; + syn::parenthesized!(weight_content in content); + Ok(WeightAttr(weight_content.parse::()?)) + } +} + struct Method { name: Ident, camel_name: String, @@ -362,19 +389,32 @@ has_normal_args: bool, mutability: Mutability, result: Type, + weight: Option, + docs: Vec, } impl Method { fn try_from(value: &ImplItemMethod) -> syn::Result { let mut info = MethodInfo { rename_selector: None, }; + let mut docs = Vec::new(); + let mut weight = None; for attr in &value.attrs { let ident = parse_ident_from_path(&attr.path, false)?; if ident == "solidity" { let args = attr.parse_meta().unwrap(); info = MethodInfo::from_meta(&args).unwrap(); } else if ident == "doc" { - // TODO: Add docs to evm interfaces + let args = attr.parse_meta().unwrap(); + let value = match args { + Meta::NameValue(MetaNameValue { + lit: Lit::Str(str), .. + }) => str.value(), + _ => unreachable!(), + }; + docs.push(value); + } else if ident == "weight" { + weight = Some(syn::parse2::(attr.to_token_stream())?.0); } } let ident = &value.sig.ident; @@ -457,6 +497,8 @@ has_normal_args, mutability, result: result.clone(), + weight, + docs, }) } fn expand_call_def(&self) -> proc_macro2::TokenStream { @@ -518,7 +560,7 @@ } } - fn expand_variant_call(&self) -> proc_macro2::TokenStream { + fn expand_variant_call(&self, call_name: &proc_macro2::Ident) -> proc_macro2::TokenStream { let pascal_name = &self.pascal_name; let name = &self.name; @@ -545,13 +587,46 @@ let args = self.args.iter().map(|a| a.expand_call_arg()); quote! { - InternalCall::#pascal_name #matcher => { + #call_name::#pascal_name #matcher => { let result = #receiver #name( #( #args, )* )?; - (&result).abi_write(&mut writer); + (&result).to_result() + } + } + } + + fn expand_variant_weight(&self) -> proc_macro2::TokenStream { + let pascal_name = &self.pascal_name; + if let Some(weight) = &self.weight { + let matcher = if self.has_normal_args { + let names = self + .args + .iter() + .filter(|a| !a.is_special()) + .map(|a| &a.name); + + quote! {{ + #( + #names, + )* + }} + } else { + quote! {} + }; + quote! { + Self::#pascal_name #matcher => (#weight).into() + } + } else { + let matcher = if self.has_normal_args { + quote! {{..}} + } else { + quote! {} + }; + quote! { + Self::#pascal_name #matcher => ().into() } } } @@ -570,10 +645,12 @@ .iter() .filter(|a| !a.is_special()) .map(MethodArg::expand_solidity_argument); + let docs = self.docs.iter(); let selector = format!("{} {:0>8x}", self.selector_str, self.selector); quote! { SolidityFunction { + docs: &[#(#docs),*], selector: #selector, name: #camel_name, mutability: #mutability, @@ -588,6 +665,42 @@ } } +fn generics_list(gen: &Generics) -> proc_macro2::TokenStream { + if gen.params.is_empty() { + return quote! {}; + } + let params = gen.params.iter().map(|p| match p { + syn::GenericParam::Type(id) => { + let v = &id.ident; + quote! {#v} + } + syn::GenericParam::Lifetime(lt) => { + let v = <.lifetime; + quote! {#v} + } + syn::GenericParam::Const(c) => { + let i = &c.ident; + quote! {#i} + } + }); + quote! { #(#params),* } +} +fn generics_reference(gen: &Generics) -> proc_macro2::TokenStream { + if gen.params.is_empty() { + return quote! {}; + } + let list = generics_list(gen); + quote! { <#list> } +} +fn generics_data(gen: &Generics) -> proc_macro2::TokenStream { + let list = generics_list(gen); + if gen.params.len() == 1 { + quote! {#list} + } else { + quote! { (#list) } + } +} + pub struct SolidityInterface { generics: Generics, name: Box, @@ -616,6 +729,8 @@ let solidity_name = self.info.name.to_string(); let call_name = pascal_ident_to_call(&self.info.name); let generics = self.generics; + let gen_ref = generics_reference(&generics); + let gen_data = generics_data(&generics); let call_sub = self .info @@ -623,30 +738,46 @@ .0 .iter() .chain(self.info.is.0.iter()) - .map(Is::expand_call_def); + .map(|c| Is::expand_call_def(c, &gen_ref)); let call_parse = self .info .inline_is .0 .iter() .chain(self.info.is.0.iter()) - .map(Is::expand_parse); + .map(|is| Is::expand_parse(is, &gen_ref)); let call_variants = self .info .inline_is .0 .iter() .chain(self.info.is.0.iter()) - .map(Is::expand_variant_call); + .map(|c| Is::expand_variant_call(c, &call_name, &gen_ref)); + let weight_variants = self + .info + .inline_is + .0 + .iter() + .chain(self.info.is.0.iter()) + .map(Is::expand_variant_weight); let inline_interface_id = self.info.inline_is.0.iter().map(Is::expand_interface_id); - let supports_interface = self.info.is.0.iter().map(Is::expand_supports_interface); + let supports_interface = self + .info + .is + .0 + .iter() + .map(|is| Is::expand_supports_interface(is, &gen_ref)); let calls = self.methods.iter().map(Method::expand_call_def); let consts = self.methods.iter().map(Method::expand_const); let interface_id = self.methods.iter().map(Method::expand_interface_id); let parsers = self.methods.iter().map(Method::expand_parse); - let call_variants_this = self.methods.iter().map(Method::expand_variant_call); + let call_variants_this = self + .methods + .iter() + .map(|m| Method::expand_variant_call(m, &call_name)); + let weight_variants_this = self.methods.iter().map(Method::expand_variant_weight); let solidity_functions = self.methods.iter().map(Method::expand_solidity_function); // TODO: Inline inline_is @@ -664,15 +795,15 @@ .0 .iter() .chain(self.info.inline_is.0.iter()) - .map(Is::expand_generator); + .map(|is| Is::expand_generator(is, &gen_ref)); let solidity_event_generators = self.info.events.0.iter().map(Is::expand_event_generator); // let methods = self.methods.iter().map(Method::solidity_def); quote! { #[derive(Debug)] - pub enum #call_name { - ERC165Call(::evm_coder::ERC165Call), + pub enum #call_name #gen_ref { + ERC165Call(::evm_coder::ERC165Call, ::core::marker::PhantomData<#gen_data>), #( #calls, )* @@ -680,11 +811,11 @@ #call_sub, )* } - impl #call_name { + impl #gen_ref #call_name #gen_ref { #( #consts )* - pub const fn interface_id() -> u32 { + pub fn interface_id() -> u32 { let mut interface_id = 0; #(#interface_id)* #(#inline_interface_id)* @@ -704,6 +835,7 @@ use core::fmt::Write; let interface = SolidityInterface { name: #solidity_name, + selector: Self::interface_id(), is: &["Dummy", "ERC165", #( #solidity_is, )* #( @@ -735,11 +867,14 @@ tc.collect(out); } } - impl ::evm_coder::Call for #call_name { + impl #gen_ref ::evm_coder::Call for #call_name #gen_ref { fn parse(method_id: u32, reader: &mut ::evm_coder::abi::AbiReader) -> ::evm_coder::execution::Result> { use ::evm_coder::abi::AbiRead; match method_id { - ::evm_coder::ERC165Call::INTERFACE_ID => return Ok(::evm_coder::ERC165Call::parse(method_id, reader)?.map(Self::ERC165Call)), + ::evm_coder::ERC165Call::INTERFACE_ID => return Ok( + ::evm_coder::ERC165Call::parse(method_id, reader)? + .map(|c| Self::ERC165Call(c, ::core::marker::PhantomData)) + ), #( #parsers, )* @@ -751,19 +886,33 @@ return Ok(None); } } - impl #generics ::evm_coder::Callable<#call_name> for #name { + impl #generics ::evm_coder::Weighted for #call_name #gen_ref { + #[allow(unused_variables)] + fn weight(&self) -> ::evm_coder::execution::DispatchInfo { + match self { + #( + #weight_variants, + )* + // TODO: It should be very cheap, but not free + Self::ERC165Call(::evm_coder::ERC165Call::SupportsInterface {..}, _) => 100u64.into(), + #( + #weight_variants_this, + )* + } + } + } + impl #generics ::evm_coder::Callable<#call_name #gen_ref> for #name { #[allow(unreachable_code)] // In case of no inner calls - fn call(&mut self, c: Msg<#call_name>) -> Result<::evm_coder::abi::AbiWriter> { + fn call(&mut self, c: Msg<#call_name #gen_ref>) -> ::evm_coder::execution::ResultWithPostInfo<::evm_coder::abi::AbiWriter> { use ::evm_coder::abi::AbiWrite; - type InternalCall = #call_name; match c.call { #( #call_variants, )* - InternalCall::ERC165Call(::evm_coder::ERC165Call::SupportsInterface {interface_id}) => { + #call_name::ERC165Call(::evm_coder::ERC165Call::SupportsInterface {interface_id}, _) => { let mut writer = ::evm_coder::abi::AbiWriter::default(); - writer.bool(&InternalCall::supports_interface(interface_id)); - return Ok(writer); + writer.bool(&<#call_name #gen_ref>::supports_interface(interface_id)); + return Ok(writer.into()); } _ => {}, } @@ -774,7 +923,6 @@ )* _ => unreachable!() } - Ok(writer) } } } --- a/crates/evm-coder-macros/src/to_log.rs +++ b/crates/evm-coder-macros/src/to_log.rs @@ -183,6 +183,7 @@ use evm_coder::solidity::*; use core::fmt::Write; let interface = SolidityInterface { + selector: 0, name: #solidity_name, is: &[], functions: (#( --- a/crates/evm-coder/Cargo.toml +++ b/crates/evm-coder/Cargo.toml @@ -1,14 +1,14 @@ [package] name = "evm-coder" version = "0.1.0" -edition = "2018" +edition = "2021" [dependencies] evm-coder-macros = { path = "../evm-coder-macros" } primitive-types = { version = "0.10.1", default-features = false } hex-literal = "0.3.3" -ethereum = { version = "0.9", git = "https://github.com/purestake/ethereum", branch = "joshy-scale-info", default-features = false } -evm-core = { default-features = false, git = "https://github.com/uniquenetwork/evm.git", branch="precompile-output-parachain" } +ethereum = { version = "0.10.0", default-features = false } +evm-core = { default-features = false, git = "https://github.com/uniquenetwork/evm.git", branch = "unique-weights" } impl-trait-for-tuples = "0.2.1" [dev-dependencies] --- a/crates/evm-coder/src/abi.rs +++ b/crates/evm-coder/src/abi.rs @@ -11,7 +11,10 @@ use evm_core::ExitError; use primitive_types::{H160, U256}; -use crate::{execution::Error, types::string}; +use crate::{ + execution::{Error, ResultWithPostInfo, WithPostDispatchInfo}, + types::string, +}; use crate::execution::Result; const ABI_ALIGNMENT: usize = 32; @@ -244,6 +247,7 @@ } impl_abi_readable!(u32, uint32); +impl_abi_readable!(u64, uint64); impl_abi_readable!(u128, uint128); impl_abi_readable!(U256, uint256); impl_abi_readable!(H160, address); @@ -306,6 +310,36 @@ pub trait AbiWrite { fn abi_write(&self, writer: &mut AbiWriter); + fn to_result(&self) -> ResultWithPostInfo { + let mut writer = AbiWriter::new(); + self.abi_write(&mut writer); + Ok(writer.into()) + } +} + +impl AbiWrite for ResultWithPostInfo { + // this particular AbiWrite implementation should be split to another trait, + // which only implements [`to_result`] + // + // But due to lack of specialization feature in stable Rust, we can't have + // blanket impl of this trait `for T where T: AbiWrite`, so here we abusing + // default trait methods for it + fn abi_write(&self, _writer: &mut AbiWriter) { + debug_assert!(false, "shouldn't be called, see comment") + } + fn to_result(&self) -> ResultWithPostInfo { + match self { + Ok(v) => Ok(WithPostDispatchInfo { + post_info: v.post_info.clone(), + data: { + let mut out = AbiWriter::new(); + v.data.abi_write(&mut out); + out + }, + }), + Err(e) => Err(e.clone()), + } + } } macro_rules! impl_abi_writeable { --- a/crates/evm-coder/src/execution.rs +++ b/crates/evm-coder/src/execution.rs @@ -4,7 +4,9 @@ #[cfg(feature = "std")] use std::string::{String, ToString}; -#[derive(Debug)] +use crate::Weight; + +#[derive(Debug, Clone)] pub enum Error { Revert(String), Fatal(ExitFatal), @@ -21,3 +23,55 @@ } pub type Result = core::result::Result; + +pub struct DispatchInfo { + pub weight: Weight, +} + +impl From for DispatchInfo { + fn from(weight: Weight) -> Self { + Self { weight } + } +} +impl From<()> for DispatchInfo { + fn from(_: ()) -> Self { + Self { weight: 0 } + } +} + +#[derive(Default, Clone)] +pub struct PostDispatchInfo { + actual_weight: Option, +} + +impl PostDispatchInfo { + pub fn calc_unspent(&self, info: &DispatchInfo) -> Weight { + info.weight - self.calc_actual_weight(info) + } + + pub fn calc_actual_weight(&self, info: &DispatchInfo) -> Weight { + if let Some(actual_weight) = self.actual_weight { + actual_weight.min(info.weight) + } else { + info.weight + } + } +} + +#[derive(Clone)] +pub struct WithPostDispatchInfo { + pub data: T, + pub post_info: PostDispatchInfo, +} + +impl From for WithPostDispatchInfo { + fn from(data: T) -> Self { + Self { + data, + post_info: Default::default(), + } + } +} + +pub type ResultWithPostInfo = + core::result::Result, WithPostDispatchInfo>; --- a/crates/evm-coder/src/lib.rs +++ b/crates/evm-coder/src/lib.rs @@ -3,10 +3,11 @@ extern crate alloc; use abi::{AbiRead, AbiReader, AbiWriter}; -pub use evm_coder_macros::{event_topic, fn_selector, solidity_interface, solidity, ToLog}; +pub use evm_coder_macros::{event_topic, fn_selector, solidity_interface, solidity, weight, ToLog}; pub mod abi; pub mod events; pub use events::ToLog; +use execution::DispatchInfo; pub mod execution; pub mod solidity; @@ -57,8 +58,14 @@ fn parse(selector: u32, input: &mut AbiReader) -> execution::Result>; } +pub type Weight = u64; + +pub trait Weighted: Call { + fn weight(&self) -> DispatchInfo; +} + pub trait Callable { - fn call(&mut self, call: types::Msg) -> execution::Result; + fn call(&mut self, call: types::Msg) -> execution::ResultWithPostInfo; } /// Implementation is implicitly provided for all interfaces @@ -84,15 +91,20 @@ } } +/// Generate "tests", which will generate solidity code on execution and print it to stdout +/// Script at .maintain/scripts/generate_api.sh can split this output from test runtime +/// +/// This macro receives type usage as second argument, but you can use anything as generics, +/// because no bounds are implied #[macro_export] macro_rules! generate_stubgen { - ($name:ident, $decl:ident, $is_impl:literal) => { + ($name:ident, $decl:ty, $is_impl:literal) => { #[test] #[ignore] fn $name() { use evm_coder::solidity::TypeCollector; let mut out = TypeCollector::new(); - $decl::generate_solidity_interface(&mut out, $is_impl); + <$decl>::generate_solidity_interface(&mut out, $is_impl); println!("=== SNIP START ==="); println!("// SPDX-License-Identifier: OTHER"); println!("// This code is automatically generated"); --- a/crates/evm-coder/src/solidity.rs +++ b/crates/evm-coder/src/solidity.rs @@ -84,6 +84,7 @@ solidity_type_name! { uint8 => "uint8" true = "0", uint32 => "uint32" true = "0", + uint64 => "uint64" true = "0", uint128 => "uint128" true = "0", uint256 => "uint256" true = "0", address => "address" true = "0x0000000000000000000000000000000000000000", @@ -376,6 +377,7 @@ Mutable, } pub struct SolidityFunction { + pub docs: &'static [&'static str], pub selector: &'static str, pub name: &'static str, pub args: A, @@ -389,6 +391,12 @@ writer: &mut impl fmt::Write, tc: &TypeCollector, ) -> fmt::Result { + for doc in self.docs { + writeln!(writer, "\t//{}", doc)?; + } + if !self.docs.is_empty() { + writeln!(writer, "\t//")?; + } writeln!(writer, "\t// Selector: {}", self.selector)?; write!(writer, "\tfunction {}(", self.name)?; self.args.solidity_name(writer, tc)?; @@ -449,6 +457,7 @@ } pub struct SolidityInterface { + pub selector: u32, pub name: &'static str, pub is: &'static [&'static str], pub functions: F, @@ -461,6 +470,9 @@ out: &mut impl fmt::Write, tc: &TypeCollector, ) -> fmt::Result { + if self.selector != 0 { + writeln!(out, "// Selector: {:0>8x}", self.selector)?; + } if is_impl { write!(out, "contract ")?; } else { --- a/crates/evm-coder/tests/a.rs +++ /dev/null @@ -1,89 +0,0 @@ -#![allow(dead_code)] // This test only checks that macros is not panicking - -use evm_coder::{solidity_interface, types::*, ToLog, execution::Result}; -use evm_coder_macros::solidity; - -struct Impls; - -#[solidity_interface(name = "OurInterface")] -impl Impls { - fn fn_a(&self, _input: uint256) -> Result { - todo!() - } -} - -#[solidity_interface(name = "OurInterface1")] -impl Impls { - fn fn_b(&self, _input: uint128) -> Result { - todo!() - } -} - -#[solidity_interface( - name = "OurInterface2", - is(OurInterface), - inline_is(OurInterface1), - events(ERC721Log) -)] -impl Impls { - #[solidity(rename_selector = "fnK")] - fn fn_c(&self, _input: uint32) -> Result { - todo!() - } - fn fn_d(&self, _value: uint32) -> Result { - todo!() - } - - fn caller_sensitive(&self, _caller: caller) -> Result { - todo!() - } - fn payable(&mut self, _value: value) -> Result { - todo!() - } -} - -#[derive(ToLog)] -enum ERC721Log { - Transfer { - #[indexed] - from: address, - #[indexed] - to: address, - value: uint256, - }, - Eee { - #[indexed] - aaa: address, - bbb: uint256, - }, -} - -struct ERC20; - -#[solidity_interface(name = "ERC20")] -impl ERC20 { - fn decimals(&self) -> Result { - todo!() - } - fn balance_of(&self, _owner: address) -> Result { - todo!() - } - fn transfer(&mut self, _caller: caller, _to: address, _value: uint256) -> Result { - todo!() - } - fn transfer_from( - &mut self, - _caller: caller, - _from: address, - _to: address, - _value: uint256, - ) -> Result { - todo!() - } - fn approve(&mut self, _caller: caller, _spender: address, _value: uint256) -> Result { - todo!() - } - fn allowance(&self, _owner: address, _spender: address) -> Result { - todo!() - } -} --- /dev/null +++ b/crates/evm-coder/tests/generics.rs @@ -0,0 +1,20 @@ +use std::marker::PhantomData; +use evm_coder::{execution::Result, generate_stubgen, solidity_interface, types::*}; + +struct Generic(PhantomData); + +#[solidity_interface(name = "GenericIs")] +impl Generic { + fn test_1(&self) -> Result { + todo!() + } +} + +#[solidity_interface(name = "Generic", is(GenericIs))] +impl> Generic { + fn test_2(&self) -> Result { + todo!() + } +} + +generate_stubgen!(gen_iface, GenericCall<()>, false); --- /dev/null +++ b/crates/evm-coder/tests/log.rs @@ -0,0 +1,19 @@ +#![allow(dead_code)] + +use evm_coder::{ToLog, types::*}; + +#[derive(ToLog)] +enum ERC721Log { + Transfer { + #[indexed] + from: address, + #[indexed] + to: address, + value: uint256, + }, + Eee { + #[indexed] + aaa: address, + bbb: uint256, + }, +} --- /dev/null +++ b/crates/evm-coder/tests/random.rs @@ -0,0 +1,65 @@ +#![allow(dead_code)] // This test only checks that macros is not panicking + +use evm_coder::{ToLog, execution::Result, solidity_interface, types::*}; +use evm_coder_macros::{solidity, weight}; + +struct Impls; + +#[solidity_interface(name = "OurInterface")] +impl Impls { + fn fn_a(&self, _input: uint256) -> Result { + todo!() + } +} + +#[solidity_interface(name = "OurInterface1")] +impl Impls { + fn fn_b(&self, _input: uint128) -> Result { + todo!() + } +} + +#[derive(ToLog)] +enum OurEvents { + Event1 { + field1: uint32, + }, + Event2 { + field1: uint32, + #[indexed] + field2: uint32, + }, +} + +#[solidity_interface( + name = "OurInterface2", + is(OurInterface), + inline_is(OurInterface1), + events(OurEvents) +)] +impl Impls { + #[solidity(rename_selector = "fnK")] + fn fn_c(&self, _input: uint32) -> Result { + todo!() + } + fn fn_d(&self, _value: uint32) -> Result { + todo!() + } + + fn caller_sensitive(&self, _caller: caller) -> Result { + todo!() + } + fn payable(&mut self, _value: value) -> Result { + todo!() + } + + #[weight(*_weight)] + fn with_weight(&self, _weight: uint64) -> Result { + todo!() + } + + /// Doccoment example + fn with_doc(&self) -> Result { + todo!() + } +} --- /dev/null +++ b/crates/evm-coder/tests/solidity_generation.rs @@ -0,0 +1,35 @@ +use evm_coder::{execution::Result, generate_stubgen, solidity_interface, types::*}; + +struct ERC20; + +#[solidity_interface(name = "ERC20")] +impl ERC20 { + fn decimals(&self) -> Result { + todo!() + } + /// Get balance of specified owner + fn balance_of(&self, _owner: address) -> Result { + todo!() + } + fn transfer(&mut self, _caller: caller, _to: address, _value: uint256) -> Result { + todo!() + } + fn transfer_from( + &mut self, + _caller: caller, + _from: address, + _to: address, + _value: uint256, + ) -> Result { + todo!() + } + fn approve(&mut self, _caller: caller, _spender: address, _value: uint256) -> Result { + todo!() + } + fn allowance(&self, _owner: address, _spender: address) -> Result { + todo!() + } +} + +generate_stubgen!(gen_impl, ERC20Call, true); +generate_stubgen!(gen_iface, ERC20Call, false); --- /dev/null +++ b/launch-config-westend.json @@ -0,0 +1,152 @@ +{ + "relaychain": { + "bin": "../polkadot/target/release/polkadot", + "chain": "westend-local", + "nodes": [ + { + "name": "alice", + "wsPort": 9844, + "rpcPort": 9843, + "port": 30444, + "flags": [ + "--rpc-port=9843", + "-lparachain::candidate_validation=debug" + ] + }, + { + "name": "bob", + "wsPort": 9855, + "rpcPort": 9854, + "port": 30555, + "flags": [ + "--rpc-port=9854", + "-lparachain::candidate_validation=debug" + ] + }, + { + "name": "charlie", + "wsPort": 9866, + "rpcPort": 9865, + "port": 30666, + "flags": [ + "--rpc-port=9865", + "-lparachain::candidate_validation=debug" + ] + }, + { + "name": "dave", + "wsPort": 9877, + "rpcPort": 9876, + "port": 30777, + "flags": [ + "--rpc-port=9876", + "-lparachain::candidate_validation=debug" + ] + }, + { + "name": "eve", + "wsPort": 9888, + "rpcPort": 9886, + "port": 30888, + "flags": [ + "--rpc-port=9886", + "-lparachain::candidate_validation=debug" + ] + }, + { + "name": "ferdie", + "wsPort": 9897, + "rpcPort": 9896, + "port": 30999, + "flags": [ + "--rpc-port=9896", + "-lparachain::candidate_validation=debug" + ] + } + ], + "genesis": { + "runtime": { + "runtime_genesis_config": { + "parachainsConfiguration": { + "config": { + "validation_upgrade_frequency": 1, + "validation_upgrade_delay": 1 + } + } + } + } + } + }, + "parachains": [ + { + "bin": "../unique-chain/target/release/unique-collator", + "chain": "westend-local", + "balance": "1000000000000000000000000", + "nodes": [ + { + "port": 31200, + "wsPort": 9944, + "rpcPort": 9933, + "name": "alice", + "flags": [ + "--rpc-cors=all", + "--rpc-port=9933", + "--unsafe-rpc-external", + "--unsafe-ws-external" + ] + }, + { + "port": 31201, + "wsPort": 9945, + "rpcPort": 9934, + "name": "bob", + "flags": [ + "--rpc-cors=all", + "--rpc-port=9934", + "--unsafe-rpc-external", + "--unsafe-ws-external" + ] + }, + { + "port": 31202, + "wsPort": 9946, + "rpcPort": 9935, + "name": "charlie", + "flags": [ + "--rpc-cors=all", + "--rpc-port=9935", + "--unsafe-rpc-external", + "--unsafe-ws-external" + ] + }, + { + "port": 31203, + "wsPort": 9947, + "rpcPort": 9936, + "name": "dave", + "flags": [ + "--rpc-cors=all", + "--rpc-port=9936", + "--unsafe-rpc-external", + "--unsafe-ws-external" + ] + }, + { + "port": 31204, + "wsPort": 9948, + "rpcPort": 9937, + "name": "eve", + "flags": [ + "--rpc-cors=all", + "--rpc-port=9937", + "--unsafe-rpc-external", + "--unsafe-ws-external" + ] + } + ] + } + ], + "simpleParachains": [], + "hrmpChannels": [], + "finalization": false +} --- a/launch-config.json +++ b/launch-config.json @@ -57,7 +57,7 @@ { "bin": "../unique-chain/target/release/unique-collator", "id": "2000", - "balance": "1000000000000000000000", + "balance": "1000000000000000000000000", "nodes": [ { "port": 31200, --- a/node/cli/Cargo.toml +++ b/node/cli/Cargo.toml @@ -268,13 +268,13 @@ jsonrpc-core = '18.0.0' jsonrpc-pubsub = "18.0.0" -fc-rpc-core = { git = "https://github.com/uniquenetwork/frontier.git", branch = "unique-polkadot-v0.9.12" } -fc-consensus = { git = "https://github.com/uniquenetwork/frontier.git", branch = "unique-polkadot-v0.9.12" } -fc-mapping-sync = { git = "https://github.com/uniquenetwork/frontier.git", branch = "unique-polkadot-v0.9.12" } -fc-rpc = { git = "https://github.com/uniquenetwork/frontier.git", branch = "unique-polkadot-v0.9.12" } -fc-db = { git = "https://github.com/uniquenetwork/frontier.git", branch = "unique-polkadot-v0.9.12" } -fp-rpc = { git = "https://github.com/uniquenetwork/frontier.git", branch = "unique-polkadot-v0.9.12" } -pallet-ethereum = { git = "https://github.com/uniquenetwork/frontier.git", branch = "unique-polkadot-v0.9.12" } +fc-rpc-core = { git = "https://github.com/uniquenetwork/frontier.git", branch = "unique-polkadot-v0.9.12-weights" } +fc-consensus = { git = "https://github.com/uniquenetwork/frontier.git", branch = "unique-polkadot-v0.9.12-weights" } +fc-mapping-sync = { git = "https://github.com/uniquenetwork/frontier.git", branch = "unique-polkadot-v0.9.12-weights" } +fc-rpc = { git = "https://github.com/uniquenetwork/frontier.git", branch = "unique-polkadot-v0.9.12-weights" } +fc-db = { git = "https://github.com/uniquenetwork/frontier.git", branch = "unique-polkadot-v0.9.12-weights" } +fp-rpc = { git = "https://github.com/uniquenetwork/frontier.git", branch = "unique-polkadot-v0.9.12-weights" } +pallet-ethereum = { git = "https://github.com/uniquenetwork/frontier.git", branch = "unique-polkadot-v0.9.12-weights" } unique-rpc = { path = "../rpc" } --- a/node/cli/src/chain_spec.rs +++ b/node/cli/src/chain_spec.rs @@ -53,9 +53,9 @@ pub fn development_config(id: ParaId) -> ChainSpec { let mut properties = Map::new(); - properties.insert("tokenSymbol".into(), "testUNQ".into()); + properties.insert("tokenSymbol".into(), "OPL".into()); properties.insert("tokenDecimals".into(), 15.into()); - properties.insert("ss58Format".into(), 42.into()); // Generic Substrate wildcard (SS58 checksum preimage) + properties.insert("ss58Format".into(), 42.into()); ChainSpec::from_genesis( // Name @@ -95,7 +95,7 @@ ) } -pub fn local_testnet_config(id: ParaId) -> ChainSpec { +pub fn local_testnet_rococo_config(id: ParaId) -> ChainSpec { ChainSpec::from_genesis( // Name "Local Testnet", @@ -144,6 +144,58 @@ ) } +pub fn local_testnet_westend_config(id: ParaId) -> ChainSpec { + ChainSpec::from_genesis( + // Name + "Local Testnet", + // ID + "local_testnet", + ChainType::Local, + move || { + testnet_genesis( + // Sudo account + get_account_id_from_seed::("Alice"), + vec![ + get_from_seed::("Alice"), + get_from_seed::("Bob"), + get_from_seed::("Charlie"), + get_from_seed::("Dave"), + get_from_seed::("Eve"), + ], + // Pre-funded accounts + vec![ + get_account_id_from_seed::("Alice"), + get_account_id_from_seed::("Bob"), + get_account_id_from_seed::("Charlie"), + get_account_id_from_seed::("Dave"), + get_account_id_from_seed::("Eve"), + get_account_id_from_seed::("Ferdie"), + get_account_id_from_seed::("Alice//stash"), + get_account_id_from_seed::("Bob//stash"), + get_account_id_from_seed::("Charlie//stash"), + get_account_id_from_seed::("Dave//stash"), + get_account_id_from_seed::("Eve//stash"), + get_account_id_from_seed::("Ferdie//stash"), + ], + id, + ) + }, + // Bootnodes + vec![], + // Telemetry + None, + // Protocol ID + None, + // Properties + None, + // Extensions + Extensions { + relay_chain: "westend-local".into(), + para_id: id.into(), + }, + ) +} + fn testnet_genesis( root_key: AccountId, initial_authorities: Vec, @@ -161,7 +213,8 @@ balances: endowed_accounts .iter() .cloned() - .map(|k| (k, 1 << 70)) + // 1e13 UNQ + .map(|k| (k, 1 << 100)) .collect(), }, treasury: Default::default(), --- a/node/cli/src/command.rs +++ b/node/cli/src/command.rs @@ -42,8 +42,9 @@ para_id: ParaId, ) -> std::result::Result, String> { Ok(match id { + "westend-local" => Box::new(chain_spec::local_testnet_westend_config(para_id)), "dev" => Box::new(chain_spec::development_config(para_id)), - "" | "local" => Box::new(chain_spec::local_testnet_config(para_id)), + "" | "local" => Box::new(chain_spec::local_testnet_rococo_config(para_id)), path => Box::new(chain_spec::ChainSpec::from_json_file( std::path::PathBuf::from(path), )?), @@ -84,7 +85,7 @@ } fn load_spec(&self, id: &str) -> std::result::Result, String> { - load_spec(id, self.run.parachain_id.unwrap_or(200).into()) + load_spec(id, self.run.parachain_id.unwrap_or(2000).into()) } fn native_runtime_version(_: &Box) -> &'static RuntimeVersion { @@ -217,7 +218,7 @@ let block: Block = generate_genesis_block(&load_spec( ¶ms.chain.clone().unwrap_or_default(), - params.parachain_id.unwrap_or(200).into(), + params.parachain_id.unwrap_or(2000).into(), )?)?; let raw_header = block.header().encode(); let output_buf = if params.raw { @@ -280,7 +281,7 @@ .chain(cli.relaychain_args.iter()), ); - let id = ParaId::from(cli.run.parachain_id.or(para_id).unwrap_or(200)); + let id = ParaId::from(cli.run.parachain_id.or(para_id).unwrap_or(2000)); let parachain_account = AccountIdConversion::::into_account(&id); --- a/node/rpc/Cargo.toml +++ b/node/rpc/Cargo.toml @@ -3,7 +3,7 @@ version = "0.1.0" authors = ['Unique Network '] license = 'All Rights Reserved' -edition = "2018" +edition = "2021" description = "Unique chain rpc" [package.metadata.docs.rs] @@ -41,12 +41,12 @@ substrate-frame-rpc-system = { git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.12' } tokio = { version = "0.2.25", features = ["macros", "sync"] } -pallet-ethereum = { git = "https://github.com/uniquenetwork/frontier.git", branch = "unique-polkadot-v0.9.12" } -fc-rpc = { default-features = false, git = "https://github.com/uniquenetwork/frontier.git", branch = "unique-polkadot-v0.9.12" } -fp-rpc = { default-features = false, git = "https://github.com/uniquenetwork/frontier.git", branch = "unique-polkadot-v0.9.12" } -fc-rpc-core = { default-features = false, git = "https://github.com/uniquenetwork/frontier.git", branch = "unique-polkadot-v0.9.12" } -fc-db = { default-features = false, git = "https://github.com/uniquenetwork/frontier.git", branch = "unique-polkadot-v0.9.12" } -fc-mapping-sync = { default-features = false, git = "https://github.com/uniquenetwork/frontier.git", branch = "unique-polkadot-v0.9.12" } +pallet-ethereum = { git = "https://github.com/uniquenetwork/frontier.git", branch = "unique-polkadot-v0.9.12-weights" } +fc-rpc = { default-features = false, git = "https://github.com/uniquenetwork/frontier.git", branch = "unique-polkadot-v0.9.12-weights" } +fp-rpc = { default-features = false, git = "https://github.com/uniquenetwork/frontier.git", branch = "unique-polkadot-v0.9.12-weights" } +fc-rpc-core = { default-features = false, git = "https://github.com/uniquenetwork/frontier.git", branch = "unique-polkadot-v0.9.12-weights" } +fc-db = { default-features = false, git = "https://github.com/uniquenetwork/frontier.git", branch = "unique-polkadot-v0.9.12-weights" } +fc-mapping-sync = { default-features = false, git = "https://github.com/uniquenetwork/frontier.git", branch = "unique-polkadot-v0.9.12-weights" } pallet-unique = { path = "../../pallets/unique" } uc-rpc = { path = "../../client/rpc" } --- a/node/rpc/src/lib.rs +++ b/node/rpc/src/lib.rs @@ -214,7 +214,7 @@ 500_usize, // max stored filters overrides.clone(), max_past_logs, - block_data_cache.clone(), + block_data_cache, ))); } --- a/pallets/common/Cargo.toml +++ b/pallets/common/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "pallet-common" version = "0.1.0" -edition = "2018" +edition = "2021" [dependencies.codec] default-features = false @@ -19,7 +19,7 @@ up-data-structs = { default-features = false, path = '../../primitives/data-structs' } pallet-evm-coder-substrate = { default-features = false, path = '../../pallets/evm-coder-substrate' } evm-coder = { default-features = false, path = '../../crates/evm-coder' } -pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier.git", branch = "unique-polkadot-v0.9.12" } +pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier.git", branch = "unique-polkadot-v0.9.12-weights" } serde = { version = "1.0.130", default-features = false } scale-info = { version = "1.0.0", default-features = false, features = [ "derive", --- a/pallets/common/src/benchmarking.rs +++ b/pallets/common/src/benchmarking.rs @@ -54,7 +54,6 @@ variable_on_chain_schema, const_on_chain_schema, meta_update_permission: Default::default(), - transfers_enabled: true, }) .and_then(CollectionHandle::try_get) .map(cast) --- a/pallets/common/src/erc.rs +++ b/pallets/common/src/erc.rs @@ -1,4 +1,5 @@ pub use pallet_evm::PrecompileOutput; +pub use pallet_evm::PrecompileResult; use sp_core::{H160, U256}; /// Does not always represent a full collection, for RFT it is either @@ -6,5 +7,5 @@ pub trait CommonEvmHandler { const CODE: &'static [u8]; - fn call(self, source: &H160, input: &[u8], value: U256) -> Option; + fn call(self, source: &H160, input: &[u8], value: U256) -> Option; } --- a/pallets/common/src/lib.rs +++ b/pallets/common/src/lib.rs @@ -1,6 +1,7 @@ #![cfg_attr(not(feature = "std"), no_std)] use core::ops::{Deref, DerefMut}; +use pallet_evm_coder_substrate::{SubstrateRecorder, WithRecorder}; use sp_std::vec::Vec; use account::CrossAccountId; use frame_support::{ @@ -8,6 +9,7 @@ ensure, fail, traits::{Imbalance, Get, Currency}, }; +use pallet_evm::GasWeightMapping; use up_data_structs::{ COLLECTION_NUMBER_LIMIT, Collection, CollectionId, CreateItemData, ExistenceRequirement, MAX_COLLECTION_DESCRIPTION_LENGTH, MAX_COLLECTION_NAME_LENGTH, MAX_TOKEN_PREFIX_LENGTH, @@ -27,52 +29,54 @@ pub struct CollectionHandle { pub id: CollectionId, collection: Collection, - pub recorder: pallet_evm_coder_substrate::SubstrateRecorder, + pub recorder: SubstrateRecorder, +} +impl WithRecorder for CollectionHandle { + fn recorder(&self) -> &SubstrateRecorder { + &self.recorder + } + fn into_recorder(self) -> SubstrateRecorder { + self.recorder + } } impl CollectionHandle { pub fn new_with_gas_limit(id: CollectionId, gas_limit: u64) -> Option { >::get(id).map(|collection| Self { id, collection, - recorder: pallet_evm_coder_substrate::SubstrateRecorder::new( - eth::collection_id_to_address(id), - gas_limit, - ), + recorder: SubstrateRecorder::new(eth::collection_id_to_address(id), gas_limit), }) } pub fn new(id: CollectionId) -> Option { Self::new_with_gas_limit(id, u64::MAX) } pub fn try_get(id: CollectionId) -> Result { - Ok(Self::new(id).ok_or_else(|| >::CollectionNotFound)?) - } - pub fn log(&self, log: impl evm_coder::ToLog) -> DispatchResult { - self.recorder.log_sub(log) - } - pub fn log_infallible(&self, log: impl evm_coder::ToLog) { - self.recorder.log_infallible(log) + Ok(Self::new(id).ok_or(>::CollectionNotFound)?) } - #[allow(dead_code)] - fn consume_gas(&self, gas: u64) -> DispatchResult { - self.recorder.consume_gas_sub(gas) - } - pub fn consume_sload(&self) -> DispatchResult { - self.recorder.consume_sload_sub() - } - pub fn consume_sstores(&self, amount: usize) -> DispatchResult { - self.recorder.consume_sstores_sub(amount) + pub fn log(&self, log: impl evm_coder::ToLog) { + self.recorder.log(log) } - pub fn consume_sstore(&self) -> DispatchResult { - self.recorder.consume_sstore_sub() + pub fn consume_store_reads(&self, reads: u64) -> evm_coder::execution::Result<()> { + self.recorder + .consume_gas(T::GasWeightMapping::weight_to_gas( + ::DbWeight::get() + .read + .saturating_mul(reads), + )) } - pub fn consume_log(&self, topics: usize, data: usize) -> DispatchResult { - self.recorder.consume_log_sub(topics, data) + pub fn consume_store_writes(&self, writes: u64) -> evm_coder::execution::Result<()> { + self.recorder + .consume_gas(T::GasWeightMapping::weight_to_gas( + ::DbWeight::get() + .write + .saturating_mul(writes), + )) } - pub fn submit_logs(self) -> DispatchResult { + pub fn submit_logs(self) { self.recorder.submit_logs() } pub fn save(self) -> DispatchResult { - self.recorder.submit_logs()?; + self.recorder.submit_logs(); >::insert(self.id, self.collection); Ok(()) } @@ -96,24 +100,20 @@ ensure!(*subject.as_sub() == self.owner, >::NoPermission); Ok(()) } - pub fn is_owner_or_admin(&self, subject: &T::CrossAccountId) -> Result { - self.consume_sload()?; - - Ok(*subject.as_sub() == self.owner || >::get((self.id, subject))) + pub fn is_owner_or_admin(&self, subject: &T::CrossAccountId) -> bool { + *subject.as_sub() == self.owner || >::get((self.id, subject)) } pub fn check_is_owner_or_admin(&self, subject: &T::CrossAccountId) -> DispatchResult { - ensure!(self.is_owner_or_admin(subject)?, >::NoPermission); + ensure!(self.is_owner_or_admin(subject), >::NoPermission); Ok(()) } - pub fn ignores_allowance(&self, user: &T::CrossAccountId) -> Result { - Ok(self.limits.owner_can_transfer() && self.is_owner_or_admin(user)?) + pub fn ignores_allowance(&self, user: &T::CrossAccountId) -> bool { + self.limits.owner_can_transfer() && self.is_owner_or_admin(user) } - pub fn ignores_owned_amount(&self, user: &T::CrossAccountId) -> Result { - Ok(self.limits.owner_can_transfer() && self.is_owner_or_admin(user)?) + pub fn ignores_owned_amount(&self, user: &T::CrossAccountId) -> bool { + self.limits.owner_can_transfer() && self.is_owner_or_admin(user) } pub fn check_allowlist(&self, user: &T::CrossAccountId) -> DispatchResult { - self.consume_sload()?; - ensure!( >::get((self.id, user)), >::AddressNotInAllowlist @@ -187,6 +187,13 @@ /// * account_id: Collection owner. CollectionCreated(CollectionId, u8, T::AccountId), + /// New collection was destroyed + /// + /// # Arguments + /// + /// * collection_id: Globally unique identifier of collection. + CollectionDestroyed(CollectionId), + /// New item was created. /// /// # Arguments @@ -410,7 +417,7 @@ // bound Total number of collections ensure!( - created_count - destroyed_count < COLLECTION_NUMBER_LIMIT, + created_count - destroyed_count <= COLLECTION_NUMBER_LIMIT, >::TotalCollectionsLimitExceeded ); @@ -453,7 +460,7 @@ collection.limits.owner_can_destroy(), >::NoPermission, ); - collection.check_is_owner(&sender)?; + collection.check_is_owner(sender)?; let destroyed_collections = >::get() .0 @@ -467,6 +474,8 @@ >::remove(collection.id); >::remove_prefix((collection.id,), None); >::remove_prefix((collection.id,), None); + + >::deposit_event(Event::CollectionDestroyed(collection.id)); Ok(()) } @@ -476,7 +485,7 @@ user: &T::CrossAccountId, allowed: bool, ) -> DispatchResult { - collection.check_is_owner_or_admin(&sender)?; + collection.check_is_owner_or_admin(sender)?; // ========= @@ -495,7 +504,7 @@ user: &T::CrossAccountId, admin: bool, ) -> DispatchResult { - collection.check_is_owner_or_admin(&sender)?; + collection.check_is_owner_or_admin(sender)?; let was_admin = >::get((collection.id, user)); if was_admin == admin { --- a/pallets/contract-helpers/Cargo.toml +++ b/pallets/contract-helpers/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "pallet-contract-helpers" version = "0.1.0" -edition = "2018" +edition = "2021" [dependencies.codec] default-features = false @@ -16,7 +16,7 @@ pallet-contracts = { default-features = false, git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.12' } sp-runtime = { default-features = false, git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.12' } sp-std = { default-features = false, git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.12' } -up-sponsorship = { version = "0.1.0", default-features = false, git = "https://github.com/UniqueNetwork/pallet-sponsoring" } +up-sponsorship = { version = "0.1.0", default-features = false, git = "https://github.com/UniqueNetwork/pallet-sponsoring" } [features] default = ["std"] --- a/pallets/evm-coder-substrate/Cargo.toml +++ b/pallets/evm-coder-substrate/Cargo.toml @@ -1,18 +1,21 @@ [package] name = "pallet-evm-coder-substrate" version = "0.1.0" -edition = "2018" +edition = "2021" [dependencies] -scale-info = { version = "1.0.0", default-features = false, features = ["derive"] } +scale-info = { version = "1.0.0", default-features = false, features = [ + "derive", +] } sp-std = { default-features = false, git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.12' } sp-core = { default-features = false, git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.12' } -ethereum = { version = "0.9", git = "https://github.com/purestake/ethereum", branch = "joshy-scale-info", default-features = false } +ethereum = { version = "0.10.0", default-features = false } evm-coder = { default-features = false, path = "../../crates/evm-coder" } -pallet-ethereum = { default-features = false, git = "https://github.com/uniquenetwork/frontier.git", branch = "unique-polkadot-v0.9.12" } -pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier.git", branch = "unique-polkadot-v0.9.12" } +pallet-ethereum = { default-features = false, git = "https://github.com/uniquenetwork/frontier.git", branch = "unique-polkadot-v0.9.12-weights" } +pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier.git", branch = "unique-polkadot-v0.9.12-weights" } frame-support = { default-features = false, git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.12' } frame-system = { default-features = false, git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.12' } +frame-benchmarking = { default-features = false, optional = true, git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.12' } [dependencies.codec] default-features = false @@ -31,4 +34,6 @@ "pallet-evm/std", "frame-support/std", "frame-system/std", + 'frame-benchmarking/std', ] +runtime-benchmarks = ['frame-benchmarking'] --- /dev/null +++ b/pallets/evm-coder-substrate/src/benchmarking.rs @@ -0,0 +1,8 @@ +use super::*; + +use frame_benchmarking::benchmarks; + +benchmarks! { + // gas_per_second { + // }: (pallet_evm::) +} --- a/pallets/evm-coder-substrate/src/lib.rs +++ b/pallets/evm-coder-substrate/src/lib.rs @@ -2,6 +2,8 @@ #[cfg(not(feature = "std"))] extern crate alloc; +// #[cfg(feature = "runtime-benchmarks")] +// pub mod benchmarking; pub use pallet::*; @@ -17,7 +19,11 @@ types::{Msg, value}, }; use frame_support::{ensure}; - use pallet_evm::{ExitError, ExitReason, ExitRevert, ExitSucceed, PrecompileOutput}; + use pallet_evm::{ + ExitError, ExitRevert, ExitSucceed, GasWeightMapping, PrecompileFailure, PrecompileOutput, + PrecompileResult, + }; + use frame_system::ensure_signed; pub use frame_support::dispatch::DispatchResult; use pallet_ethereum::EthereumTransactionSender; use sp_std::cell::RefCell; @@ -25,6 +31,7 @@ use sp_core::{H160, H256}; use ethereum::Log; use frame_support::{pallet_prelude::*, traits::PalletInfo}; + use frame_system::pallet_prelude::*; /// DispatchError is opaque, but we need to somehow extract correct error in case of OutOfGas failure /// So we have this pallet, which defines OutOfGas error, and knews its own id to check if DispatchError @@ -40,26 +47,25 @@ #[pallet::config] pub trait Config: frame_system::Config { type EthereumTransactionSender: pallet_ethereum::EthereumTransactionSender; + type GasWeightMapping: pallet_evm::GasWeightMapping; } #[pallet::pallet] pub struct Pallet(_); - // FIXME: those items are defined as private in evm_gasometer::consts, and we can't directly use it - pub const G_LOG: u64 = 375; - pub const G_LOGDATA: u64 = 8; - pub const G_LOGTOPIC: u64 = 375; + #[pallet::call] + impl Pallet { + #[pallet::weight(0)] + pub fn empty_call(origin: OriginFor) -> DispatchResult { + let _sender = ensure_signed(origin)?; + Ok(()) + } + } // From instabul hardfork configuration: https://github.com/rust-blockchain/evm/blob/fd4fd6acc0ca3208d6770fdb3ba407c94cdf97c6/runtime/src/lib.rs#L284 pub const G_SLOAD_WORD: u64 = 800; pub const G_SSTORE_WORD: u64 = 20000; - fn log_price(data: usize, topics: usize) -> u64 { - G_LOG - .saturating_add((data as u64).saturating_mul(G_LOGDATA)) - .saturating_add((topics as u64).saturating_mul(G_LOGTOPIC)) - } - pub fn generate_transaction() -> ethereum::TransactionV0 { use ethereum::{TransactionV0, TransactionAction, TransactionSignature}; TransactionV0 { @@ -97,17 +103,11 @@ pub fn is_empty(&self) -> bool { self.logs.borrow().is_empty() - } - pub fn log_sub(&self, log: impl ToLog) -> DispatchResult { - self.log_raw_sub(log.to_log(self.contract)) } - pub fn log_raw_sub(&self, log: Log) -> DispatchResult { - self.consume_gas_sub(log_price(log.data.len(), log.topics.len()))?; - self.logs.borrow_mut().push(log); - Ok(()) - } + // TODO: Replace with real storage in pallet-ethereum, + // same way as it is done with frame_system's Events /// Doesn't consumes any gas, should be used after consume_log_sub - pub fn log_infallible(&self, log: impl ToLog) { + pub fn log(&self, log: impl ToLog) { self.logs.borrow_mut().push(log.to_log(self.contract)); } pub fn retrieve_logs(self) -> Vec { @@ -125,9 +125,6 @@ } pub fn consume_sstore_sub(&self) -> DispatchResult { self.consume_gas_sub(G_SSTORE_WORD) - } - pub fn consume_log_sub(&self, topics: usize, data: usize) -> DispatchResult { - self.consume_gas_sub(log_price(data, topics)) } pub fn consume_gas_sub(&self, gas: u64) -> DispatchResult { ensure!(gas != u64::MAX, Error::::OutOfGas); @@ -154,39 +151,49 @@ *gas_limit -= gas; Ok(()) } + pub fn return_gas(&self, gas: u64) { + let mut gas_limit = self.gas_limit.borrow_mut(); + *gas_limit += gas; + } pub fn evm_to_precompile_output( self, result: evm_coder::execution::Result>, - ) -> Option { + ) -> Option { use evm_coder::execution::Error; - let (writer, reason) = match result { - Ok(Some(v)) => (v, ExitReason::Succeed(ExitSucceed::Returned)), + Some(match result { + Ok(Some(v)) => Ok(PrecompileOutput { + exit_status: ExitSucceed::Returned, + cost: self.initial_gas - self.gas_left(), + logs: self.retrieve_logs(), + output: v.finish(), + }), Ok(None) => return None, Err(Error::Revert(e)) => { let mut writer = AbiWriter::new_call(evm_coder::fn_selector!(Error(string))); (&e as &str).abi_write(&mut writer); - (writer, ExitReason::Revert(ExitRevert::Reverted)) + Err(PrecompileFailure::Revert { + exit_status: ExitRevert::Reverted, + cost: self.initial_gas - self.gas_left(), + output: writer.finish(), + }) } - Err(Error::Fatal(f)) => (AbiWriter::new(), ExitReason::Fatal(f)), - Err(Error::Error(e)) => (AbiWriter::new(), ExitReason::Error(e)), - }; - - Some(PrecompileOutput { - cost: self.initial_gas - self.gas_left(), - exit_status: reason, - logs: self.retrieve_logs(), - output: writer.finish(), + Err(Error::Fatal(f)) => Err(f.into()), + Err(Error::Error(e)) => Err(e.into()), }) } - pub fn submit_logs(self) -> DispatchResult { + pub fn submit_logs(self) { let logs = self.retrieve_logs(); if logs.is_empty() { - return Ok(()); + return; } - T::EthereumTransactionSender::submit_logs_transaction(generate_transaction(), logs) + T::EthereumTransactionSender::submit_logs_transaction( + Default::default(), + generate_transaction(), + logs, + ) } } @@ -215,8 +222,32 @@ } } - pub fn call_internal>( + pub trait WithRecorder { + fn recorder(&self) -> &SubstrateRecorder; + fn into_recorder(self) -> SubstrateRecorder; + } + + /// Helper to simplify implementing bridge between evm-coder definitions and pallet-evm + pub fn call< + T: Config, + C: evm_coder::Call + evm_coder::Weighted, + E: evm_coder::Callable + WithRecorder, + >( caller: H160, + mut e: E, + value: value, + input: &[u8], + ) -> Option { + let result = call_internal(caller, &mut e, value, input); + e.into_recorder().evm_to_precompile_output(result) + } + + fn call_internal< + T: Config, + C: evm_coder::Call + evm_coder::Weighted, + E: evm_coder::Callable + WithRecorder, + >( + caller: H160, e: &mut E, value: value, input: &[u8], @@ -227,11 +258,28 @@ return Ok(None); } let call = call.unwrap(); - e.call(Msg { + + let dispatch_info = call.weight(); + e.recorder() + .consume_gas(T::GasWeightMapping::weight_to_gas(dispatch_info.weight))?; + + match e.call(Msg { call, caller, value, - }) - .map(Some) + }) { + Ok(v) => { + let unspent = v.post_info.calc_unspent(&dispatch_info); + e.recorder() + .return_gas(T::GasWeightMapping::weight_to_gas(unspent)); + Ok(Some(v.data)) + } + Err(v) => { + let unspent = v.post_info.calc_unspent(&dispatch_info); + e.recorder() + .return_gas(T::GasWeightMapping::weight_to_gas(unspent)); + Err(v.data) + } + } } } --- a/pallets/evm-contract-helpers/Cargo.toml +++ b/pallets/evm-contract-helpers/Cargo.toml @@ -1,10 +1,12 @@ [package] name = "pallet-evm-contract-helpers" version = "0.1.0" -edition = "2018" +edition = "2021" [dependencies] -scale-info = { version = "1.0.0", default-features = false, features = ["derive"] } +scale-info = { version = "1.0.0", default-features = false, features = [ + "derive", +] } frame-support = { default-features = false, git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.12' } frame-system = { default-features = false, git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.12' } sp-runtime = { default-features = false, git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.12' } @@ -12,8 +14,8 @@ sp-core = { default-features = false, git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.12' } evm-coder = { default-features = false, path = '../../crates/evm-coder' } pallet-evm-coder-substrate = { default-features = false, path = '../../pallets/evm-coder-substrate' } -pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier.git", branch = "unique-polkadot-v0.9.12" } -up-sponsorship = { version = "0.1.0", default-features = false, git = "https://github.com/UniqueNetwork/pallet-sponsoring" } +pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier.git", branch = "unique-polkadot-v0.9.12-weights" } +up-sponsorship = { version = "0.1.0", default-features = false, git = "https://github.com/UniqueNetwork/pallet-sponsoring" } log = "0.4.14" [dependencies.codec] --- /dev/null +++ b/pallets/evm-contract-helpers/exp.rs @@ -0,0 +1,1474 @@ +#![feature(prelude_import)] +#[prelude_import] +use std::prelude::rust_2018::*; +#[macro_use] +extern crate std; +pub use pallet::*; +pub use eth::*; +pub mod eth { + use core::marker::PhantomData; + use evm_coder::{abi::AbiWriter, execution::Result, generate_stubgen, solidity_interface, types::*}; + use pallet_evm_coder_substrate::{SubstrateRecorder, WithRecorder}; + use pallet_evm::{ExitReason, ExitRevert, OnCreate, OnMethodCall, PrecompileOutput}; + use sp_core::H160; + use crate::{ + AllowlistEnabled, Config, Owner, Pallet, SelfSponsoring, SponsorBasket, SponsoringRateLimit, + }; + use frame_support::traits::Get; + use up_sponsorship::SponsorshipHandler; + use sp_std::{convert::TryInto, vec::Vec}; + struct ContractHelpers(SubstrateRecorder); + impl WithRecorder for ContractHelpers { + fn recorder(&self) -> &SubstrateRecorder { + &self.0 + } + fn into_recorder(self) -> SubstrateRecorder { + self.0 + } + } + impl ContractHelpers { + fn contract_owner(&self, contract_address: address) -> Result
{ + Ok(>::get(contract_address)) + } + fn sponsoring_enabled(&self, contract_address: address) -> Result { + Ok(>::get(contract_address)) + } + fn toggle_sponsoring( + &mut self, + caller: caller, + contract_address: address, + enabled: bool, + ) -> Result { + >::ensure_owner(contract_address, caller)?; + >::toggle_sponsoring(contract_address, enabled); + Ok(()) + } + fn set_sponsoring_rate_limit( + &mut self, + caller: caller, + contract_address: address, + rate_limit: uint32, + ) -> Result { + >::ensure_owner(contract_address, caller)?; + >::set_sponsoring_rate_limit(contract_address, rate_limit.into()); + Ok(()) + } + fn get_sponsoring_rate_limit(&self, contract_address: address) -> Result { + Ok(>::get(contract_address) + .try_into() + .map_err(|_| "rate limit > u32::MAX")?) + } + fn allowed(&self, contract_address: address, user: address) -> Result { + Ok(>::allowed(contract_address, user, true)) + } + fn allowlist_enabled(&self, contract_address: address) -> Result { + Ok(>::get(contract_address)) + } + fn toggle_allowlist( + &mut self, + caller: caller, + contract_address: address, + enabled: bool, + ) -> Result { + >::ensure_owner(contract_address, caller)?; + >::toggle_allowlist(contract_address, enabled); + Ok(()) + } + fn toggle_allowed( + &mut self, + caller: caller, + contract_address: address, + user: address, + allowed: bool, + ) -> Result { + >::ensure_owner(contract_address, caller)?; + >::toggle_allowed(contract_address, user, allowed); + Ok(()) + } + } + pub enum ContractHelpersCall { + ERC165Call(::evm_coder::ERC165Call, PhantomData<(T)>), + ContractOwner { + contract_address: address, + }, + SponsoringEnabled { + contract_address: address, + }, + ToggleSponsoring { + contract_address: address, + enabled: bool, + }, + SetSponsoringRateLimit { + contract_address: address, + rate_limit: uint32, + }, + GetSponsoringRateLimit { + contract_address: address, + }, + Allowed { + contract_address: address, + user: address, + }, + AllowlistEnabled { + contract_address: address, + }, + ToggleAllowlist { + contract_address: address, + enabled: bool, + }, + ToggleAllowed { + contract_address: address, + user: address, + allowed: bool, + }, + } + #[automatically_derived] + #[allow(unused_qualifications)] + impl ::core::fmt::Debug for ContractHelpersCall { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + match (&*self,) { + (&ContractHelpersCall::ERC165Call(ref __self_0, ref __self_1),) => { + let debug_trait_builder = + &mut ::core::fmt::Formatter::debug_tuple(f, "ERC165Call"); + let _ = ::core::fmt::DebugTuple::field(debug_trait_builder, &&(*__self_0)); + let _ = ::core::fmt::DebugTuple::field(debug_trait_builder, &&(*__self_1)); + ::core::fmt::DebugTuple::finish(debug_trait_builder) + } + (&ContractHelpersCall::ContractOwner { + contract_address: ref __self_0, + },) => { + let debug_trait_builder = + &mut ::core::fmt::Formatter::debug_struct(f, "ContractOwner"); + let _ = ::core::fmt::DebugStruct::field( + debug_trait_builder, + "contract_address", + &&(*__self_0), + ); + ::core::fmt::DebugStruct::finish(debug_trait_builder) + } + (&ContractHelpersCall::SponsoringEnabled { + contract_address: ref __self_0, + },) => { + let debug_trait_builder = + &mut ::core::fmt::Formatter::debug_struct(f, "SponsoringEnabled"); + let _ = ::core::fmt::DebugStruct::field( + debug_trait_builder, + "contract_address", + &&(*__self_0), + ); + ::core::fmt::DebugStruct::finish(debug_trait_builder) + } + (&ContractHelpersCall::ToggleSponsoring { + contract_address: ref __self_0, + enabled: ref __self_1, + },) => { + let debug_trait_builder = + &mut ::core::fmt::Formatter::debug_struct(f, "ToggleSponsoring"); + let _ = ::core::fmt::DebugStruct::field( + debug_trait_builder, + "contract_address", + &&(*__self_0), + ); + let _ = ::core::fmt::DebugStruct::field( + debug_trait_builder, + "enabled", + &&(*__self_1), + ); + ::core::fmt::DebugStruct::finish(debug_trait_builder) + } + (&ContractHelpersCall::SetSponsoringRateLimit { + contract_address: ref __self_0, + rate_limit: ref __self_1, + },) => { + let debug_trait_builder = + &mut ::core::fmt::Formatter::debug_struct(f, "SetSponsoringRateLimit"); + let _ = ::core::fmt::DebugStruct::field( + debug_trait_builder, + "contract_address", + &&(*__self_0), + ); + let _ = ::core::fmt::DebugStruct::field( + debug_trait_builder, + "rate_limit", + &&(*__self_1), + ); + ::core::fmt::DebugStruct::finish(debug_trait_builder) + } + (&ContractHelpersCall::GetSponsoringRateLimit { + contract_address: ref __self_0, + },) => { + let debug_trait_builder = + &mut ::core::fmt::Formatter::debug_struct(f, "GetSponsoringRateLimit"); + let _ = ::core::fmt::DebugStruct::field( + debug_trait_builder, + "contract_address", + &&(*__self_0), + ); + ::core::fmt::DebugStruct::finish(debug_trait_builder) + } + (&ContractHelpersCall::Allowed { + contract_address: ref __self_0, + user: ref __self_1, + },) => { + let debug_trait_builder = + &mut ::core::fmt::Formatter::debug_struct(f, "Allowed"); + let _ = ::core::fmt::DebugStruct::field( + debug_trait_builder, + "contract_address", + &&(*__self_0), + ); + let _ = + ::core::fmt::DebugStruct::field(debug_trait_builder, "user", &&(*__self_1)); + ::core::fmt::DebugStruct::finish(debug_trait_builder) + } + (&ContractHelpersCall::AllowlistEnabled { + contract_address: ref __self_0, + },) => { + let debug_trait_builder = + &mut ::core::fmt::Formatter::debug_struct(f, "AllowlistEnabled"); + let _ = ::core::fmt::DebugStruct::field( + debug_trait_builder, + "contract_address", + &&(*__self_0), + ); + ::core::fmt::DebugStruct::finish(debug_trait_builder) + } + (&ContractHelpersCall::ToggleAllowlist { + contract_address: ref __self_0, + enabled: ref __self_1, + },) => { + let debug_trait_builder = + &mut ::core::fmt::Formatter::debug_struct(f, "ToggleAllowlist"); + let _ = ::core::fmt::DebugStruct::field( + debug_trait_builder, + "contract_address", + &&(*__self_0), + ); + let _ = ::core::fmt::DebugStruct::field( + debug_trait_builder, + "enabled", + &&(*__self_1), + ); + ::core::fmt::DebugStruct::finish(debug_trait_builder) + } + (&ContractHelpersCall::ToggleAllowed { + contract_address: ref __self_0, + user: ref __self_1, + allowed: ref __self_2, + },) => { + let debug_trait_builder = + &mut ::core::fmt::Formatter::debug_struct(f, "ToggleAllowed"); + let _ = ::core::fmt::DebugStruct::field( + debug_trait_builder, + "contract_address", + &&(*__self_0), + ); + let _ = + ::core::fmt::DebugStruct::field(debug_trait_builder, "user", &&(*__self_1)); + let _ = ::core::fmt::DebugStruct::field( + debug_trait_builder, + "allowed", + &&(*__self_2), + ); + ::core::fmt::DebugStruct::finish(debug_trait_builder) + } + } + } + } + impl ContractHelpersCall { + #[doc = "contractOwner(address)"] + const CONTRACT_OWNER: u32 = 1364373836u32; + #[doc = "sponsoringEnabled(address)"] + const SPONSORING_ENABLED: u32 = 1613225057u32; + #[doc = "toggleSponsoring(address,bool)"] + const TOGGLE_SPONSORING: u32 = 4239158662u32; + #[doc = "setSponsoringRateLimit(address,uint32)"] + const SET_SPONSORING_RATE_LIMIT: u32 = 2008467720u32; + #[doc = "getSponsoringRateLimit(address)"] + const GET_SPONSORING_RATE_LIMIT: u32 = 1628240573u32; + #[doc = "allowed(address,address)"] + const ALLOWED: u32 = 1550156133u32; + #[doc = "allowlistEnabled(address)"] + const ALLOWLIST_ENABLED: u32 = 3346198380u32; + #[doc = "toggleAllowlist(address,bool)"] + const TOGGLE_ALLOWLIST: u32 = 920527093u32; + #[doc = "toggleAllowed(address,address,bool)"] + const TOGGLE_ALLOWED: u32 = 1191627804u32; + pub const fn interface_id() -> u32 { + let mut interface_id = 0; + interface_id ^= Self::CONTRACT_OWNER; + interface_id ^= Self::SPONSORING_ENABLED; + interface_id ^= Self::TOGGLE_SPONSORING; + interface_id ^= Self::SET_SPONSORING_RATE_LIMIT; + interface_id ^= Self::GET_SPONSORING_RATE_LIMIT; + interface_id ^= Self::ALLOWED; + interface_id ^= Self::ALLOWLIST_ENABLED; + interface_id ^= Self::TOGGLE_ALLOWLIST; + interface_id ^= Self::TOGGLE_ALLOWED; + interface_id + } + pub fn supports_interface(interface_id: u32) -> bool { + interface_id != 0xffffff + && (interface_id == ::evm_coder::ERC165Call::INTERFACE_ID + || interface_id == Self::interface_id()) + } + pub fn generate_solidity_interface(tc: &evm_coder::solidity::TypeCollector, is_impl: bool) { + use evm_coder::solidity::*; + use core::fmt::Write; + let interface = SolidityInterface { + name: "ContractHelpers", + selector: Self::interface_id(), + is: &["Dummy", "ERC165"], + functions: ( + SolidityFunction { + docs: &[], + selector: "contractOwner(address) 5152b14c", + name: "contractOwner", + mutability: SolidityMutability::View, + args: (>::new("contractAddress"),), + result: >::default(), + }, + SolidityFunction { + docs: &[], + selector: "sponsoringEnabled(address) 6027dc61", + name: "sponsoringEnabled", + mutability: SolidityMutability::View, + args: (>::new("contractAddress"),), + result: >::default(), + }, + SolidityFunction { + docs: &[], + selector: "toggleSponsoring(address,bool) fcac6d86", + name: "toggleSponsoring", + mutability: SolidityMutability::Mutable, + args: ( + >::new("contractAddress"), + >::new("enabled"), + ), + result: >::default(), + }, + SolidityFunction { + docs: &[], + selector: "setSponsoringRateLimit(address,uint32) 77b6c908", + name: "setSponsoringRateLimit", + mutability: SolidityMutability::Mutable, + args: ( + >::new("contractAddress"), + >::new("rateLimit"), + ), + result: >::default(), + }, + SolidityFunction { + docs: &[], + selector: "getSponsoringRateLimit(address) 610cfabd", + name: "getSponsoringRateLimit", + mutability: SolidityMutability::View, + args: (>::new("contractAddress"),), + result: >::default(), + }, + SolidityFunction { + docs: &[], + selector: "allowed(address,address) 5c658165", + name: "allowed", + mutability: SolidityMutability::View, + args: ( + >::new("contractAddress"), + >::new("user"), + ), + result: >::default(), + }, + SolidityFunction { + docs: &[], + selector: "allowlistEnabled(address) c772ef6c", + name: "allowlistEnabled", + mutability: SolidityMutability::View, + args: (>::new("contractAddress"),), + result: >::default(), + }, + SolidityFunction { + docs: &[], + selector: "toggleAllowlist(address,bool) 36de20f5", + name: "toggleAllowlist", + mutability: SolidityMutability::Mutable, + args: ( + >::new("contractAddress"), + >::new("enabled"), + ), + result: >::default(), + }, + SolidityFunction { + docs: &[], + selector: "toggleAllowed(address,address,bool) 4706cc1c", + name: "toggleAllowed", + mutability: SolidityMutability::Mutable, + args: ( + >::new("contractAddress"), + >::new("user"), + >::new("allowed"), + ), + result: >::default(), + }, + ), + }; + if is_impl { + tc . collect ("// Common stubs holder\ncontract Dummy {\n\tuint8 dummy;\n\tstring stub_error = \"this contract is implemented in native\";\n}\ncontract ERC165 is Dummy {\n\tfunction supportsInterface(bytes4 interfaceID) external view returns (bool) {\n\t\trequire(false, stub_error);\n\t\tinterfaceID;\n\t\treturn true;\n\t}\n}\n" . into ()) ; + } else { + tc . collect ("// Common stubs holder\ninterface Dummy {\n}\ninterface ERC165 is Dummy {\n\tfunction supportsInterface(bytes4 interfaceID) external view returns (bool);\n}\n" . into ()) ; + } + let mut out = string::new(); + if "ContractHelpers".starts_with("Inline") { + out.push_str("// Inline\n"); + } + let _ = interface.format(is_impl, &mut out, tc); + tc.collect(out); + } + } + impl ::evm_coder::Call for ContractHelpersCall { + fn parse( + method_id: u32, + reader: &mut ::evm_coder::abi::AbiReader, + ) -> ::evm_coder::execution::Result> { + use ::evm_coder::abi::AbiRead; + match method_id { + ::evm_coder::ERC165Call::INTERFACE_ID => { + return Ok( + ::evm_coder::ERC165Call::parse(method_id, reader)?.map(Self::ERC165Call) + ) + } + Self::CONTRACT_OWNER => { + return Ok(Some(Self::ContractOwner { + contract_address: reader.abi_read()?, + })) + } + Self::SPONSORING_ENABLED => { + return Ok(Some(Self::SponsoringEnabled { + contract_address: reader.abi_read()?, + })) + } + Self::TOGGLE_SPONSORING => { + return Ok(Some(Self::ToggleSponsoring { + contract_address: reader.abi_read()?, + enabled: reader.abi_read()?, + })) + } + Self::SET_SPONSORING_RATE_LIMIT => { + return Ok(Some(Self::SetSponsoringRateLimit { + contract_address: reader.abi_read()?, + rate_limit: reader.abi_read()?, + })) + } + Self::GET_SPONSORING_RATE_LIMIT => { + return Ok(Some(Self::GetSponsoringRateLimit { + contract_address: reader.abi_read()?, + })) + } + Self::ALLOWED => { + return Ok(Some(Self::Allowed { + contract_address: reader.abi_read()?, + user: reader.abi_read()?, + })) + } + Self::ALLOWLIST_ENABLED => { + return Ok(Some(Self::AllowlistEnabled { + contract_address: reader.abi_read()?, + })) + } + Self::TOGGLE_ALLOWLIST => { + return Ok(Some(Self::ToggleAllowlist { + contract_address: reader.abi_read()?, + enabled: reader.abi_read()?, + })) + } + Self::TOGGLE_ALLOWED => { + return Ok(Some(Self::ToggleAllowed { + contract_address: reader.abi_read()?, + user: reader.abi_read()?, + allowed: reader.abi_read()?, + })) + } + _ => {} + } + return Ok(None); + } + } + impl ::evm_coder::Weighted for ContractHelpersCall { + fn weight(&self) -> ::evm_coder::execution::DispatchInfo { + type InternalCall = ContractHelpersCall; + match self { + InternalCall::ERC165Call(::evm_coder::ERC165Call::SupportsInterface { .. }) => { + 100u64.into() + } + InternalCall::ContractOwner { .. } => ().into(), + InternalCall::SponsoringEnabled { .. } => ().into(), + InternalCall::ToggleSponsoring { .. } => ().into(), + InternalCall::SetSponsoringRateLimit { .. } => ().into(), + InternalCall::GetSponsoringRateLimit { .. } => ().into(), + InternalCall::Allowed { .. } => ().into(), + InternalCall::AllowlistEnabled { .. } => ().into(), + InternalCall::ToggleAllowlist { .. } => ().into(), + InternalCall::ToggleAllowed { .. } => ().into(), + } + } + } + impl ::evm_coder::Callable> for ContractHelpers { + #[allow(unreachable_code)] + fn call( + &mut self, + c: Msg, + ) -> ::evm_coder::execution::ResultWithPostInfo<::evm_coder::abi::AbiWriter> { + use ::evm_coder::abi::AbiWrite; + type InternalCall = ContractHelpersCall; + match c.call { + InternalCall::ERC165Call(::evm_coder::ERC165Call::SupportsInterface { + interface_id, + }) => { + let mut writer = ::evm_coder::abi::AbiWriter::default(); + writer.bool(&InternalCall::supports_interface(interface_id)); + return Ok(writer.into()); + } + _ => {} + } + let mut writer = ::evm_coder::abi::AbiWriter::default(); + match c.call { + InternalCall::ContractOwner { contract_address } => { + let result = self.contract_owner(contract_address)?; + (&result).to_result() + } + InternalCall::SponsoringEnabled { contract_address } => { + let result = self.sponsoring_enabled(contract_address)?; + (&result).to_result() + } + InternalCall::ToggleSponsoring { + contract_address, + enabled, + } => { + let result = + self.toggle_sponsoring(c.caller.clone(), contract_address, enabled)?; + (&result).to_result() + } + InternalCall::SetSponsoringRateLimit { + contract_address, + rate_limit, + } => { + let result = self.set_sponsoring_rate_limit( + c.caller.clone(), + contract_address, + rate_limit, + )?; + (&result).to_result() + } + InternalCall::GetSponsoringRateLimit { contract_address } => { + let result = self.get_sponsoring_rate_limit(contract_address)?; + (&result).to_result() + } + InternalCall::Allowed { + contract_address, + user, + } => { + let result = self.allowed(contract_address, user)?; + (&result).to_result() + } + InternalCall::AllowlistEnabled { contract_address } => { + let result = self.allowlist_enabled(contract_address)?; + (&result).to_result() + } + InternalCall::ToggleAllowlist { + contract_address, + enabled, + } => { + let result = + self.toggle_allowlist(c.caller.clone(), contract_address, enabled)?; + (&result).to_result() + } + InternalCall::ToggleAllowed { + contract_address, + user, + allowed, + } => { + let result = + self.toggle_allowed(c.caller.clone(), contract_address, user, allowed)?; + (&result).to_result() + } + _ => ::core::panicking::panic("internal error: entered unreachable code"), + } + } + } + pub struct HelpersOnMethodCall(PhantomData<*const T>); + impl OnMethodCall for HelpersOnMethodCall { + fn is_reserved(contract: &sp_core::H160) -> bool { + contract == &T::ContractAddress::get() + } + fn is_used(contract: &sp_core::H160) -> bool { + contract == &T::ContractAddress::get() + } + fn call( + source: &sp_core::H160, + target: &sp_core::H160, + gas_left: u64, + input: &[u8], + value: sp_core::U256, + ) -> Option { + if !>::allowed(*target, *source, true) { + return Some(PrecompileOutput { + exit_status: ExitReason::Revert(ExitRevert::Reverted), + cost: 0, + output: { + let mut writer = AbiWriter::new_call(147028384u32); + writer.string("Target contract is allowlisted"); + writer.finish() + }, + logs: ::alloc::vec::Vec::new(), + }); + } + if target != &T::ContractAddress::get() { + return None; + } + let helpers = ContractHelpers::(SubstrateRecorder::::new(*target, gas_left)); + pallet_evm_coder_substrate::call(*source, helpers, value, input) + } + fn get_code(contract: &sp_core::H160) -> Option> { + (contract == & T :: ContractAddress :: get ()) . then (| | b"`\xe0`@R`&`\x80\x81\x81R\x90a\x04\xf4`\xa09\x80Qa\x00&\x91`\x01\x91` \x90\x91\x01\x90a\x009V[P4\x80\x15a\x003W`\x00\x80\xfd[Pa\x01\rV[\x82\x80Ta\x00E\x90a\x00\xd2V[\x90`\x00R` `\x00 \x90`\x1f\x01` \x90\x04\x81\x01\x92\x82a\x00gW`\x00\x85Ua\x00\xadV[\x82`\x1f\x10a\x00\x80W\x80Q`\xff\x19\x16\x83\x80\x01\x17\x85Ua\x00\xadV[\x82\x80\x01`\x01\x01\x85U\x82\x15a\x00\xadW\x91\x82\x01[\x82\x81\x11\x15a\x00\xadW\x82Q\x82U\x91` \x01\x91\x90`\x01\x01\x90a\x00\x92V[Pa\x00\xb9\x92\x91Pa\x00\xbdV[P\x90V[[\x80\x82\x11\x15a\x00\xb9W`\x00\x81U`\x01\x01a\x00\xbeV[`\x01\x81\x81\x1c\x90\x82\x16\x80a\x00\xe6W`\x7f\x82\x16\x91P[` \x82\x10\x81\x14\x15a\x01\x07WcNH{q`\xe0\x1b`\x00R`\"`\x04R`$`\x00\xfd[P\x91\x90PV[a\x03\xd8\x80a\x01\x1c`\x009`\x00\xf3\xfe`\x80`@R4\x80\x15a\x00\x10W`\x00\x80\xfd[P`\x046\x10a\x00\x9eW`\x005`\xe0\x1c\x80c`\'\xdca\x11a\x00fW\x80c`\'\xdca\x14a\x01\"W\x80ca\x0c\xfa\xbd\x14a\x010W\x80cw\xb6\xc9\x08\x14a\x01SW\x80c\xc7r\xefl\x14a\x01\"W\x80c\xfc\xacm\x86\x14a\x00\xcbW`\x00\x80\xfd[\x80c\x01\xff\xc9\xa7\x14a\x00\xa3W\x80c6\xde \xf5\x14a\x00\xcbW\x80cG\x06\xcc\x1c\x14a\x00\xe0W\x80cQR\xb1L\x14a\x00\xeeW\x80c\\e\x81e\x14a\x01\x14W[`\x00\x80\xfd[a\x00\xb6a\x00\xb16`\x04a\x01\xa2V[a\x01aV[`@Q\x90\x15\x15\x81R` \x01[`@Q\x80\x91\x03\x90\xf3[a\x00\xdea\x00\xd96`\x04a\x01\xffV[a\x01\x87V[\x00[a\x00\xdea\x00\xd96`\x04a\x022V[a\x00\xfca\x00\xb16`\x04a\x02uV[`@Q`\x01`\x01`\xa0\x1b\x03\x90\x91\x16\x81R` \x01a\x00\xc2V[a\x00\xb6a\x00\xb16`\x04a\x02\x90V[a\x00\xb6a\x00\xb16`\x04a\x02uV[a\x01>a\x00\xb16`\x04a\x02uV[`@Qc\xff\xff\xff\xff\x90\x91\x16\x81R` \x01a\x00\xc2V[a\x00\xdea\x00\xd96`\x04a\x02\xbaV[`\x00`\x01`@QbF\x1b\xcd`\xe5\x1b\x81R`\x04\x01a\x01~\x91\x90a\x02\xfaV[`@Q\x80\x91\x03\x90\xfd[`\x01`@QbF\x1b\xcd`\xe5\x1b\x81R`\x04\x01a\x01~\x91\x90a\x02\xfaV[`\x00` \x82\x84\x03\x12\x15a\x01\xb4W`\x00\x80\xfd[\x815`\x01`\x01`\xe0\x1b\x03\x19\x81\x16\x81\x14a\x01\xccW`\x00\x80\xfd[\x93\x92PPPV[\x805`\x01`\x01`\xa0\x1b\x03\x81\x16\x81\x14a\x01\xeaW`\x00\x80\xfd[\x91\x90PV[\x805\x80\x15\x15\x81\x14a\x01\xeaW`\x00\x80\xfd[`\x00\x80`@\x83\x85\x03\x12\x15a\x02\x12W`\x00\x80\xfd[a\x02\x1b\x83a\x01\xd3V[\x91Pa\x02)` \x84\x01a\x01\xefV[\x90P\x92P\x92\x90PV[`\x00\x80`\x00``\x84\x86\x03\x12\x15a\x02GW`\x00\x80\xfd[a\x02P\x84a\x01\xd3V[\x92Pa\x02^` \x85\x01a\x01\xd3V[\x91Pa\x02l`@\x85\x01a\x01\xefV[\x90P\x92P\x92P\x92V[`\x00` \x82\x84\x03\x12\x15a\x02\x87W`\x00\x80\xfd[a\x01\xcc\x82a\x01\xd3V[`\x00\x80`@\x83\x85\x03\x12\x15a\x02\xa3W`\x00\x80\xfd[a\x02\xac\x83a\x01\xd3V[\x91Pa\x02)` \x84\x01a\x01\xd3V[`\x00\x80`@\x83\x85\x03\x12\x15a\x02\xcdW`\x00\x80\xfd[a\x02\xd6\x83a\x01\xd3V[\x91P` \x83\x015c\xff\xff\xff\xff\x81\x16\x81\x14a\x02\xefW`\x00\x80\xfd[\x80\x91PP\x92P\x92\x90PV[`\x00` \x80\x83R`\x00\x84T\x81`\x01\x82\x81\x1c\x91P\x80\x83\x16\x80a\x03\x1cW`\x7f\x83\x16\x92P[\x85\x83\x10\x81\x14\x15a\x03:WcNH{q`\xe0\x1b\x85R`\"`\x04R`$\x85\xfd[\x87\x86\x01\x83\x81R` \x01\x81\x80\x15a\x03WW`\x01\x81\x14a\x03hWa\x03\x93V[`\xff\x19\x86\x16\x82R\x87\x82\x01\x96Pa\x03\x93V[`\x00\x8b\x81R` \x90 `\x00[\x86\x81\x10\x15a\x03\x8dW\x81T\x84\x82\x01R\x90\x85\x01\x90\x89\x01a\x03tV[\x83\x01\x97PP[P\x94\x99\x98PPPPPPPPPV\xfe\xa2dipfsX\"\x12 \xde\xe1\xb0gnP\xa0\xbb\xa7\xaf\xbek+\xe6S6\n\xcd?\x0c+\x81\xebEq\x8c\xe3\xab\xaaC6UdsolcC\x00\x08\t\x003this contract is implemented in native" . to_vec ()) + } + } + pub struct HelpersOnCreate(PhantomData<*const T>); + impl OnCreate for HelpersOnCreate { + fn on_create(owner: H160, contract: H160) { + >::insert(contract, owner); + } + } + pub struct HelpersContractSponsoring(PhantomData<*const T>); + impl SponsorshipHandler)> for HelpersContractSponsoring { + fn get_sponsor(who: &H160, call: &(H160, Vec)) -> Option { + if >::get(&call.0) && >::allowed(call.0, *who, false) { + let block_number = >::block_number() as T::BlockNumber; + if let Some(last_tx_block) = >::get(&call.0, who) { + let rate_limit = >::get(&call.0); + let limit_time = last_tx_block + rate_limit; + if block_number > limit_time { + >::insert(&call.0, who, block_number); + return Some(call.0); + } + } else { + >::insert(&call.0, who, block_number); + return Some(call.0); + } + } + None + } + } +} +#[doc = r" + The module that hosts all the + [FRAME](https://docs.substrate.io/v3/runtime/frame) + types needed to add this pallet to a + runtime. + "] +pub mod pallet { + use evm_coder::execution::Result; + use frame_support::pallet_prelude::*; + use sp_core::H160; + #[doc = r" + Configuration trait of this pallet. + + Implement this type for a runtime in order to customize this pallet. + "] + pub trait Config: frame_system::Config + pallet_evm_coder_substrate::Config { + type ContractAddress: Get; + type DefaultSponsoringRateLimit: Get; + } + #[scale_info(skip_type_params(T), capture_docs = "always")] + #[doc = r" + Custom [dispatch errors](https://docs.substrate.io/v3/runtime/events-and-errors) + of this pallet. + "] + pub enum Error { + #[doc(hidden)] + #[codec(skip)] + __Ignore( + frame_support::sp_std::marker::PhantomData<(T)>, + frame_support::Never, + ), + #[doc = " This method is only executable by owner"] + NoPermission, + } + #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] + const _: () = { + impl ::scale_info::TypeInfo for Error + where + frame_support::sp_std::marker::PhantomData<(T)>: ::scale_info::TypeInfo + 'static, + T: 'static, + { + type Identity = Self; + fn type_info() -> ::scale_info::Type { + :: scale_info :: Type :: builder () . path (:: scale_info :: Path :: new ("Error" , "pallet_evm_contract_helpers::pallet")) . type_params (< [_] > :: into_vec (box [:: scale_info :: TypeParameter :: new ("T" , :: core :: option :: Option :: None)])) . docs_always (& ["\n\t\t\tCustom [dispatch errors](https://docs.substrate.io/v3/runtime/events-and-errors)\n\t\t\tof this pallet.\n\t\t\t"]) . variant (:: scale_info :: build :: Variants :: new () . variant ("NoPermission" , | v | v . index (0usize as :: core :: primitive :: u8) . docs_always (& ["This method is only executable by owner"]))) + } + }; + }; + #[doc = r" + The [pallet](https://docs.substrate.io/v3/runtime/frame#pallets) implementing + the on-chain logic. + "] + pub struct Pallet(frame_support::sp_std::marker::PhantomData<(T)>); + const _: () = { + impl core::clone::Clone for Pallet { + fn clone(&self) -> Self { + Self(core::clone::Clone::clone(&self.0)) + } + } + }; + const _: () = { + impl core::cmp::Eq for Pallet {} + }; + const _: () = { + impl core::cmp::PartialEq for Pallet { + fn eq(&self, other: &Self) -> bool { + true && self.0 == other.0 + } + } + }; + const _: () = { + impl core::fmt::Debug for Pallet { + fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result { + fmt.debug_tuple("Pallet").field(&self.0).finish() + } + } + }; + #[allow(type_alias_bounds)] + pub(super) type Owner = StorageMap< + _GeneratedPrefixForStorageOwner, + Twox128, + H160, + H160, + ValueQuery, + frame_support::traits::GetDefault, + frame_support::traits::GetDefault, + >; + #[allow(type_alias_bounds)] + pub(super) type SelfSponsoring = StorageMap< + _GeneratedPrefixForStorageSelfSponsoring, + Twox128, + H160, + bool, + ValueQuery, + frame_support::traits::GetDefault, + frame_support::traits::GetDefault, + >; + #[allow(type_alias_bounds)] + pub(super) type SponsoringRateLimit = StorageMap< + _GeneratedPrefixForStorageSponsoringRateLimit, + Twox128, + H160, + T::BlockNumber, + ValueQuery, + T::DefaultSponsoringRateLimit, + frame_support::traits::GetDefault, + >; + #[allow(type_alias_bounds)] + pub(super) type SponsorBasket = StorageDoubleMap< + _GeneratedPrefixForStorageSponsorBasket, + Twox128, + H160, + Twox128, + H160, + T::BlockNumber, + OptionQuery, + frame_support::traits::GetDefault, + frame_support::traits::GetDefault, + >; + #[allow(type_alias_bounds)] + pub(super) type AllowlistEnabled = StorageMap< + _GeneratedPrefixForStorageAllowlistEnabled, + Twox128, + H160, + bool, + ValueQuery, + frame_support::traits::GetDefault, + frame_support::traits::GetDefault, + >; + #[allow(type_alias_bounds)] + pub(super) type Allowlist = StorageDoubleMap< + _GeneratedPrefixForStorageAllowlist, + Twox128, + H160, + Twox128, + H160, + bool, + ValueQuery, + frame_support::traits::GetDefault, + frame_support::traits::GetDefault, + >; + impl Pallet { + pub fn toggle_sponsoring(contract: H160, enabled: bool) { + >::insert(contract, enabled); + } + pub fn set_sponsoring_rate_limit(contract: H160, rate_limit: T::BlockNumber) { + >::insert(contract, rate_limit); + } + #[doc = " Default is returned if allowlist is disabled"] + pub fn allowed(contract: H160, user: H160, default: bool) -> bool { + if !>::get(contract) { + return default; + } + >::get(&contract, &user) || >::get(&contract) == user + } + pub fn toggle_allowlist(contract: H160, enabled: bool) { + >::insert(contract, enabled) + } + pub fn toggle_allowed(contract: H160, user: H160, allowed: bool) { + >::insert(contract, user, allowed); + } + pub fn ensure_owner(contract: H160, user: H160) -> Result<()> { + { + if !(>::get(&contract) == user) { + { + return Err("no permission".into()); + }; + } + }; + Ok(()) + } + } + impl Pallet { + #[doc(hidden)] + pub fn pallet_constants_metadata( + ) -> frame_support::sp_std::vec::Vec + { + ::alloc::vec::Vec::new() + } + } + impl Pallet { + pub fn error_metadata() -> Option { + Some(frame_support::metadata::PalletErrorMetadata { + ty: frame_support::scale_info::meta_type::>(), + }) + } + } + #[doc = r" Type alias to `Pallet`, to be used by `construct_runtime`."] + #[doc = r""] + #[doc = r" Generated by `pallet` attribute macro."] + #[deprecated(note = "use `Pallet` instead")] + #[allow(dead_code)] + pub type Module = Pallet; + impl frame_support::traits::GetStorageVersion for Pallet { + fn current_storage_version() -> frame_support::traits::StorageVersion { + frame_support::traits::StorageVersion::default() + } + fn on_chain_storage_version() -> frame_support::traits::StorageVersion { + frame_support::traits::StorageVersion::get::() + } + } + impl frame_support::traits::OnGenesis for Pallet { + fn on_genesis() { + let storage_version = frame_support::traits::StorageVersion::default(); + storage_version.put::(); + } + } + impl frame_support::traits::PalletInfoAccess for Pallet { + fn index() -> usize { + <::PalletInfo as frame_support::traits::PalletInfo>::index::< + Self, + >() + .expect( + "Pallet is part of the runtime because pallet `Config` trait is \ + implemented by the runtime", + ) + } + fn name() -> &'static str { + <::PalletInfo as frame_support::traits::PalletInfo>::name::< + Self, + >() + .expect( + "Pallet is part of the runtime because pallet `Config` trait is \ + implemented by the runtime", + ) + } + fn module_name() -> &'static str { + < < T as frame_system :: Config > :: PalletInfo as frame_support :: traits :: PalletInfo > :: module_name :: < Self > () . expect ("Pallet is part of the runtime because pallet `Config` trait is \ + implemented by the runtime") + } + fn crate_version() -> frame_support::traits::CrateVersion { + frame_support::traits::CrateVersion { + major: 0u16, + minor: 1u8, + patch: 0u8, + } + } + } + impl frame_support::traits::StorageInfoTrait for Pallet { + fn storage_info() -> frame_support::sp_std::vec::Vec { + #[allow(unused_mut)] + let mut res = ::alloc::vec::Vec::new(); + { + let mut storage_info = < Owner < T > as frame_support :: traits :: PartialStorageInfoTrait > :: partial_storage_info () ; + res.append(&mut storage_info); + } + { + let mut storage_info = < SelfSponsoring < T > as frame_support :: traits :: PartialStorageInfoTrait > :: partial_storage_info () ; + res.append(&mut storage_info); + } + { + let mut storage_info = < SponsoringRateLimit < T > as frame_support :: traits :: PartialStorageInfoTrait > :: partial_storage_info () ; + res.append(&mut storage_info); + } + { + let mut storage_info = < SponsorBasket < T > as frame_support :: traits :: PartialStorageInfoTrait > :: partial_storage_info () ; + res.append(&mut storage_info); + } + { + let mut storage_info = < AllowlistEnabled < T > as frame_support :: traits :: PartialStorageInfoTrait > :: partial_storage_info () ; + res.append(&mut storage_info); + } + { + let mut storage_info = < Allowlist < T > as frame_support :: traits :: PartialStorageInfoTrait > :: partial_storage_info () ; + res.append(&mut storage_info); + } + res + } + } + #[doc(hidden)] + pub mod __substrate_call_check { + #[doc(hidden)] + pub use __is_call_part_defined_0 as is_call_part_defined; + } + #[doc = r"Contains one variant per dispatchable that can be called by an extrinsic."] + #[codec(encode_bound())] + #[codec(decode_bound())] + #[scale_info(skip_type_params(T), capture_docs = "always")] + #[allow(non_camel_case_types)] + pub enum Call { + #[doc(hidden)] + #[codec(skip)] + __Ignore( + frame_support::sp_std::marker::PhantomData<(T,)>, + frame_support::Never, + ), + } + const _: () = { + impl core::fmt::Debug for Call { + fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result { + match *self { + Self::__Ignore(ref _0, ref _1) => fmt + .debug_tuple("Call::__Ignore") + .field(&_0) + .field(&_1) + .finish(), + } + } + } + }; + const _: () = { + impl core::clone::Clone for Call { + fn clone(&self) -> Self { + match self { + Self::__Ignore(ref _0, ref _1) => { + Self::__Ignore(core::clone::Clone::clone(_0), core::clone::Clone::clone(_1)) + } + } + } + } + }; + const _: () = { + impl core::cmp::Eq for Call {} + }; + const _: () = { + impl core::cmp::PartialEq for Call { + fn eq(&self, other: &Self) -> bool { + match (self, other) { + (Self::__Ignore(_0, _1), Self::__Ignore(_0_other, _1_other)) => { + true && _0 == _0_other && _1 == _1_other + } + } + } + } + }; + const _: () = { + #[allow(non_camel_case_types)] + impl ::codec::Encode for Call {} + impl ::codec::EncodeLike for Call {} + }; + const _: () = { + #[allow(non_camel_case_types)] + impl ::codec::Decode for Call { + fn decode<__CodecInputEdqy: ::codec::Input>( + __codec_input_edqy: &mut __CodecInputEdqy, + ) -> ::core::result::Result { + match __codec_input_edqy + .read_byte() + .map_err(|e| e.chain("Could not decode `Call`, failed to read variant byte"))? + { + _ => ::core::result::Result::Err(<_ as ::core::convert::Into<_>>::into( + "Could not decode `Call`, variant doesn\'t exist", + )), + } + } + } + }; + #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] + const _: () = { + impl ::scale_info::TypeInfo for Call + where + frame_support::sp_std::marker::PhantomData<(T,)>: ::scale_info::TypeInfo + 'static, + T: Config + 'static, + { + type Identity = Self; + fn type_info() -> ::scale_info::Type { + ::scale_info::Type::builder() + .path(::scale_info::Path::new( + "Call", + "pallet_evm_contract_helpers::pallet", + )) + .type_params(<[_]>::into_vec(box [::scale_info::TypeParameter::new( + "T", + ::core::option::Option::None, + )])) + .docs_always(&[ + "Contains one variant per dispatchable that can be called by an extrinsic.", + ]) + .variant(::scale_info::build::Variants::new()) + } + }; + }; + impl Call {} + impl frame_support::dispatch::GetDispatchInfo for Call { + fn get_dispatch_info(&self) -> frame_support::dispatch::DispatchInfo { + match *self { + Self::__Ignore(_, _) => { + ::core::panicking::panic_fmt(::core::fmt::Arguments::new_v1( + &["internal error: entered unreachable code: "], + &match (&"__Ignore cannot be used",) { + (arg0,) => [::core::fmt::ArgumentV1::new( + arg0, + ::core::fmt::Display::fmt, + )], + }, + )) + } + } + } + } + impl frame_support::dispatch::GetCallName for Call { + fn get_call_name(&self) -> &'static str { + match *self { + Self::__Ignore(_, _) => { + ::core::panicking::panic_fmt(::core::fmt::Arguments::new_v1( + &["internal error: entered unreachable code: "], + &match (&"__PhantomItem cannot be used.",) { + (arg0,) => [::core::fmt::ArgumentV1::new( + arg0, + ::core::fmt::Display::fmt, + )], + }, + )) + } + } + } + fn get_call_names() -> &'static [&'static str] { + &[] + } + } + impl frame_support::traits::UnfilteredDispatchable for Call { + type Origin = frame_system::pallet_prelude::OriginFor; + fn dispatch_bypass_filter( + self, + origin: Self::Origin, + ) -> frame_support::dispatch::DispatchResultWithPostInfo { + match self { + Self::__Ignore(_, _) => { + let _ = origin; + { + { + ::core::panicking::panic_fmt(::core::fmt::Arguments::new_v1( + &["internal error: entered unreachable code: "], + &match (&"__PhantomItem cannot be used.",) { + (arg0,) => [::core::fmt::ArgumentV1::new( + arg0, + ::core::fmt::Display::fmt, + )], + }, + )) + } + }; + } + } + } + } + impl frame_support::dispatch::Callable for Pallet { + type Call = Call; + } + impl Pallet { + #[doc(hidden)] + pub fn call_functions() -> frame_support::metadata::PalletCallMetadata { + frame_support::scale_info::meta_type::>().into() + } + } + impl frame_support::sp_std::fmt::Debug for Error { + fn fmt( + &self, + f: &mut frame_support::sp_std::fmt::Formatter<'_>, + ) -> frame_support::sp_std::fmt::Result { + f.write_str(self.as_str()) + } + } + impl Error { + pub fn as_u8(&self) -> u8 { + match &self { + Self::__Ignore(_, _) => { + ::core::panicking::panic_fmt(::core::fmt::Arguments::new_v1( + &["internal error: entered unreachable code: "], + &match (&"`__Ignore` can never be constructed",) { + (arg0,) => [::core::fmt::ArgumentV1::new( + arg0, + ::core::fmt::Display::fmt, + )], + }, + )) + } + Self::NoPermission => 0usize as u8, + } + } + pub fn as_str(&self) -> &'static str { + match &self { + Self::__Ignore(_, _) => { + ::core::panicking::panic_fmt(::core::fmt::Arguments::new_v1( + &["internal error: entered unreachable code: "], + &match (&"`__Ignore` can never be constructed",) { + (arg0,) => [::core::fmt::ArgumentV1::new( + arg0, + ::core::fmt::Display::fmt, + )], + }, + )) + } + Self::NoPermission => "NoPermission", + } + } + } + impl From> for &'static str { + fn from(err: Error) -> &'static str { + err.as_str() + } + } + impl From> for frame_support::sp_runtime::DispatchError { + fn from(err: Error) -> Self { + let index = < < T as frame_system :: Config > :: PalletInfo as frame_support :: traits :: PalletInfo > :: index :: < Pallet < T > > () . expect ("Every active module has an index in the runtime; qed") as u8 ; + frame_support::sp_runtime::DispatchError::Module { + index, + error: err.as_u8(), + message: Some(err.as_str()), + } + } + } + #[doc(hidden)] + pub mod __substrate_event_check { + #[doc(hidden)] + pub use __is_event_part_defined_1 as is_event_part_defined; + } + impl Pallet { + #[doc(hidden)] + pub fn storage_metadata() -> frame_support::metadata::PalletStorageMetadata { + frame_support :: metadata :: PalletStorageMetadata { prefix : < < T as frame_system :: Config > :: PalletInfo as frame_support :: traits :: PalletInfo > :: name :: < Pallet < T > > () . expect ("Every active pallet has a name in the runtime; qed") , entries : { # [allow (unused_mut)] let mut entries = :: alloc :: vec :: Vec :: new () ; { < Owner < T > as frame_support :: storage :: StorageEntryMetadataBuilder > :: build_metadata (:: alloc :: vec :: Vec :: new () , & mut entries) ; } { < SelfSponsoring < T > as frame_support :: storage :: StorageEntryMetadataBuilder > :: build_metadata (:: alloc :: vec :: Vec :: new () , & mut entries) ; } { < SponsoringRateLimit < T > as frame_support :: storage :: StorageEntryMetadataBuilder > :: build_metadata (:: alloc :: vec :: Vec :: new () , & mut entries) ; } { < SponsorBasket < T > as frame_support :: storage :: StorageEntryMetadataBuilder > :: build_metadata (:: alloc :: vec :: Vec :: new () , & mut entries) ; } { < AllowlistEnabled < T > as frame_support :: storage :: StorageEntryMetadataBuilder > :: build_metadata (:: alloc :: vec :: Vec :: new () , & mut entries) ; } { < Allowlist < T > as frame_support :: storage :: StorageEntryMetadataBuilder > :: build_metadata (:: alloc :: vec :: Vec :: new () , & mut entries) ; } entries } , } + } + } + pub(super) struct _GeneratedPrefixForStorageOwner(core::marker::PhantomData<(T,)>); + impl frame_support::traits::StorageInstance for _GeneratedPrefixForStorageOwner { + fn pallet_prefix() -> &'static str { + <::PalletInfo as frame_support::traits::PalletInfo>::name::< + Pallet, + >() + .expect("Every active pallet has a name in the runtime; qed") + } + const STORAGE_PREFIX: &'static str = "Owner"; + } + pub(super) struct _GeneratedPrefixForStorageSelfSponsoring(core::marker::PhantomData<(T,)>); + impl frame_support::traits::StorageInstance + for _GeneratedPrefixForStorageSelfSponsoring + { + fn pallet_prefix() -> &'static str { + <::PalletInfo as frame_support::traits::PalletInfo>::name::< + Pallet, + >() + .expect("Every active pallet has a name in the runtime; qed") + } + const STORAGE_PREFIX: &'static str = "SelfSponsoring"; + } + pub(super) struct _GeneratedPrefixForStorageSponsoringRateLimit( + core::marker::PhantomData<(T,)>, + ); + impl frame_support::traits::StorageInstance + for _GeneratedPrefixForStorageSponsoringRateLimit + { + fn pallet_prefix() -> &'static str { + <::PalletInfo as frame_support::traits::PalletInfo>::name::< + Pallet, + >() + .expect("Every active pallet has a name in the runtime; qed") + } + const STORAGE_PREFIX: &'static str = "SponsoringRateLimit"; + } + pub(super) struct _GeneratedPrefixForStorageSponsorBasket(core::marker::PhantomData<(T,)>); + impl frame_support::traits::StorageInstance + for _GeneratedPrefixForStorageSponsorBasket + { + fn pallet_prefix() -> &'static str { + <::PalletInfo as frame_support::traits::PalletInfo>::name::< + Pallet, + >() + .expect("Every active pallet has a name in the runtime; qed") + } + const STORAGE_PREFIX: &'static str = "SponsorBasket"; + } + pub(super) struct _GeneratedPrefixForStorageAllowlistEnabled( + core::marker::PhantomData<(T,)>, + ); + impl frame_support::traits::StorageInstance + for _GeneratedPrefixForStorageAllowlistEnabled + { + fn pallet_prefix() -> &'static str { + <::PalletInfo as frame_support::traits::PalletInfo>::name::< + Pallet, + >() + .expect("Every active pallet has a name in the runtime; qed") + } + const STORAGE_PREFIX: &'static str = "AllowlistEnabled"; + } + pub(super) struct _GeneratedPrefixForStorageAllowlist(core::marker::PhantomData<(T,)>); + impl frame_support::traits::StorageInstance for _GeneratedPrefixForStorageAllowlist { + fn pallet_prefix() -> &'static str { + <::PalletInfo as frame_support::traits::PalletInfo>::name::< + Pallet, + >() + .expect("Every active pallet has a name in the runtime; qed") + } + const STORAGE_PREFIX: &'static str = "Allowlist"; + } + #[doc(hidden)] + pub mod __substrate_inherent_check { + #[doc(hidden)] + pub use __is_inherent_part_defined_2 as is_inherent_part_defined; + } + #[doc = r" Hidden instance generated to be internally used when module is used without"] + #[doc = r" instance."] + #[doc(hidden)] + pub type __InherentHiddenInstance = (); + pub(super) trait Store { + type Owner; + type SelfSponsoring; + type SponsoringRateLimit; + type SponsorBasket; + type AllowlistEnabled; + type Allowlist; + } + impl Store for Pallet { + type Owner = Owner; + type SelfSponsoring = SelfSponsoring; + type SponsoringRateLimit = SponsoringRateLimit; + type SponsorBasket = SponsorBasket; + type AllowlistEnabled = AllowlistEnabled; + type Allowlist = Allowlist; + } + impl frame_support::traits::Hooks<::BlockNumber> + for Pallet + { + } + impl frame_support::traits::OnFinalize<::BlockNumber> + for Pallet + { + fn on_finalize(n: ::BlockNumber) { + let __within_span__ = { + use ::tracing::__macro_support::Callsite as _; + static CALLSITE: ::tracing::__macro_support::MacroCallsite = { + use ::tracing::__macro_support::MacroCallsite; + static META: ::tracing::Metadata<'static> = { + ::tracing_core::metadata::Metadata::new( + "on_finalize", + "pallet_evm_contract_helpers::pallet", + ::tracing::Level::TRACE, + Some("pallets/evm-contract-helpers/src/lib.rs"), + Some(7u32), + Some("pallet_evm_contract_helpers::pallet"), + ::tracing_core::field::FieldSet::new( + &[], + ::tracing_core::callsite::Identifier(&CALLSITE), + ), + ::tracing::metadata::Kind::SPAN, + ) + }; + MacroCallsite::new(&META) + }; + let mut interest = ::tracing::subscriber::Interest::never(); + if ::tracing::Level::TRACE <= ::tracing::level_filters::STATIC_MAX_LEVEL + && ::tracing::Level::TRACE <= ::tracing::level_filters::LevelFilter::current() + && { + interest = CALLSITE.interest(); + !interest.is_never() + } + && CALLSITE.is_enabled(interest) + { + let meta = CALLSITE.metadata(); + ::tracing::Span::new(meta, &{ meta.fields().value_set(&[]) }) + } else { + let span = CALLSITE.disabled_span(); + {}; + span + } + }; + let __tracing_guard__ = __within_span__.enter(); + < Self as frame_support :: traits :: Hooks < < T as frame_system :: Config > :: BlockNumber > > :: on_finalize (n) + } + } + impl frame_support::traits::OnIdle<::BlockNumber> + for Pallet + { + fn on_idle( + n: ::BlockNumber, + remaining_weight: frame_support::weights::Weight, + ) -> frame_support::weights::Weight { + < Self as frame_support :: traits :: Hooks < < T as frame_system :: Config > :: BlockNumber > > :: on_idle (n , remaining_weight) + } + } + impl frame_support::traits::OnInitialize<::BlockNumber> + for Pallet + { + fn on_initialize( + n: ::BlockNumber, + ) -> frame_support::weights::Weight { + let __within_span__ = { + use ::tracing::__macro_support::Callsite as _; + static CALLSITE: ::tracing::__macro_support::MacroCallsite = { + use ::tracing::__macro_support::MacroCallsite; + static META: ::tracing::Metadata<'static> = { + ::tracing_core::metadata::Metadata::new( + "on_initialize", + "pallet_evm_contract_helpers::pallet", + ::tracing::Level::TRACE, + Some("pallets/evm-contract-helpers/src/lib.rs"), + Some(7u32), + Some("pallet_evm_contract_helpers::pallet"), + ::tracing_core::field::FieldSet::new( + &[], + ::tracing_core::callsite::Identifier(&CALLSITE), + ), + ::tracing::metadata::Kind::SPAN, + ) + }; + MacroCallsite::new(&META) + }; + let mut interest = ::tracing::subscriber::Interest::never(); + if ::tracing::Level::TRACE <= ::tracing::level_filters::STATIC_MAX_LEVEL + && ::tracing::Level::TRACE <= ::tracing::level_filters::LevelFilter::current() + && { + interest = CALLSITE.interest(); + !interest.is_never() + } + && CALLSITE.is_enabled(interest) + { + let meta = CALLSITE.metadata(); + ::tracing::Span::new(meta, &{ meta.fields().value_set(&[]) }) + } else { + let span = CALLSITE.disabled_span(); + {}; + span + } + }; + let __tracing_guard__ = __within_span__.enter(); + < Self as frame_support :: traits :: Hooks < < T as frame_system :: Config > :: BlockNumber > > :: on_initialize (n) + } + } + impl frame_support::traits::OnRuntimeUpgrade for Pallet { + fn on_runtime_upgrade() -> frame_support::weights::Weight { + let __within_span__ = { + use ::tracing::__macro_support::Callsite as _; + static CALLSITE: ::tracing::__macro_support::MacroCallsite = { + use ::tracing::__macro_support::MacroCallsite; + static META: ::tracing::Metadata<'static> = { + ::tracing_core::metadata::Metadata::new( + "on_runtime_update", + "pallet_evm_contract_helpers::pallet", + ::tracing::Level::TRACE, + Some("pallets/evm-contract-helpers/src/lib.rs"), + Some(7u32), + Some("pallet_evm_contract_helpers::pallet"), + ::tracing_core::field::FieldSet::new( + &[], + ::tracing_core::callsite::Identifier(&CALLSITE), + ), + ::tracing::metadata::Kind::SPAN, + ) + }; + MacroCallsite::new(&META) + }; + let mut interest = ::tracing::subscriber::Interest::never(); + if ::tracing::Level::TRACE <= ::tracing::level_filters::STATIC_MAX_LEVEL + && ::tracing::Level::TRACE <= ::tracing::level_filters::LevelFilter::current() + && { + interest = CALLSITE.interest(); + !interest.is_never() + } + && CALLSITE.is_enabled(interest) + { + let meta = CALLSITE.metadata(); + ::tracing::Span::new(meta, &{ meta.fields().value_set(&[]) }) + } else { + let span = CALLSITE.disabled_span(); + {}; + span + } + }; + let __tracing_guard__ = __within_span__.enter(); + let pallet_name = < < T as frame_system :: Config > :: PalletInfo as frame_support :: traits :: PalletInfo > :: name :: < Self > () . unwrap_or ("") ; + { + let lvl = ::log::Level::Info; + if lvl <= ::log::STATIC_MAX_LEVEL && lvl <= ::log::max_level() { + ::log::__private_api_log( + ::core::fmt::Arguments::new_v1( + &["\u{2705} no migration for "], + &match (&pallet_name,) { + (arg0,) => [::core::fmt::ArgumentV1::new( + arg0, + ::core::fmt::Display::fmt, + )], + }, + ), + lvl, + &( + frame_support::LOG_TARGET, + "pallet_evm_contract_helpers::pallet", + "pallets/evm-contract-helpers/src/lib.rs", + 7u32, + ), + ); + } + }; + < Self as frame_support :: traits :: Hooks < < T as frame_system :: Config > :: BlockNumber > > :: on_runtime_upgrade () + } + } + impl frame_support::traits::OffchainWorker<::BlockNumber> + for Pallet + { + fn offchain_worker(n: ::BlockNumber) { + < Self as frame_support :: traits :: Hooks < < T as frame_system :: Config > :: BlockNumber > > :: offchain_worker (n) + } + } + impl frame_support::traits::IntegrityTest for Pallet { + fn integrity_test() { + < Self as frame_support :: traits :: Hooks < < T as frame_system :: Config > :: BlockNumber > > :: integrity_test () + } + } + #[doc(hidden)] + pub mod __substrate_genesis_config_check { + #[doc(hidden)] + pub use __is_genesis_config_defined_3 as is_genesis_config_defined; + #[doc(hidden)] + pub use __is_std_enabled_for_genesis_3 as is_std_enabled_for_genesis; + } + #[doc(hidden)] + pub mod __substrate_origin_check { + #[doc(hidden)] + pub use __is_origin_part_defined_4 as is_origin_part_defined; + } + #[doc(hidden)] + pub mod __substrate_validate_unsigned_check { + #[doc(hidden)] + pub use __is_validate_unsigned_part_defined_5 as is_validate_unsigned_part_defined; + } +} --- a/pallets/evm-contract-helpers/src/eth.rs +++ b/pallets/evm-contract-helpers/src/eth.rs @@ -1,7 +1,7 @@ use core::marker::PhantomData; use evm_coder::{abi::AbiWriter, execution::Result, generate_stubgen, solidity_interface, types::*}; -use pallet_evm_coder_substrate::SubstrateRecorder; -use pallet_evm::{ExitReason, ExitRevert, OnCreate, OnMethodCall, PrecompileOutput}; +use pallet_evm_coder_substrate::{SubstrateRecorder, WithRecorder}; +use pallet_evm::{ExitRevert, OnCreate, OnMethodCall, PrecompileResult, PrecompileFailure}; use sp_core::H160; use crate::{ AllowlistEnabled, Config, Owner, Pallet, SelfSponsoring, SponsorBasket, SponsoringRateLimit, @@ -11,16 +11,23 @@ use sp_std::{convert::TryInto, vec::Vec}; struct ContractHelpers(SubstrateRecorder); +impl WithRecorder for ContractHelpers { + fn recorder(&self) -> &SubstrateRecorder { + &self.0 + } + fn into_recorder(self) -> SubstrateRecorder { + self.0 + } +} + #[solidity_interface(name = "ContractHelpers")] impl ContractHelpers { fn contract_owner(&self, contract_address: address) -> Result
{ - self.0.consume_sload()?; Ok(>::get(contract_address)) } fn sponsoring_enabled(&self, contract_address: address) -> Result { - self.0.consume_sload()?; Ok(>::get(contract_address)) } @@ -30,9 +37,7 @@ contract_address: address, enabled: bool, ) -> Result { - self.0.consume_sload()?; >::ensure_owner(contract_address, caller)?; - self.0.consume_sstore()?; >::toggle_sponsoring(contract_address, enabled); Ok(()) } @@ -43,15 +48,12 @@ contract_address: address, rate_limit: uint32, ) -> Result { - self.0.consume_sload()?; >::ensure_owner(contract_address, caller)?; - self.0.consume_sstore()?; >::set_sponsoring_rate_limit(contract_address, rate_limit.into()); Ok(()) } fn get_sponsoring_rate_limit(&self, contract_address: address) -> Result { - self.0.consume_sload()?; Ok(>::get(contract_address) .try_into() .map_err(|_| "rate limit > u32::MAX")?) @@ -64,7 +66,6 @@ } fn allowlist_enabled(&self, contract_address: address) -> Result { - self.0.consume_sload()?; Ok(>::get(contract_address)) } @@ -74,9 +75,7 @@ contract_address: address, enabled: bool, ) -> Result { - self.0.consume_sload()?; >::ensure_owner(contract_address, caller)?; - self.0.consume_sstore()?; >::toggle_allowlist(contract_address, enabled); Ok(()) } @@ -88,9 +87,7 @@ user: address, allowed: bool, ) -> Result { - self.0.consume_sload()?; >::ensure_owner(contract_address, caller)?; - self.0.consume_sstore()?; >::toggle_allowed(contract_address, user, allowed); Ok(()) } @@ -112,28 +109,26 @@ gas_left: u64, input: &[u8], value: sp_core::U256, - ) -> Option { + ) -> Option { // TODO: Extract to another OnMethodCall handler if >::get(target) && !>::allowed(*target, *source) { - return Some(PrecompileOutput { - exit_status: ExitReason::Revert(ExitRevert::Reverted), + return Some(Err(PrecompileFailure::Revert { + exit_status: ExitRevert::Reverted, cost: 0, output: { let mut writer = AbiWriter::new_call(evm_coder::fn_selector!(Error(string))); writer.string("Target contract is allowlisted"); writer.finish() }, - logs: sp_std::vec![], - }); + })); } if target != &T::ContractAddress::get() { return None; } - let mut helpers = ContractHelpers::(SubstrateRecorder::::new(*target, gas_left)); - let result = pallet_evm_coder_substrate::call_internal(*source, &mut helpers, value, input); - helpers.0.evm_to_precompile_output(result) + let helpers = ContractHelpers::(SubstrateRecorder::::new(*target, gas_left)); + pallet_evm_coder_substrate::call(*source, helpers, value, input) } fn get_code(contract: &sp_core::H160) -> Option> { @@ -163,7 +158,7 @@ if let Some(last_tx_block) = >::get(&call.0, who) { let limit = >::get(&call.0); - let timeout = last_tx_block + limit.into(); + let timeout = last_tx_block + limit; if block_number < timeout { return None; } @@ -175,5 +170,5 @@ } } -generate_stubgen!(contract_helpers_impl, ContractHelpersCall, true); -generate_stubgen!(contract_helpers_iface, ContractHelpersCall, false); +generate_stubgen!(contract_helpers_impl, ContractHelpersCall<()>, true); +generate_stubgen!(contract_helpers_iface, ContractHelpersCall<()>, false); --- a/pallets/evm-contract-helpers/src/stubs/ContractHelpers.sol +++ b/pallets/evm-contract-helpers/src/stubs/ContractHelpers.sol @@ -21,6 +21,7 @@ } } +// Selector: 31acb1fe contract ContractHelpers is Dummy, ERC165 { // Selector: contractOwner(address) 5152b14c function contractOwner(address contractAddress) --- a/pallets/evm-migration/Cargo.toml +++ b/pallets/evm-migration/Cargo.toml @@ -1,10 +1,12 @@ [package] name = "pallet-evm-migration" version = "0.1.0" -edition = "2018" +edition = "2021" [dependencies] -scale-info = { version = "1.0.0", default-features = false, features = ["derive"] } +scale-info = { version = "1.0.0", default-features = false, features = [ + "derive", +] } frame-support = { default-features = false, git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.12' } frame-system = { default-features = false, git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.12' } frame-benchmarking = { default-features = false, optional = true, git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.12' } @@ -12,8 +14,8 @@ sp-std = { default-features = false, git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.12' } sp-io = { default-features = false, git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.12' } sp-core = { default-features = false, git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.12' } -pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier.git", branch = "unique-polkadot-v0.9.12" } -fp-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier.git", branch = "unique-polkadot-v0.9.12" } +pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier.git", branch = "unique-polkadot-v0.9.12-weights" } +fp-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier.git", branch = "unique-polkadot-v0.9.12-weights" } [dependencies.codec] default-features = false --- a/pallets/evm-migration/src/lib.rs +++ b/pallets/evm-migration/src/lib.rs @@ -98,7 +98,7 @@ _gas_left: u64, _input: &[u8], _value: sp_core::U256, - ) -> Option { + ) -> Option { None } --- a/pallets/evm-migration/src/weights.rs +++ b/pallets/evm-migration/src/weights.rs @@ -25,6 +25,7 @@ #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] #![allow(unused_imports)] +#![allow(clippy::unnecessary_cast)] use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; use sp_std::marker::PhantomData; --- a/pallets/evm-transaction-payment/Cargo.toml +++ b/pallets/evm-transaction-payment/Cargo.toml @@ -1,20 +1,22 @@ [package] name = "pallet-evm-transaction-payment" version = "0.1.0" -edition = "2018" +edition = "2021" [dependencies] -scale-info = { version = "1.0.0", default-features = false, features = ["derive"] } +scale-info = { version = "1.0.0", default-features = false, features = [ + "derive", +] } frame-support = { default-features = false, git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.12' } frame-system = { default-features = false, git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.12' } sp-runtime = { default-features = false, git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.12' } sp-std = { default-features = false, git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.12' } sp-io = { default-features = false, git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.12' } sp-core = { default-features = false, git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.12' } -pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier.git", branch = "unique-polkadot-v0.9.12" } -fp-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier.git", branch = "unique-polkadot-v0.9.12" } -pallet-ethereum = { default-features = false, git = "https://github.com/uniquenetwork/frontier.git", branch = "unique-polkadot-v0.9.12" } -up-sponsorship = { version = "0.1.0", default-features = false, git = "https://github.com/UniqueNetwork/pallet-sponsoring" } +pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier.git", branch = "unique-polkadot-v0.9.12-weights" } +fp-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier.git", branch = "unique-polkadot-v0.9.12-weights" } +pallet-ethereum = { default-features = false, git = "https://github.com/uniquenetwork/frontier.git", branch = "unique-polkadot-v0.9.12-weights" } +up-sponsorship = { version = "0.1.0", default-features = false, git = "https://github.com/UniqueNetwork/pallet-sponsoring" } up-evm-mapping = { default-features = false, path = "../../primitives/evm-mapping" } [dependencies.codec] --- a/pallets/evm-transaction-payment/src/lib.rs +++ b/pallets/evm-transaction-payment/src/lib.rs @@ -128,7 +128,7 @@ let sponsor = frame_support::storage::with_transaction(|| { TransactionOutcome::Rollback(T::EvmSponsorshipHandler::get_sponsor( &who, - &(target.clone(), input.clone()), + &(*target, input.clone()), )) })?; let sponsor = T::EvmAddressMapping::into_account_id(sponsor); --- a/pallets/fungible/Cargo.toml +++ b/pallets/fungible/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "pallet-fungible" version = "0.1.0" -edition = "2018" +edition = "2021" [dependencies.codec] default-features = false @@ -19,7 +19,7 @@ up-data-structs = { default-features = false, path = '../../primitives/data-structs' } evm-coder = { default-features = false, path = '../../crates/evm-coder' } pallet-evm-coder-substrate = { default-features = false, path = '../evm-coder-substrate' } -ethereum = { git = "https://github.com/purestake/ethereum", branch = "joshy-scale-info", default-features = false } +ethereum = { version = "0.10.0", default-features = false } frame-benchmarking = { default-features = false, optional = true, git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.12' } scale-info = { version = "1.0.0", default-features = false, features = [ "derive", --- a/pallets/fungible/src/benchmarking.rs +++ b/pallets/fungible/src/benchmarking.rs @@ -58,4 +58,13 @@ >::create_item(&collection, &owner, (sender.clone(), 200))?; >::set_allowance(&collection, &sender, &spender, 200)?; }: {>::transfer_from(&collection, &spender, &sender, &receiver, 100)?} + + burn_from { + bench_init!{ + owner: sub; collection: collection(owner); + owner: cross_from_sub; sender: cross_sub; burner: cross_sub; + }; + >::create_item(&collection, &owner, (sender.clone(), 200))?; + >::set_allowance(&collection, &sender, &burner, 200)?; + }: {>::burn_from(&collection, &burner, &sender, 100)?} } --- a/pallets/fungible/src/common.rs +++ b/pallets/fungible/src/common.rs @@ -37,7 +37,7 @@ } fn burn_from() -> Weight { - 0 + >::burn_from() } fn set_variable_metadata(_bytes: u32) -> Weight { @@ -116,7 +116,7 @@ ); with_weight( - >::transfer(&self, &from, &to, amount), + >::transfer(self, &from, &to, amount), >::transfer(), ) } @@ -134,7 +134,7 @@ ); with_weight( - >::set_allowance(&self, &sender, &spender, amount), + >::set_allowance(self, &sender, &spender, amount), >::approve(), ) } @@ -153,7 +153,7 @@ ); with_weight( - >::transfer_from(&self, &sender, &from, &to, amount), + >::transfer_from(self, &sender, &from, &to, amount), >::transfer_from(), ) } @@ -171,7 +171,7 @@ ); with_weight( - >::burn_from(&self, &sender, &from, amount), + >::burn_from(self, &sender, &from, amount), >::burn_from(), ) } --- a/pallets/fungible/src/erc.rs +++ b/pallets/fungible/src/erc.rs @@ -1,15 +1,17 @@ use core::char::{REPLACEMENT_CHARACTER, decode_utf16}; use core::convert::TryInto; -use evm_coder::{ToLog, execution::*, generate_stubgen, solidity_interface, types::*}; +use evm_coder::{ToLog, execution::*, generate_stubgen, solidity_interface, types::*, weight}; use up_data_structs::CollectionMode; -use pallet_common::erc::CommonEvmHandler; +use pallet_common::erc::{CommonEvmHandler, PrecompileResult}; use sp_core::{H160, U256}; use sp_std::vec::Vec; use pallet_common::account::CrossAccountId; -use pallet_common::erc::PrecompileOutput; -use pallet_evm_coder_substrate::{call_internal, dispatch_to_evm}; +use pallet_evm_coder_substrate::{call, dispatch_to_evm}; -use crate::{Allowance, Balance, Config, FungibleHandle, Pallet, TotalSupply}; +use crate::{ + Allowance, Balance, Config, FungibleHandle, Pallet, SelfWeightOf, TotalSupply, + weights::WeightInfo, +}; #[derive(ToLog)] pub enum ERC20Events { @@ -40,6 +42,7 @@ Ok(string::from_utf8_lossy(&self.token_prefix).into()) } fn total_supply(&self) -> Result { + self.consume_store_reads(1)?; Ok(>::get(self.id).into()) } @@ -51,10 +54,12 @@ }) } fn balance_of(&self, owner: address) -> Result { + self.consume_store_reads(1)?; let owner = T::CrossAccountId::from_eth(owner); let balance = >::get((self.id, owner)); Ok(balance.into()) } + #[weight(>::transfer())] fn transfer(&mut self, caller: caller, to: address, amount: uint256) -> Result { let caller = T::CrossAccountId::from_eth(caller); let to = T::CrossAccountId::from_eth(to); @@ -63,6 +68,7 @@ >::transfer(self, &caller, &to, amount).map_err(|_| "transfer error")?; Ok(true) } + #[weight(>::transfer_from())] fn transfer_from( &mut self, caller: caller, @@ -79,6 +85,7 @@ .map_err(dispatch_to_evm::)?; Ok(true) } + #[weight(>::approve())] fn approve(&mut self, caller: caller, spender: address, amount: uint256) -> Result { let caller = T::CrossAccountId::from_eth(caller); let spender = T::CrossAccountId::from_eth(spender); @@ -89,6 +96,7 @@ Ok(true) } fn allowance(&self, owner: address, spender: address) -> Result { + self.consume_store_reads(1)?; let owner = T::CrossAccountId::from_eth(owner); let spender = T::CrossAccountId::from_eth(spender); @@ -98,6 +106,7 @@ #[solidity_interface(name = "ERC20UniqueExtensions")] impl FungibleHandle { + #[weight(>::burn_from())] fn burn_from(&mut self, caller: caller, from: address, amount: uint256) -> Result { let caller = T::CrossAccountId::from_eth(caller); let from = T::CrossAccountId::from_eth(from); @@ -111,14 +120,13 @@ #[solidity_interface(name = "UniqueFungible", is(ERC20))] impl FungibleHandle {} -generate_stubgen!(gen_impl, UniqueFungibleCall, true); -generate_stubgen!(gen_iface, UniqueFungibleCall, false); +generate_stubgen!(gen_impl, UniqueFungibleCall<()>, true); +generate_stubgen!(gen_iface, UniqueFungibleCall<()>, false); impl CommonEvmHandler for FungibleHandle { const CODE: &'static [u8] = include_bytes!("./stubs/UniqueFungible.raw"); - fn call(mut self, source: &H160, input: &[u8], value: U256) -> Option { - let result = call_internal::(*source, &mut self, value, input); - self.0.recorder.evm_to_precompile_output(result) + fn call(self, source: &H160, input: &[u8], value: U256) -> Option { + call::, _>(*source, self, value, input) } } --- a/pallets/fungible/src/lib.rs +++ b/pallets/fungible/src/lib.rs @@ -6,6 +6,7 @@ use pallet_common::{ Error as CommonError, Event as CommonEvent, Pallet as PalletCommon, account::CrossAccountId, }; +use pallet_evm_coder_substrate::WithRecorder; use sp_core::H160; use sp_runtime::{ArithmeticError, DispatchError, DispatchResult}; use sp_std::{vec::Vec, vec, collections::btree_map::BTreeMap}; @@ -82,6 +83,14 @@ self.0 } } +impl WithRecorder for FungibleHandle { + fn recorder(&self) -> &pallet_evm_coder_substrate::SubstrateRecorder { + self.0.recorder() + } + fn into_recorder(self) -> pallet_evm_coder_substrate::SubstrateRecorder { + self.0.into_recorder() + } +} impl Deref for FungibleHandle { type Target = pallet_common::CollectionHandle; @@ -136,7 +145,7 @@ } >::insert(collection.id, total_supply); - collection.log_infallible(ERC20Events::Transfer { + collection.log(ERC20Events::Transfer { from: *owner.as_eth(), to: H160::default(), value: amount.into(), @@ -180,11 +189,6 @@ None }; - collection.consume_sstore()?; - collection.consume_sstore()?; - collection.consume_log(2, 32)?; - collection.consume_sstore()?; - // ========= if let Some(balance_to) = balance_to { @@ -197,7 +201,7 @@ >::insert((collection.id, to), balance_to); } - collection.log_infallible(ERC20Events::Transfer { + collection.log(ERC20Events::Transfer { from: *from.as_eth(), to: *to.as_eth(), value: amount.into(), @@ -217,8 +221,7 @@ sender: &T::CrossAccountId, data: Vec>, ) -> DispatchResult { - let unrestricted_minting = collection.is_owner_or_admin(sender)?; - if !unrestricted_minting { + if !collection.is_owner_or_admin(sender) { ensure!( collection.mint_mode, >::PublicMintingNotAllowed @@ -241,7 +244,6 @@ .ok_or(ArithmeticError::Overflow)?; for (user, amount) in data.into_iter() { - collection.consume_sload()?; let balance = balances .entry(user.clone()) .or_insert_with(|| >::get((collection.id, user))); @@ -250,20 +252,13 @@ .ok_or(ArithmeticError::Overflow)?; } - collection.consume_sstore()?; - for _ in &balances { - collection.consume_sstore()?; - collection.consume_log(2, 32)?; - collection.consume_sstore()?; - } - // ========= >::insert(collection.id, total_supply); for (user, amount) in balances { >::insert((collection.id, &user), amount); - collection.log_infallible(ERC20Events::Transfer { + collection.log(ERC20Events::Transfer { from: H160::default(), to: *user.as_eth(), value: amount.into(), @@ -291,7 +286,7 @@ >::insert((collection.id, owner, spender), amount); } - collection.log_infallible(ERC20Events::Approval { + collection.log(ERC20Events::Approval { owner: *owner.as_eth(), spender: *spender.as_eth(), value: amount.into(), @@ -312,13 +307,13 @@ amount: u128, ) -> DispatchResult { if collection.access == AccessMode::AllowList { - collection.check_allowlist(&owner)?; - collection.check_allowlist(&spender)?; + collection.check_allowlist(owner)?; + collection.check_allowlist(spender)?; } if >::get((collection.id, owner)) < amount { ensure!( - collection.ignores_owned_amount(owner)?, + collection.ignores_owned_amount(owner), >::CantApproveMoreThanOwned ); } @@ -347,7 +342,7 @@ let allowance = >::get((collection.id, from, spender)).checked_sub(amount); if allowance.is_none() { ensure!( - collection.ignores_allowance(spender)?, + collection.ignores_allowance(spender), >::TokenValueNotEnough ); } @@ -378,7 +373,7 @@ let allowance = >::get((collection.id, from, spender)).checked_sub(amount); if allowance.is_none() { ensure!( - collection.ignores_allowance(spender)?, + collection.ignores_allowance(spender), >::TokenValueNotEnough ); } --- a/pallets/fungible/src/stubs/UniqueFungible.sol +++ b/pallets/fungible/src/stubs/UniqueFungible.sol @@ -31,6 +31,7 @@ ); } +// Selector: 942e8b22 contract ERC20 is Dummy, ERC165, ERC20Events { // Selector: name() 06fdde03 function name() public view returns (string memory) { --- a/pallets/fungible/src/weights.rs +++ b/pallets/fungible/src/weights.rs @@ -25,6 +25,7 @@ #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] #![allow(unused_imports)] +#![allow(clippy::unnecessary_cast)] use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; use sp_std::marker::PhantomData; @@ -36,6 +37,7 @@ fn transfer() -> Weight; fn approve() -> Weight; fn transfer_from() -> Weight; + fn burn_from() -> Weight; } /// Weights for pallet_fungible using the Substrate node and recommended hardware. @@ -75,6 +77,14 @@ .saturating_add(T::DbWeight::get().reads(3 as Weight)) .saturating_add(T::DbWeight::get().writes(3 as Weight)) } + // Storage: Fungible Allowance (r:1 w:1) + // Storage: Fungible TotalSupply (r:1 w:1) + // Storage: Fungible Balance (r:1 w:1) + fn burn_from() -> Weight { + (55_874_000 as Weight) + .saturating_add(T::DbWeight::get().reads(3 as Weight)) + .saturating_add(T::DbWeight::get().writes(3 as Weight)) + } } // For backwards compatibility and tests @@ -113,4 +123,12 @@ .saturating_add(RocksDbWeight::get().reads(3 as Weight)) .saturating_add(RocksDbWeight::get().writes(3 as Weight)) } + // Storage: Fungible Allowance (r:1 w:1) + // Storage: Fungible TotalSupply (r:1 w:1) + // Storage: Fungible Balance (r:1 w:1) + fn burn_from() -> Weight { + (55_874_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(3 as Weight)) + .saturating_add(RocksDbWeight::get().writes(3 as Weight)) + } } --- a/pallets/nonfungible/Cargo.toml +++ b/pallets/nonfungible/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "pallet-nonfungible" version = "0.1.0" -edition = "2018" +edition = "2021" [dependencies.codec] default-features = false @@ -19,7 +19,7 @@ up-data-structs = { default-features = false, path = '../../primitives/data-structs' } evm-coder = { default-features = false, path = '../../crates/evm-coder' } pallet-evm-coder-substrate = { default-features = false, path = '../evm-coder-substrate' } -ethereum = { git = "https://github.com/purestake/ethereum", branch = "joshy-scale-info", default-features = false } +ethereum = { version = "0.10.0", default-features = false } frame-benchmarking = { default-features = false, optional = true, git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.12' } scale-info = { version = "1.0.0", default-features = false, features = [ "derive", --- a/pallets/nonfungible/src/benchmarking.rs +++ b/pallets/nonfungible/src/benchmarking.rs @@ -89,6 +89,15 @@ >::set_allowance(&collection, &sender, item, Some(&spender))?; }: {>::transfer_from(&collection, &spender, &sender, &receiver, item)?} + burn_from { + bench_init!{ + owner: sub; collection: collection(owner); + owner: cross_from_sub; sender: cross_sub; burner: cross_sub; + }; + let item = create_max_item(&collection, &owner, sender.clone())?; + >::set_allowance(&collection, &sender, item, Some(&burner))?; + }: {>::burn_from(&collection, &burner, &sender, item)?} + set_variable_metadata { let b in 0..CUSTOM_DATA_LIMIT; bench_init!{ --- a/pallets/nonfungible/src/common.rs +++ b/pallets/nonfungible/src/common.rs @@ -38,7 +38,7 @@ } fn burn_from() -> Weight { - 0 + >::burn_from() } fn set_variable_metadata(bytes: u32) -> Weight { @@ -100,7 +100,7 @@ ensure!(amount <= 1, >::NonfungibleItemsHaveNoAmount); if amount == 1 { with_weight( - >::burn(&self, &sender, token), + >::burn(self, &sender, token), >::burn_item(), ) } else { @@ -118,7 +118,7 @@ ensure!(amount <= 1, >::NonfungibleItemsHaveNoAmount); if amount == 1 { with_weight( - >::transfer(&self, &from, &to, token), + >::transfer(self, &from, &to, token), >::transfer(), ) } else { @@ -137,9 +137,9 @@ with_weight( if amount == 1 { - >::set_allowance(&self, &sender, token, Some(&spender)) + >::set_allowance(self, &sender, token, Some(&spender)) } else { - >::set_allowance(&self, &sender, token, None) + >::set_allowance(self, &sender, token, None) }, >::approve(), ) @@ -157,7 +157,7 @@ if amount == 1 { with_weight( - >::transfer_from(&self, &sender, &from, &to, token), + >::transfer_from(self, &sender, &from, &to, token), >::transfer_from(), ) } else { @@ -176,7 +176,7 @@ if amount == 1 { with_weight( - >::burn_from(&self, &sender, &from, token), + >::burn_from(self, &sender, &from, token), >::burn_from(), ) } else { @@ -192,7 +192,7 @@ ) -> DispatchResultWithPostInfo { let len = data.len(); with_weight( - >::set_variable_metadata(&self, &sender, token, data), + >::set_variable_metadata(self, &sender, token, data), >::set_variable_metadata(len as u32), ) } @@ -218,12 +218,12 @@ } fn const_metadata(&self, token: TokenId) -> Vec { >::get((self.id, token)) - .map(|t| t.const_data.clone()) + .map(|t| t.const_data) .unwrap_or_default() } fn variable_metadata(&self, token: TokenId) -> Vec { >::get((self.id, token)) - .map(|t| t.variable_data.clone()) + .map(|t| t.variable_data) .unwrap_or_default() } --- a/pallets/nonfungible/src/erc.rs +++ b/pallets/nonfungible/src/erc.rs @@ -2,18 +2,21 @@ char::{REPLACEMENT_CHARACTER, decode_utf16}, convert::TryInto, }; -use evm_coder::{ToLog, execution::*, generate_stubgen, solidity, solidity_interface, types::*}; +use evm_coder::{ToLog, execution::*, generate_stubgen, solidity, solidity_interface, types::*, weight}; use frame_support::BoundedVec; use up_data_structs::TokenId; use pallet_evm_coder_substrate::dispatch_to_evm; use sp_core::{H160, U256}; use sp_std::{vec::Vec, vec}; -use pallet_common::{account::CrossAccountId, erc::CommonEvmHandler}; -use pallet_evm_coder_substrate::call_internal; -use pallet_common::erc::PrecompileOutput; +use pallet_common::{ + account::CrossAccountId, + erc::{CommonEvmHandler, PrecompileResult}, +}; +use pallet_evm_coder_substrate::call; use crate::{ AccountBalance, Config, CreateItemData, NonfungibleHandle, Pallet, TokenData, TokensMinted, + SelfWeightOf, weights::WeightInfo, }; #[derive(ToLog)] @@ -61,8 +64,10 @@ Ok(string::from_utf8_lossy(&self.token_prefix).into()) } + /// Returns token's const_metadata #[solidity(rename_selector = "tokenURI")] fn token_uri(&self, token_id: uint256) -> Result { + self.consume_store_reads(1)?; let token_id: u32 = token_id.try_into().map_err(|_| "token id overflow")?; Ok(string::from_utf8_lossy( &>::get((self.id, token_id)) @@ -79,12 +84,14 @@ Ok(index) } + /// Not implemented fn token_of_owner_by_index(&self, _owner: address, _index: uint256) -> Result { // TODO: Not implemetable Err("not implemented".into()) } fn total_supply(&self) -> Result { + self.consume_store_reads(1)?; Ok(>::total_supply(self).into()) } } @@ -92,17 +99,20 @@ #[solidity_interface(name = "ERC721", events(ERC721Events))] impl NonfungibleHandle { fn balance_of(&self, owner: address) -> Result { + self.consume_store_reads(1)?; let owner = T::CrossAccountId::from_eth(owner); let balance = >::get((self.id, owner)); Ok(balance.into()) } fn owner_of(&self, token_id: uint256) -> Result
{ + self.consume_store_reads(1)?; let token: TokenId = token_id.try_into()?; Ok(*>::get((self.id, token)) .ok_or("token not found")? .owner .as_eth()) } + /// Not implemented fn safe_transfer_from_with_data( &mut self, _from: address, @@ -114,6 +124,7 @@ // TODO: Not implemetable Err("not implemented".into()) } + /// Not implemented fn safe_transfer_from( &mut self, _from: address, @@ -125,6 +136,7 @@ Err("not implemented".into()) } + #[weight(>::transfer_from())] fn transfer_from( &mut self, caller: caller, @@ -143,6 +155,7 @@ Ok(()) } + #[weight(>::approve())] fn approve( &mut self, caller: caller, @@ -159,6 +172,7 @@ Ok(()) } + /// Not implemented fn set_approval_for_all( &mut self, _caller: caller, @@ -169,11 +183,13 @@ Err("not implemented".into()) } + /// Not implemented fn get_approved(&self, _token_id: uint256) -> Result
{ // TODO: Not implemetable Err("not implemented".into()) } + /// Not implemented fn is_approved_for_all(&self, _owner: address, _operator: address) -> Result
{ // TODO: Not implemetable Err("not implemented".into()) @@ -182,6 +198,7 @@ #[solidity_interface(name = "ERC721Burnable")] impl NonfungibleHandle { + #[weight(>::burn_item())] fn burn(&mut self, caller: caller, token_id: uint256) -> Result { let caller = T::CrossAccountId::from_eth(caller); let token = token_id.try_into()?; @@ -197,6 +214,9 @@ Ok(false) } + /// `token_id` should be obtained with `next_token_id` method, + /// unlike standard, you can't specify it manually + #[weight(>::create_item())] fn mint(&mut self, caller: caller, to: address, token_id: uint256) -> Result { let caller = T::CrossAccountId::from_eth(caller); let to = T::CrossAccountId::from_eth(to); @@ -223,7 +243,10 @@ Ok(true) } + /// `token_id` should be obtained with `next_token_id` method, + /// unlike standard, you can't specify it manually #[solidity(rename_selector = "mintWithTokenURI")] + #[weight(>::create_item())] fn mint_with_token_uri( &mut self, caller: caller, @@ -257,6 +280,7 @@ Ok(true) } + /// Not implemented fn finish_minting(&mut self, _caller: caller) -> Result { Err("not implementable".into()) } @@ -264,6 +288,7 @@ #[solidity_interface(name = "ERC721UniqueExtensions")] impl NonfungibleHandle { + #[weight(>::transfer())] fn transfer( &mut self, caller: caller, @@ -279,6 +304,7 @@ Ok(()) } + #[weight(>::burn_from())] fn burn_from( &mut self, caller: caller, @@ -295,12 +321,14 @@ } fn next_token_id(&self) -> Result { + self.consume_store_reads(1)?; Ok(>::get(self.id) .checked_add(1) .ok_or("item id overflow")? .into()) } + #[weight(>::set_variable_metadata(data.len() as u32))] fn set_variable_metadata( &mut self, caller: caller, @@ -316,6 +344,7 @@ } fn get_variable_metadata(&self, token_id: uint256) -> Result { + self.consume_store_reads(1)?; let token: TokenId = token_id.try_into()?; Ok(>::get((self.id, token)) @@ -323,6 +352,7 @@ .variable_data) } + #[weight(>::create_multiple_items(token_ids.len() as u32))] fn mint_bulk(&mut self, caller: caller, to: address, token_ids: Vec) -> Result { let caller = T::CrossAccountId::from_eth(caller); let to = T::CrossAccountId::from_eth(to); @@ -351,6 +381,7 @@ } #[solidity(rename_selector = "mintBulkWithTokenURI")] + #[weight(>::create_multiple_items(tokens.len() as u32))] fn mint_bulk_with_token_uri( &mut self, caller: caller, @@ -399,16 +430,13 @@ impl NonfungibleHandle {} // Not a tests, but code generators -generate_stubgen!(gen_impl, UniqueNFTCall, true); -generate_stubgen!(gen_iface, UniqueNFTCall, false); - -pub const CODE: &[u8] = include_bytes!("./stubs/UniqueNFT.raw"); +generate_stubgen!(gen_impl, UniqueNFTCall<()>, true); +generate_stubgen!(gen_iface, UniqueNFTCall<()>, false); impl CommonEvmHandler for NonfungibleHandle { const CODE: &'static [u8] = include_bytes!("./stubs/UniqueNFT.raw"); - fn call(mut self, source: &H160, input: &[u8], value: U256) -> Option { - let result = call_internal::(*source, &mut self, value, input); - self.0.recorder.evm_to_precompile_output(result) + fn call(self, source: &H160, input: &[u8], value: U256) -> Option { + call::, _>(*source, self, value, input) } } --- a/pallets/nonfungible/src/lib.rs +++ b/pallets/nonfungible/src/lib.rs @@ -8,6 +8,7 @@ use pallet_common::{ Error as CommonError, Pallet as PalletCommon, Event as CommonEvent, account::CrossAccountId, }; +use pallet_evm_coder_substrate::{SubstrateRecorder, WithRecorder}; use sp_core::H160; use sp_runtime::{ArithmeticError, DispatchError, DispatchResult}; use sp_std::{vec::Vec, vec}; @@ -114,6 +115,14 @@ self.0 } } +impl WithRecorder for NonfungibleHandle { + fn recorder(&self) -> &SubstrateRecorder { + self.0.recorder() + } + fn into_recorder(self) -> SubstrateRecorder { + self.0.into_recorder() + } +} impl Deref for NonfungibleHandle { type Target = pallet_common::CollectionHandle; @@ -160,12 +169,11 @@ sender: &T::CrossAccountId, token: TokenId, ) -> DispatchResult { - let token_data = >::get((collection.id, token)) - .ok_or_else(|| >::TokenNotFound)?; + let token_data = + >::get((collection.id, token)).ok_or(>::TokenNotFound)?; ensure!( &token_data.owner == sender - || (collection.limits.owner_can_transfer() - && collection.is_owner_or_admin(sender)?), + || (collection.limits.owner_can_transfer() && collection.is_owner_or_admin(sender)), >::NoPermission ); @@ -188,7 +196,7 @@ } // ========= - >::remove((collection.id, &token_data.owner.clone(), token)); + >::remove((collection.id, &token_data.owner, token)); >::insert(collection.id, burnt); >::remove((collection.id, token)); let old_spender = >::take((collection.id, token)); @@ -198,12 +206,12 @@ collection.id, token, sender.clone(), - old_spender.clone(), + old_spender, 0, )); } - collection.log_infallible(ERC721Events::Transfer { + collection.log(ERC721Events::Transfer { from: *token_data.owner.as_eth(), to: H160::default(), token_id: token.into(), @@ -214,7 +222,7 @@ token_data.owner, 1, )); - return Ok(()); + Ok(()) } pub fn transfer( @@ -228,12 +236,11 @@ >::TransferNotAllowed ); - let token_data = >::get((collection.id, token)) - .ok_or_else(|| >::TokenNotFound)?; + let token_data = + >::get((collection.id, token)).ok_or(>::TokenNotFound)?; ensure!( &token_data.owner == from - || (collection.limits.owner_can_transfer() - && collection.is_owner_or_admin(from)?), + || (collection.limits.owner_can_transfer() && collection.is_owner_or_admin(from)), >::NoPermission ); @@ -260,9 +267,6 @@ } else { None }; - - collection.consume_sstores(4)?; - collection.consume_log(3, 0)?; // ========= @@ -287,7 +291,7 @@ } Self::set_allowance_unchecked(collection, from, token, None, true); - collection.log_infallible(ERC721Events::Transfer { + collection.log(ERC721Events::Transfer { from: *from.as_eth(), to: *to.as_eth(), token_id: token.into(), @@ -307,8 +311,7 @@ sender: &T::CrossAccountId, data: Vec>, ) -> DispatchResult { - let unrestricted_minting = collection.is_owner_or_admin(sender)?; - if !unrestricted_minting { + if !collection.is_owner_or_admin(sender) { ensure!( collection.mint_mode, >::PublicMintingNotAllowed @@ -322,14 +325,6 @@ for data in data.iter() { >::ensure_correct_receiver(&data.owner)?; - if !data.const_data.is_empty() { - collection.consume_sstore()?; - } - if !data.variable_data.is_empty() { - collection.consume_sstore()?; - } - collection.consume_sstore()?; - collection.consume_log(3, 0)?; } let first_token = >::get(collection.id); @@ -340,7 +335,6 @@ tokens_minted <= collection.limits.token_limit(), >::CollectionTokenLimitExceeded ); - collection.consume_sstore()?; let mut balances = BTreeMap::new(); for data in &data { @@ -354,7 +348,6 @@ >::AccountTokenLimitExceeded, ); } - collection.consume_sstores(balances.len())?; // ========= @@ -375,7 +368,7 @@ ); >::insert((collection.id, &data.owner, token), true); - collection.log_infallible(ERC721Events::Transfer { + collection.log(ERC721Events::Transfer { from: H160::default(), to: *data.owner.as_eth(), token_id: token.into(), @@ -402,7 +395,7 @@ >::insert((collection.id, token), spender); // In ERC721 there is only one possible approved user of token, so we set // approved user to spender - collection.log_infallible(ERC721Events::Approval { + collection.log(ERC721Events::Approval { owner: *sender.as_eth(), approved: *spender.as_eth(), token_id: token.into(), @@ -415,7 +408,7 @@ collection.id, token, sender.clone(), - old_owner.clone(), + old_owner, 0, )); } @@ -432,7 +425,7 @@ if !assume_implicit_eth { // In ERC721 there is only one possible approved user of token, so we set // approved user to zero address - collection.log_infallible(ERC721Events::Approval { + collection.log(ERC721Events::Approval { owner: *sender.as_eth(), approved: H160::default(), token_id: token.into(), @@ -445,7 +438,7 @@ collection.id, token, sender.clone(), - old_spender.clone(), + old_spender, 0, )); } @@ -459,9 +452,9 @@ spender: Option<&T::CrossAccountId>, ) -> DispatchResult { if collection.access == AccessMode::AllowList { - collection.check_allowlist(&sender)?; + collection.check_allowlist(sender)?; if let Some(spender) = spender { - collection.check_allowlist(&spender)?; + collection.check_allowlist(spender)?; } } @@ -472,7 +465,7 @@ >::get((collection.id, token)).ok_or(>::TokenNotFound)?; if &token_data.owner != sender { ensure!( - collection.ignores_owned_amount(sender)?, + collection.ignores_owned_amount(sender), >::CantApproveMoreThanOwned ); } @@ -500,14 +493,14 @@ if >::get((collection.id, token)).as_ref() != Some(spender) { ensure!( - collection.ignores_allowance(spender)?, + collection.ignores_allowance(spender), >::TokenValueNotEnough ); } // ========= - Self::transfer(collection, &from, to, token)?; + Self::transfer(collection, from, to, token)?; // Allowance is reset in [`transfer`] Ok(()) } @@ -528,14 +521,14 @@ if >::get((collection.id, token)).as_ref() != Some(spender) { ensure!( - collection.ignores_allowance(spender)?, + collection.ignores_allowance(spender), >::TokenValueNotEnough ); } // ========= - Self::burn(collection, &from, token) + Self::burn(collection, from, token) } pub fn set_variable_metadata( @@ -551,8 +544,6 @@ let token_data = >::get((collection.id, token)).ok_or(>::TokenNotFound)?; collection.check_can_update_meta(sender, &token_data.owner)?; - - collection.consume_sstore()?; // ========= --- a/pallets/nonfungible/src/stubs/UniqueNFT.sol +++ b/pallets/nonfungible/src/stubs/UniqueNFT.sol @@ -51,6 +51,17 @@ event MintingFinished(); } +// Selector: 42966c68 +contract ERC721Burnable is Dummy, ERC165 { + // Selector: burn(uint256) 42966c68 + function burn(uint256 tokenId) public { + require(false, stub_error); + tokenId; + dummy = 0; + } +} + +// Selector: 58800161 contract ERC721 is Dummy, ERC165, ERC721Events { // Selector: balanceOf(address) 70a08231 function balanceOf(address owner) public view returns (uint256) { @@ -68,6 +79,8 @@ return 0x0000000000000000000000000000000000000000; } + // Not implemented + // // Selector: safeTransferFromWithData(address,address,uint256,bytes) 60a11672 function safeTransferFromWithData( address from, @@ -83,6 +96,8 @@ dummy = 0; } + // Not implemented + // // Selector: safeTransferFrom(address,address,uint256) 42842e0e function safeTransferFrom( address from, @@ -117,6 +132,8 @@ dummy = 0; } + // Not implemented + // // Selector: setApprovalForAll(address,bool) a22cb465 function setApprovalForAll(address operator, bool approved) public { require(false, stub_error); @@ -125,6 +142,8 @@ dummy = 0; } + // Not implemented + // // Selector: getApproved(uint256) 081812fc function getApproved(uint256 tokenId) public view returns (address) { require(false, stub_error); @@ -133,6 +152,8 @@ return 0x0000000000000000000000000000000000000000; } + // Not implemented + // // Selector: isApprovedForAll(address,address) e985e9c5 function isApprovedForAll(address owner, address operator) public @@ -147,45 +168,7 @@ } } -contract ERC721Burnable is Dummy, ERC165 { - // Selector: burn(uint256) 42966c68 - function burn(uint256 tokenId) public { - require(false, stub_error); - tokenId; - dummy = 0; - } -} - -contract ERC721Enumerable is Dummy, ERC165 { - // Selector: tokenByIndex(uint256) 4f6ccce7 - function tokenByIndex(uint256 index) public view returns (uint256) { - require(false, stub_error); - index; - dummy; - return 0; - } - - // Selector: tokenOfOwnerByIndex(address,uint256) 2f745c59 - function tokenOfOwnerByIndex(address owner, uint256 index) - public - view - returns (uint256) - { - require(false, stub_error); - owner; - index; - dummy; - return 0; - } - - // Selector: totalSupply() 18160ddd - function totalSupply() public view returns (uint256) { - require(false, stub_error); - dummy; - return 0; - } -} - +// Selector: 5b5e139f contract ERC721Metadata is Dummy, ERC165 { // Selector: name() 06fdde03 function name() public view returns (string memory) { @@ -201,6 +184,8 @@ return ""; } + // Returns token's const_metadata + // // Selector: tokenURI(uint256) c87b56dd function tokenURI(uint256 tokenId) public view returns (string memory) { require(false, stub_error); @@ -210,6 +195,7 @@ } } +// Selector: 68ccfe89 contract ERC721Mintable is Dummy, ERC165, ERC721MintableEvents { // Selector: mintingFinished() 05d2035b function mintingFinished() public view returns (bool) { @@ -218,6 +204,9 @@ return false; } + // `token_id` should be obtained with `next_token_id` method, + // unlike standard, you can't specify it manually + // // Selector: mint(address,uint256) 40c10f19 function mint(address to, uint256 tokenId) public returns (bool) { require(false, stub_error); @@ -227,6 +216,9 @@ return false; } + // `token_id` should be obtained with `next_token_id` method, + // unlike standard, you can't specify it manually + // // Selector: mintWithTokenURI(address,uint256,string) 50bb4e7f function mintWithTokenURI( address to, @@ -241,6 +233,8 @@ return false; } + // Not implemented + // // Selector: finishMinting() 7d64bcb4 function finishMinting() public returns (bool) { require(false, stub_error); @@ -249,6 +243,40 @@ } } +// Selector: 780e9d63 +contract ERC721Enumerable is Dummy, ERC165 { + // Selector: tokenByIndex(uint256) 4f6ccce7 + function tokenByIndex(uint256 index) public view returns (uint256) { + require(false, stub_error); + index; + dummy; + return 0; + } + + // Not implemented + // + // Selector: tokenOfOwnerByIndex(address,uint256) 2f745c59 + function tokenOfOwnerByIndex(address owner, uint256 index) + public + view + returns (uint256) + { + require(false, stub_error); + owner; + index; + dummy; + return 0; + } + + // Selector: totalSupply() 18160ddd + function totalSupply() public view returns (uint256) { + require(false, stub_error); + dummy; + return 0; + } +} + +// Selector: e562194d contract ERC721UniqueExtensions is Dummy, ERC165 { // Selector: transfer(address,uint256) a9059cbb function transfer(address to, uint256 tokenId) public { --- a/pallets/nonfungible/src/weights.rs +++ b/pallets/nonfungible/src/weights.rs @@ -25,6 +25,7 @@ #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] #![allow(unused_imports)] +#![allow(clippy::unnecessary_cast)] use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; use sp_std::marker::PhantomData; @@ -37,6 +38,7 @@ fn transfer() -> Weight; fn approve() -> Weight; fn transfer_from() -> Weight; + fn burn_from() -> Weight; fn set_variable_metadata(b: u32, ) -> Weight; } @@ -98,6 +100,15 @@ .saturating_add(T::DbWeight::get().reads(4 as Weight)) .saturating_add(T::DbWeight::get().writes(6 as Weight)) } + // Storage: Nonfungible Allowance (r:1 w:1) + // Storage: Nonfungible TokenData (r:1 w:1) + // Storage: Nonfungible TokensBurnt (r:1 w:1) + // Storage: Nonfungible Owned (r:0 w:1) + fn burn_from() -> Weight { + (53_429_000 as Weight) + .saturating_add(T::DbWeight::get().reads(3 as Weight)) + .saturating_add(T::DbWeight::get().writes(4 as Weight)) + } // Storage: Nonfungible TokenData (r:1 w:1) fn set_variable_metadata(_b: u32, ) -> Weight { (6_380_000 as Weight) @@ -163,6 +174,15 @@ .saturating_add(RocksDbWeight::get().reads(4 as Weight)) .saturating_add(RocksDbWeight::get().writes(6 as Weight)) } + // Storage: Nonfungible Allowance (r:1 w:1) + // Storage: Nonfungible TokenData (r:1 w:1) + // Storage: Nonfungible TokensBurnt (r:1 w:1) + // Storage: Nonfungible Owned (r:0 w:1) + fn burn_from() -> Weight { + (53_429_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(3 as Weight)) + .saturating_add(RocksDbWeight::get().writes(4 as Weight)) + } // Storage: Nonfungible TokenData (r:1 w:1) fn set_variable_metadata(_b: u32, ) -> Weight { (6_380_000 as Weight) --- a/pallets/refungible/Cargo.toml +++ b/pallets/refungible/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "pallet-refungible" version = "0.1.0" -edition = "2018" +edition = "2021" [dependencies.codec] default-features = false --- a/pallets/refungible/src/benchmarking.rs +++ b/pallets/refungible/src/benchmarking.rs @@ -149,6 +149,16 @@ >::set_allowance(&collection, &sender, &spender, item, 200)?; }: {>::transfer_from(&collection, &spender, &sender, &receiver, item, 200)?} + // Both source account and token is destroyed + burn_from { + bench_init!{ + owner: sub; collection: collection(owner); + owner: cross_from_sub; sender: cross_sub; burner: cross_sub; + }; + let item = create_max_item(&collection, &owner, [(sender.clone(), 200)])?; + >::set_allowance(&collection, &sender, &burner, item, 200)?; + }: {>::burn_from(&collection, &burner, &sender, item, 200)?} + set_variable_metadata { let b in 0..CUSTOM_DATA_LIMIT; bench_init!{ --- a/pallets/refungible/src/common.rs +++ b/pallets/refungible/src/common.rs @@ -58,7 +58,7 @@ } fn burn_from() -> Weight { - 0 + >::burn_from() } fn set_variable_metadata(bytes: u32) -> Weight { @@ -135,7 +135,7 @@ amount: u128, ) -> DispatchResultWithPostInfo { with_weight( - >::transfer(&self, &from, &to, token, amount), + >::transfer(self, &from, &to, token, amount), >::transfer(), ) } @@ -148,7 +148,7 @@ amount: u128, ) -> DispatchResultWithPostInfo { with_weight( - >::set_allowance(&self, &sender, &spender, token, amount), + >::set_allowance(self, &sender, &spender, token, amount), >::approve(), ) } @@ -162,7 +162,7 @@ amount: u128, ) -> DispatchResultWithPostInfo { with_weight( - >::transfer_from(&self, &sender, &from, &to, token, amount), + >::transfer_from(self, &sender, &from, &to, token, amount), >::transfer_from(), ) } @@ -175,7 +175,7 @@ amount: u128, ) -> DispatchResultWithPostInfo { with_weight( - >::burn_from(&self, &sender, &from, token, amount), + >::burn_from(self, &sender, &from, token, amount), >::burn_from(), ) } @@ -188,7 +188,7 @@ ) -> DispatchResultWithPostInfo { let len = data.len(); with_weight( - >::set_variable_metadata(&self, &sender, token, data), + >::set_variable_metadata(self, &sender, token, data), >::set_variable_metadata(len as u32), ) } --- a/pallets/refungible/src/erc.rs +++ b/pallets/refungible/src/erc.rs @@ -11,7 +11,7 @@ _source: &sp_core::H160, _input: &[u8], _value: sp_core::U256, - ) -> Option { + ) -> Option { // TODO: Implement RFT variant of ERC721 None } @@ -27,7 +27,7 @@ _source: &sp_core::H160, _input: &[u8], _value: sp_core::U256, - ) -> Option { + ) -> Option { // TODO: Implement RFT variant of ERC20 None } --- a/pallets/refungible/src/lib.rs +++ b/pallets/refungible/src/lib.rs @@ -191,7 +191,7 @@ >::remove_prefix((collection.id, token_id), None); >::remove_prefix((collection.id, token_id), None); // TODO: ERC721 transfer event - return Ok(()); + Ok(()) } pub fn burn( @@ -361,8 +361,7 @@ sender: &T::CrossAccountId, data: Vec>, ) -> DispatchResult { - let unrestricted_minting = collection.is_owner_or_admin(sender)?; - if !unrestricted_minting { + if !collection.is_owner_or_admin(sender) { ensure!( collection.mint_mode, >::PublicMintingNotAllowed @@ -370,8 +369,8 @@ collection.check_allowlist(sender)?; for item in data.iter() { - for (user, _) in &item.users { - collection.check_allowlist(&user)?; + for user in item.users.keys() { + collection.check_allowlist(user)?; } } } @@ -412,7 +411,7 @@ let mut balances = BTreeMap::new(); for data in &data { - for (owner, _) in &data.users { + for owner in data.users.keys() { let balance = balances .entry(owner) .or_insert_with(|| >::get((collection.id, owner))); @@ -490,15 +489,15 @@ amount: u128, ) -> DispatchResult { if collection.access == AccessMode::AllowList { - collection.check_allowlist(&sender)?; - collection.check_allowlist(&spender)?; + collection.check_allowlist(sender)?; + collection.check_allowlist(spender)?; } >::ensure_correct_receiver(spender)?; if >::get((collection.id, token, sender)) < amount { ensure!( - collection.ignores_owned_amount(sender)? && Self::token_exists(collection, token), + collection.ignores_owned_amount(sender) && Self::token_exists(collection, token), >::CantApproveMoreThanOwned ); } @@ -529,7 +528,7 @@ >::get((collection.id, token, from, &spender)).checked_sub(amount); if allowance.is_none() { ensure!( - collection.ignores_allowance(spender)?, + collection.ignores_allowance(spender), >::TokenValueNotEnough ); } @@ -562,7 +561,7 @@ >::get((collection.id, token, from, &spender)).checked_sub(amount); if allowance.is_none() { ensure!( - collection.ignores_allowance(spender)?, + collection.ignores_allowance(spender), >::TokenValueNotEnough ); } @@ -591,7 +590,6 @@ &T::CrossAccountId::from_sub(collection.owner.clone()), )?; - collection.consume_sstore()?; let token_data = >::get((collection.id, token)); // ========= --- a/pallets/refungible/src/weights.rs +++ b/pallets/refungible/src/weights.rs @@ -25,6 +25,7 @@ #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] #![allow(unused_imports)] +#![allow(clippy::unnecessary_cast)] use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; use sp_std::marker::PhantomData; @@ -44,6 +45,7 @@ fn transfer_from_creating() -> Weight; fn transfer_from_removing() -> Weight; fn transfer_from_creating_removing() -> Weight; + fn burn_from() -> Weight; fn set_variable_metadata(b: u32, ) -> Weight; } @@ -166,6 +168,18 @@ .saturating_add(T::DbWeight::get().reads(5 as Weight)) .saturating_add(T::DbWeight::get().writes(7 as Weight)) } + // Storage: Refungible Allowance (r:1 w:1) + // Storage: Refungible TotalSupply (r:1 w:1) + // Storage: Refungible Balance (r:1 w:1) + // Storage: Refungible AccountBalance (r:1 w:1) + // Storage: Refungible TokensBurnt (r:1 w:1) + // Storage: Refungible TokenData (r:0 w:1) + // Storage: Refungible Owned (r:0 w:1) + fn burn_from() -> Weight { + (60_903_000 as Weight) + .saturating_add(T::DbWeight::get().reads(5 as Weight)) + .saturating_add(T::DbWeight::get().writes(7 as Weight)) + } // Storage: Refungible TokenData (r:1 w:1) fn set_variable_metadata(_b: u32, ) -> Weight { (6_801_000 as Weight) @@ -292,6 +306,18 @@ .saturating_add(RocksDbWeight::get().reads(5 as Weight)) .saturating_add(RocksDbWeight::get().writes(7 as Weight)) } + // Storage: Refungible Allowance (r:1 w:1) + // Storage: Refungible TotalSupply (r:1 w:1) + // Storage: Refungible Balance (r:1 w:1) + // Storage: Refungible AccountBalance (r:1 w:1) + // Storage: Refungible TokensBurnt (r:1 w:1) + // Storage: Refungible TokenData (r:0 w:1) + // Storage: Refungible Owned (r:0 w:1) + fn burn_from() -> Weight { + (60_903_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(5 as Weight)) + .saturating_add(RocksDbWeight::get().writes(7 as Weight)) + } // Storage: Refungible TokenData (r:1 w:1) fn set_variable_metadata(_b: u32, ) -> Weight { (6_801_000 as Weight) --- a/pallets/scheduler/Cargo.toml +++ b/pallets/scheduler/Cargo.toml @@ -2,7 +2,7 @@ name = "pallet-unq-scheduler" version = "0.1.0" authors = ["Unique Network "] -edition = "2018" +edition = "2021" license = "All Rights Reserved" homepage = "https://unique.network" repository = "https://github.com/UniqueNetwork/unique-chain" @@ -20,7 +20,7 @@ sp-io = { default-features = false, git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.12' } frame-benchmarking = { default-features = false, optional = true, git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.12' } -up-sponsorship = { version = "0.1.0", default-features = false, git = "https://github.com/UniqueNetwork/pallet-sponsoring" } +up-sponsorship = { version = "0.1.0", default-features = false, git = "https://github.com/UniqueNetwork/pallet-sponsoring" } log = { version = "0.4.14", default-features = false } [dev-dependencies] --- a/pallets/scheduler/src/benchmarking.rs +++ b/pallets/scheduler/src/benchmarking.rs @@ -33,7 +33,7 @@ // Add `n` named items to the schedule fn fill_schedule(when: T::BlockNumber, n: u32) -> Result<(), &'static str> { // Essentially a no-op call. - let call = frame_system::Call::set_storage(vec![]); + let call = frame_system::Call::set_storage { items: vec![] }; for i in 0..n { // Named schedule is strictly heavier than anonymous Scheduler::::do_schedule_named( @@ -61,7 +61,7 @@ let periodic = Some((T::BlockNumber::one(), 100)); let priority = 0; // Essentially a no-op call. - let call = Box::new(frame_system::Call::set_storage(vec![]).into()); + let call = Box::new(frame_system::Call::set_storage { items: vec![] }.into()); fill_schedule::(when, s)?; }: _(RawOrigin::Root, when, periodic, priority, call) @@ -98,7 +98,7 @@ let periodic = Some((T::BlockNumber::one(), 100)); let priority = 0; // Essentially a no-op call. - let call = Box::new(frame_system::Call::set_storage(vec![]).into()); + let call = Box::new(frame_system::Call::set_storage { items: vec![] }.into()); fill_schedule::(when, s)?; }: _(RawOrigin::Root, id, when, periodic, priority, call) --- a/pallets/unique/Cargo.toml +++ b/pallets/unique/Cargo.toml @@ -127,11 +127,11 @@ scale-info = { version = "1.0.0", default-features = false, features = [ "derive", ] } -ethereum = { version = "0.9", git = "https://github.com/purestake/ethereum", branch = "joshy-scale-info", default-features = false } +ethereum = { version = "0.10.0", default-features = false } rlp = { default-features = false, version = "0.5.0" } sp-api = { default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.12" } -up-sponsorship = { version = "0.1.0", default-features = false, git = "https://github.com/UniqueNetwork/pallet-sponsoring" } +up-sponsorship = { version = "0.1.0", default-features = false, git = "https://github.com/UniqueNetwork/pallet-sponsoring" } up-evm-mapping = { default-features = false, path = "../../primitives/evm-mapping" } evm-coder = { default-features = false, path = "../../crates/evm-coder" } pallet-evm-coder-substrate = { default-features = false, path = "../../pallets/evm-coder-substrate" } @@ -139,9 +139,9 @@ "serde_no_std", ] } -pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier.git", branch = "unique-polkadot-v0.9.12" } -pallet-ethereum = { default-features = false, git = "https://github.com/uniquenetwork/frontier.git", branch = "unique-polkadot-v0.9.12" } -fp-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier.git", branch = "unique-polkadot-v0.9.12" } +pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier.git", branch = "unique-polkadot-v0.9.12-weights" } +pallet-ethereum = { default-features = false, git = "https://github.com/uniquenetwork/frontier.git", branch = "unique-polkadot-v0.9.12-weights" } +fp-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier.git", branch = "unique-polkadot-v0.9.12-weights" } hex-literal = "0.3.3" pallet-common = { default-features = false, path = "../common" } --- a/pallets/unique/src/benchmarking.rs +++ b/pallets/unique/src/benchmarking.rs @@ -155,12 +155,14 @@ let cl = CollectionLimits { account_token_ownership_limit: Some(0), - sponsored_data_size: 0, - token_limit: 1, - sponsor_transfer_timeout: 0, - owner_can_destroy: true, - owner_can_transfer: true, + sponsored_data_size: Some(0), + token_limit: Some(1), + sponsor_transfer_timeout: Some(0), + sponsor_approve_timeout: None, + owner_can_destroy: Some(true), + owner_can_transfer: Some(true), sponsored_data_rate_limit: None, + transfers_enabled: Some(true), }; }: set_collection_limits(RawOrigin::Signed(caller.clone()), collection, cl) --- a/pallets/unique/src/dispatch.rs +++ b/pallets/unique/src/dispatch.rs @@ -83,10 +83,6 @@ _ => {} } - // TODO: Make submit_logs infallible, but it shouldn't fail here anyway - dispatched - .into_inner() - .submit_logs() - .expect("should succeed"); + dispatched.into_inner().submit_logs(); result } --- a/pallets/unique/src/eth/mod.rs +++ b/pallets/unique/src/eth/mod.rs @@ -1,5 +1,6 @@ pub mod sponsoring; +use fp_evm::PrecompileResult; use pallet_common::{ CollectionById, erc::CommonEvmHandler, @@ -10,7 +11,6 @@ use pallet_refungible::{RefungibleHandle, erc::RefungibleTokenHandle}; use sp_std::borrow::ToOwned; use sp_std::vec::Vec; -use pallet_evm::{PrecompileOutput}; use sp_core::{H160, U256}; use crate::{CollectionMode, Config, dispatch::Dispatched}; use pallet_common::CollectionHandle; @@ -54,7 +54,7 @@ gas_limit: u64, input: &[u8], value: U256, - ) -> Option { + ) -> Option { if let Some(collection_id) = map_eth_to_id(target) { let collection = >::new_with_gas_limit(collection_id, gas_limit)?; let dispatched = Dispatched::dispatch(collection); --- a/pallets/unique/src/eth/sponsoring.rs +++ b/pallets/unique/src/eth/sponsoring.rs @@ -27,7 +27,7 @@ let (method_id, mut reader) = AbiReader::new_call(&call.1).ok()?; match &collection.mode { crate::CollectionMode::NFT => { - let call = UniqueNFTCall::parse(method_id, &mut reader).ok()??; + let call = >::parse(method_id, &mut reader).ok()??; match call { UniqueNFTCall::ERC721UniqueExtensions( ERC721UniqueExtensionsCall::Transfer { token_id, .. }, @@ -49,7 +49,7 @@ } } crate::CollectionMode::Fungible(_) => { - let call = UniqueFungibleCall::parse(method_id, &mut reader).ok()??; + let call = >::parse(method_id, &mut reader).ok()??; #[allow(clippy::single_match)] match call { UniqueFungibleCall::ERC20(ERC20Call::Transfer { .. }) => { --- a/pallets/unique/src/lib.rs +++ b/pallets/unique/src/lib.rs @@ -16,7 +16,7 @@ pub use serde::{Serialize, Deserialize}; pub use frame_support::{ - construct_runtime, decl_module, decl_storage, decl_error, + construct_runtime, decl_module, decl_storage, decl_error, decl_event, dispatch::DispatchResult, ensure, fail, parameter_types, traits::{ @@ -87,6 +87,7 @@ OwnerPermissionsCantBeReverted, } } + pub trait Config: system::Config + pallet_evm_coder_substrate::Config @@ -97,10 +98,141 @@ + Sized + TypeInfo { + type Event: From> + Into<::Event>; + /// Weight information for extrinsics in this pallet. type WeightInfo: WeightInfo; } +decl_event! { + pub enum Event + where + ::AccountId, + ::CrossAccountId, + { + /// Collection sponsor was removed + /// + /// # Arguments + /// + /// * collection_id: Globally unique collection identifier. + CollectionSponsorRemoved(CollectionId), + + /// Collection admin was added + /// + /// # Arguments + /// + /// * collection_id: Globally unique collection identifier. + /// + /// * admin: Admin address. + CollectionAdminAdded(CollectionId, CrossAccountId), + + /// Collection owned was change + /// + /// # Arguments + /// + /// * collection_id: Globally unique collection identifier. + /// + /// * owner: New owner address. + CollectionOwnedChanged(CollectionId, AccountId), + + /// Collection sponsor was set + /// + /// # Arguments + /// + /// * collection_id: Globally unique collection identifier. + /// + /// * owner: New sponsor address. + CollectionSponsorSet(CollectionId, AccountId), + + /// const on chain schema was set + /// + /// # Arguments + /// + /// * collection_id: Globally unique collection identifier. + ConstOnChainSchemaSet(CollectionId), + + /// New sponsor was confirm + /// + /// # Arguments + /// + /// * collection_id: Globally unique collection identifier. + /// + /// * sponsor: New sponsor address. + SponsorshipConfirmed(CollectionId, AccountId), + + /// Collection admin was removed + /// + /// # Arguments + /// + /// * collection_id: Globally unique collection identifier. + /// + /// * admin: Admin address. + CollectionAdminRemoved(CollectionId, CrossAccountId), + + /// Address was remove from allow list + /// + /// # Arguments + /// + /// * collection_id: Globally unique collection identifier. + /// + /// * user: Address. + AllowListAddressRemoved(CollectionId, CrossAccountId), + + /// Address was add to allow list + /// + /// # Arguments + /// + /// * collection_id: Globally unique collection identifier. + /// + /// * user: Address. + AllowListAddressAdded(CollectionId, CrossAccountId), + + /// Collection limits was set + /// + /// # Arguments + /// + /// * collection_id: Globally unique collection identifier. + CollectionLimitSet(CollectionId), + + /// Mint permission was set + /// + /// # Arguments + /// + /// * collection_id: Globally unique collection identifier. + MintPermissionSet(CollectionId), + + /// Offchain schema was set + /// + /// # Arguments + /// + /// * collection_id: Globally unique collection identifier. + OffchainSchemaSet(CollectionId), + + /// Public access mode was set + /// + /// # Arguments + /// + /// * collection_id: Globally unique collection identifier. + /// + /// * mode: New access state. + PublicAccessModeSet(CollectionId, AccessMode), + + /// Schema version was set + /// + /// # Arguments + /// + /// * collection_id: Globally unique collection identifier. + SchemaVersionSet(CollectionId), + + /// Variable on chain schema was set + /// + /// # Arguments + /// + /// * collection_id: Globally unique collection identifier. + VariableOnChainSchemaSet(CollectionId), + } +} + type SelfWeightOf = ::WeightInfo; // # Used definitions @@ -162,6 +294,8 @@ { type Error = Error; + fn deposit_event() = default; + fn on_initialize(_now: T::BlockNumber) -> Weight { 0 } @@ -195,7 +329,7 @@ // Create new collection let new_collection = Collection { - owner: who.clone(), + owner: who, name: collection_name, mode: mode.clone(), mint_mode: false, @@ -289,6 +423,11 @@ true, )?; + Self::deposit_event(Event::::AllowListAddressAdded( + collection_id, + address + )); + Ok(()) } @@ -318,6 +457,11 @@ false, )?; + >::deposit_event(Event::::AllowListAddressRemoved( + collection_id, + address + )); + Ok(()) } @@ -341,7 +485,13 @@ let mut target_collection = >::try_get(collection_id)?; target_collection.check_is_owner(&sender)?; - target_collection.access = mode; + target_collection.access = mode.clone(); + + >::deposit_event(Event::::PublicAccessModeSet( + collection_id, + mode + )); + target_collection.save() } @@ -368,6 +518,11 @@ target_collection.check_is_owner(&sender)?; target_collection.mint_mode = mint_permission; + + >::deposit_event(Event::::MintPermissionSet( + collection_id + )); + target_collection.save() } @@ -391,7 +546,12 @@ let mut target_collection = >::try_get(collection_id)?; target_collection.check_is_owner(&sender)?; - target_collection.owner = new_owner; + target_collection.owner = new_owner.clone(); + >::deposit_event(Event::::CollectionOwnedChanged( + collection_id, + new_owner + )); + target_collection.save() } @@ -414,6 +574,11 @@ let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?); let collection = >::try_get(collection_id)?; + >::deposit_event(Event::::CollectionAdminAdded( + collection_id, + new_admin_id.clone() + )); + >::toggle_admin(&collection, &sender, &new_admin_id, true) } @@ -435,6 +600,11 @@ let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?); let collection = >::try_get(collection_id)?; + >::deposit_event(Event::::CollectionAdminRemoved( + collection_id, + account_id.clone() + )); + >::toggle_admin(&collection, &sender, &account_id, false) } @@ -455,7 +625,13 @@ let mut target_collection = >::try_get(collection_id)?; target_collection.check_is_owner(&sender)?; - target_collection.sponsorship = SponsorshipState::Unconfirmed(new_sponsor); + target_collection.sponsorship = SponsorshipState::Unconfirmed(new_sponsor.clone()); + + >::deposit_event(Event::::CollectionSponsorSet( + collection_id, + new_sponsor + )); + target_collection.save() } @@ -477,7 +653,13 @@ Error::::ConfirmUnsetSponsorFail ); - target_collection.sponsorship = SponsorshipState::Confirmed(sender); + target_collection.sponsorship = SponsorshipState::Confirmed(sender.clone()); + + >::deposit_event(Event::::SponsorshipConfirmed( + collection_id, + sender + )); + target_collection.save() } @@ -499,6 +681,10 @@ target_collection.check_is_owner(&sender)?; target_collection.sponsorship = SponsorshipState::Disabled; + + >::deposit_event(Event::::CollectionSponsorRemoved( + collection_id + )); target_collection.save() } @@ -793,6 +979,11 @@ let mut target_collection = >::try_get(collection_id)?; target_collection.check_is_owner_or_admin(&sender)?; target_collection.schema_version = version; + + >::deposit_event(Event::::SchemaVersionSet( + collection_id + )); + target_collection.save() } @@ -823,6 +1014,11 @@ ensure!(schema.len() as u32 <= OFFCHAIN_SCHEMA_LIMIT, ""); target_collection.offchain_schema = schema; + + >::deposit_event(Event::::OffchainSchemaSet( + collection_id + )); + target_collection.save() } @@ -853,6 +1049,11 @@ ensure!(schema.len() as u32 <= CONST_ON_CHAIN_SCHEMA_LIMIT, ""); target_collection.const_on_chain_schema = schema; + + >::deposit_event(Event::::ConstOnChainSchemaSet( + collection_id + )); + target_collection.save() } @@ -883,6 +1084,11 @@ ensure!(schema.len() as u32 <= VARIABLE_ON_CHAIN_SCHEMA_LIMIT, ""); target_collection.variable_on_chain_schema = schema; + + >::deposit_event(Event::::VariableOnChainSchemaSet( + collection_id + )); + target_collection.save() } @@ -949,6 +1155,10 @@ target_collection.limits = new_limit; + >::deposit_event(Event::::CollectionLimitSet( + collection_id + )); + target_collection.save() } } --- a/pallets/unique/src/mock.rs +++ b/pallets/unique/src/mock.rs @@ -1,7 +1,7 @@ #![allow(clippy::from_over_into)] use crate as pallet_template; -use sp_core::H256; +use sp_core::{H160, H256}; use frame_support::{parameter_types, traits::Everything, weights::IdentityFee}; use sp_runtime::{ traits::{BlakeTwo256, IdentityLookup}, @@ -159,15 +159,16 @@ pub struct TestEtheremTransactionSender; impl pallet_ethereum::EthereumTransactionSender for TestEtheremTransactionSender { fn submit_logs_transaction( + _source: H160, _tx: pallet_ethereum::Transaction, _logs: Vec, - ) -> Result<(), sp_runtime::DispatchError> { - Ok(()) + ) { } } impl pallet_evm_coder_substrate::Config for Test { type EthereumTransactionSender = TestEtheremTransactionSender; + type GasWeightMapping = (); } impl pallet_common::Config for Test { --- a/pallets/unique/src/tests.rs +++ b/pallets/unique/src/tests.rs @@ -2247,7 +2247,7 @@ #[test] fn create_max_collections() { new_test_ext().execute_with(|| { - for i in 1..=COLLECTION_NUMBER_LIMIT { + for i in 1..COLLECTION_NUMBER_LIMIT { create_test_collection(&CollectionMode::NFT, CollectionId(i)); } }); @@ -2259,7 +2259,7 @@ new_test_ext().execute_with(|| { let origin1 = Origin::signed(1); - for i in 1..=COLLECTION_NUMBER_LIMIT { + for i in 1..COLLECTION_NUMBER_LIMIT { create_test_collection(&CollectionMode::NFT, CollectionId(i)); } --- a/pallets/unique/src/weights.rs +++ b/pallets/unique/src/weights.rs @@ -25,6 +25,7 @@ #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] #![allow(unused_imports)] +#![allow(clippy::unnecessary_cast)] use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; use sp_std::marker::PhantomData; --- a/primitives/data-structs/Cargo.toml +++ b/primitives/data-structs/Cargo.toml @@ -2,7 +2,7 @@ name = "up-data-structs" authors = ["Unique Network "] description = "Unique data structs definitions" -edition = "2018" +edition = "2021" license = 'All Rights Reserved' homepage = "https://unique.network" repository = 'https://github.com/UniqueNetwork/unique-chain' --- a/primitives/data-structs/src/lib.rs +++ b/primitives/data-structs/src/lib.rs @@ -31,7 +31,7 @@ pub const MAX_SPONSOR_TIMEOUT: u32 = 10_368_000; pub const MAX_TOKEN_OWNERSHIP: u32 = if cfg!(not(feature = "limit-testing")) { - 10_000_000 + 100_000 } else { 10 }; @@ -61,9 +61,9 @@ pub const SPONSOR_APPROVE_TIMEOUT: u32 = 5; // Schema limits -pub const OFFCHAIN_SCHEMA_LIMIT: u32 = 1024; -pub const VARIABLE_ON_CHAIN_SCHEMA_LIMIT: u32 = 1024; -pub const CONST_ON_CHAIN_SCHEMA_LIMIT: u32 = 1024; +pub const OFFCHAIN_SCHEMA_LIMIT: u32 = 8192; +pub const VARIABLE_ON_CHAIN_SCHEMA_LIMIT: u32 = 8192; +pub const CONST_ON_CHAIN_SCHEMA_LIMIT: u32 = 1048576; pub const MAX_COLLECTION_NAME_LENGTH: usize = 64; pub const MAX_COLLECTION_DESCRIPTION_LENGTH: usize = 256; @@ -331,8 +331,7 @@ D: ser::Serializer, V: Serialize, { - let vec: &Vec<_> = &value; - vec.serialize(serializer) + (value as &Vec<_>).serialize(serializer) } pub fn deserialize<'de, D, V, S>(deserializer: D) -> Result, D::Error> --- a/primitives/evm-mapping/Cargo.toml +++ b/primitives/evm-mapping/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "up-evm-mapping" version = "0.1.0" -edition = "2018" +edition = "2021" [dependencies] sp-core = { default-features = false, git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.12' } @@ -9,7 +9,4 @@ [features] default = ["std"] -std = [ - "sp-core/std", - "frame-support/std", -] +std = ["sp-core/std", "frame-support/std"] --- a/primitives/rpc/Cargo.toml +++ b/primitives/rpc/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "up-rpc" version = "0.1.0" -edition = "2018" +edition = "2021" [dependencies] pallet-common = { default-features = false, path = '../../pallets/common' } --- a/runtime/Cargo.toml +++ b/runtime/Cargo.toml @@ -23,7 +23,9 @@ 'frame-support/runtime-benchmarks', 'frame-system-benchmarking', 'frame-system/runtime-benchmarks', + 'pallet-ethereum/runtime-benchmarks', 'pallet-evm-migration/runtime-benchmarks', + 'pallet-evm-coder-substrate/runtime-benchmarks', 'pallet-balances/runtime-benchmarks', 'pallet-timestamp/runtime-benchmarks', 'pallet-common/runtime-benchmarks', @@ -391,10 +393,10 @@ pallet-evm-transaction-payment = { path = '../pallets/evm-transaction-payment', default-features = false } pallet-evm-coder-substrate = { default-features = false, path = "../pallets/evm-coder-substrate" } -pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier.git", branch = "unique-polkadot-v0.9.12" } -pallet-ethereum = { default-features = false, git = "https://github.com/uniquenetwork/frontier.git", branch = "unique-polkadot-v0.9.12" } -fp-rpc = { default-features = false, git = "https://github.com/uniquenetwork/frontier.git", branch = "unique-polkadot-v0.9.12" } -fp-self-contained = { default-features = false, git = "https://github.com/uniquenetwork/frontier.git", branch = "unique-polkadot-v0.9.12" } +pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier.git", branch = "unique-polkadot-v0.9.12-weights" } +pallet-ethereum = { default-features = false, git = "https://github.com/uniquenetwork/frontier.git", branch = "unique-polkadot-v0.9.12-weights" } +fp-rpc = { default-features = false, git = "https://github.com/uniquenetwork/frontier.git", branch = "unique-polkadot-v0.9.12-weights" } +fp-self-contained = { default-features = false, git = "https://github.com/uniquenetwork/frontier.git", branch = "unique-polkadot-v0.9.12-weights" } ################################################################################ # Build Dependencies --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -65,7 +65,7 @@ }; use smallvec::smallvec; use codec::{Encode, Decode}; -use pallet_evm::{Account as EVMAccount, FeeCalculator, OnMethodCall}; +use pallet_evm::{Account as EVMAccount, FeeCalculator, GasWeightMapping, OnMethodCall}; use fp_rpc::TransactionStatus; use sp_core::crypto::Public; use sp_runtime::{ @@ -242,14 +242,42 @@ pub struct FixedFee; impl FeeCalculator for FixedFee { fn min_gas_price() -> U256 { - 1.into() + // Targeting 0.15 UNQ per transfer + 1_024_947_215_000u64.into() + } +} + +// Assuming slowest ethereum opcode is SSTORE, with gas price of 20000 as our worst case +// (contract, which only writes a lot of data), +// approximating on top of our real store write weight +parameter_types! { + pub const WritesPerSecond: u64 = WEIGHT_PER_SECOND / ::DbWeight::get().write; + pub const GasPerSecond: u64 = WritesPerSecond::get() * 20000; + pub const WeightPerGas: u64 = WEIGHT_PER_SECOND / GasPerSecond::get(); +} + +/// Limiting EVM execution to 50% of block for substrate users and management tasks +/// EVM transaction consumes more weight than substrate's, so we can't rely on them being +/// scheduled fairly +const EVM_DISPATCH_RATIO: Perbill = Perbill::from_percent(50); +parameter_types! { + pub BlockGasLimit: U256 = U256::from(NORMAL_DISPATCH_RATIO * EVM_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT / WeightPerGas::get()); +} + +pub enum FixedGasWeightMapping {} +impl GasWeightMapping for FixedGasWeightMapping { + fn gas_to_weight(gas: u64) -> Weight { + gas.saturating_mul(WeightPerGas::get()) } + fn weight_to_gas(weight: Weight) -> u64 { + weight / WeightPerGas::get() + } } impl pallet_evm::Config for Runtime { type BlockGasLimit = BlockGasLimit; type FeeCalculator = FixedFee; - type GasWeightMapping = (); + type GasWeightMapping = FixedGasWeightMapping; type BlockHashMapping = pallet_ethereum::EthereumBlockHashMapping; type CallOrigin = EnsureAddressTruncated; type WithdrawOrigin = EnsureAddressTruncated; @@ -286,16 +314,11 @@ } None } -} - -parameter_types! { - pub BlockGasLimit: U256 = U256::from(u32::max_value()); } impl pallet_ethereum::Config for Runtime { type Event = Event; type StateRoot = pallet_ethereum::IntermediateStateRoot; - type EvmSubmitLog = pallet_evm::Pallet; } impl pallet_randomness_collective_flip::Config for Runtime {} @@ -380,7 +403,7 @@ type WeightInfo = pallet_balances::weights::SubstrateWeight; } -pub const MICROUNIQUE: Balance = 1_000_000_000; +pub const MICROUNIQUE: Balance = 1_000_000_000_000; pub const MILLIUNIQUE: Balance = 1_000 * MICROUNIQUE; pub const CENTIUNIQUE: Balance = 10 * MILLIUNIQUE; pub const UNIQUE: Balance = 100 * CENTIUNIQUE; @@ -457,7 +480,8 @@ fn polynomial() -> WeightToFeeCoefficients { smallvec!(WeightToFeeCoefficient { - coeff_integer: 146_700u32.into(), // Targeting 0.1 Unique per NFT transfer + // Targeting 0.1 Unique per NFT transfer + coeff_integer: 142_688_000u32.into(), coeff_frac: Perbill::zero(), negative: false, degree: 1, @@ -686,6 +710,7 @@ impl pallet_evm_coder_substrate::Config for Runtime { type EthereumTransactionSender = pallet_ethereum::Pallet; + type GasWeightMapping = FixedGasWeightMapping; } impl pallet_xcm::Config for Runtime { @@ -756,6 +781,7 @@ } impl pallet_unique::Config for Runtime { + type Event = Event; type WeightInfo = pallet_unique::weights::SubstrateWeight; } @@ -856,7 +882,7 @@ // Unique Pallets Inflation: pallet_inflation::{Pallet, Call, Storage} = 60, - Unique: pallet_unique::{Pallet, Call, Storage} = 61, + Unique: pallet_unique::{Pallet, Call, Storage, Event} = 61, // Scheduler: pallet_unq_scheduler::{Pallet, Call, Storage, Event} = 62, // free = 63 Charging: pallet_charge_transaction::{Pallet, Call, Storage } = 64, @@ -1151,6 +1177,7 @@ EVM::account_storages(address, H256::from_slice(&tmp[..])) } + #[allow(clippy::redundant_closure)] fn call( from: H160, to: H160, @@ -1181,6 +1208,7 @@ ).map_err(|err| err.into()) } + #[allow(clippy::redundant_closure)] fn create( from: H160, data: Vec, @@ -1342,6 +1370,7 @@ list_benchmark!(list, extra, pallet_fungible, Fungible); list_benchmark!(list, extra, pallet_refungible, Refungible); list_benchmark!(list, extra, pallet_nonfungible, Nonfungible); + // list_benchmark!(list, extra, pallet_evm_coder_substrate, EvmCoderSubstrate); let storage_info = AllPalletsWithSystem::storage_info(); @@ -1375,6 +1404,7 @@ add_benchmark!(params, batches, pallet_fungible, Fungible); add_benchmark!(params, batches, pallet_refungible, Refungible); add_benchmark!(params, batches, pallet_nonfungible, Nonfungible); + // add_benchmark!(params, batches, pallet_evm_coder_substrate, EvmCoderSubstrate); if batches.is_empty() { return Err("Benchmark not found for this pallet.".into()) } Ok(batches) --- a/smart_contracs/transfer/Cargo.toml +++ b/smart_contracs/transfer/Cargo.toml @@ -2,7 +2,7 @@ name = "nft_transfer" version = "0.1.0" authors = ["[Greg Zaitsev] <[your_email]>"] -edition = "2018" +edition = "2021" [workspace] --- a/tests/README.md +++ b/tests/README.md @@ -8,7 +8,7 @@ git checkout release-v0.9.12 ``` -2. Build with nightly-2021-06-28 +2. Build with nightly-2021-11-11 ```bash cargo build --release ``` @@ -28,4 +28,3 @@ 1. Run `yarn install`. 2. Optional step - configure tests with env variables or by editing [configuration file](src/config.ts). 3. Run `yarn test`. - --- a/tests/flipper-src/Cargo.toml +++ b/tests/flipper-src/Cargo.toml @@ -2,7 +2,7 @@ name = "flipper" version = "3.0.0-rc1" authors = ["Parity Technologies "] -edition = "2018" +edition = "2021" [dependencies] ink_primitives = { version = "3.0.0-rc1", git = "https://github.com/paritytech/ink", tag = "v3.0.0-rc1", default-features = false } @@ -32,4 +32,4 @@ "scale-info", "scale-info/std", ] -ink-as-dependency = [] \ No newline at end of file +ink-as-dependency = [] --- a/tests/ink-types-node-runtime/Cargo.toml +++ b/tests/ink-types-node-runtime/Cargo.toml @@ -2,7 +2,7 @@ name = "ink_types_node_runtime" version = "0.1.0" authors = ["Parity Technologies "] -edition = "2018" +edition = "2021" license = "GPL-3.0" readme = "README.md" --- a/tests/ink-types-node-runtime/examples/calls/.ink/abi_gen/Cargo.toml +++ b/tests/ink-types-node-runtime/examples/calls/.ink/abi_gen/Cargo.toml @@ -2,7 +2,7 @@ name = "abi-gen" version = "0.1.0" authors = ["Parity Technologies "] -edition = "2018" +edition = "2021" publish = false [[bin]] --- a/tests/ink-types-node-runtime/examples/calls/Cargo.toml +++ b/tests/ink-types-node-runtime/examples/calls/Cargo.toml @@ -2,7 +2,7 @@ name = "calls" version = "0.1.0" authors = ["Parity Technologies "] -edition = "2018" +edition = "2021" [dependencies] ink_abi = { version = "2", git = "https://github.com/paritytech/ink", tag = "latest-v2", package = "ink_abi", default-features = false, features = ["derive"], optional = true } --- a/tests/loadtester-src/Cargo.toml +++ b/tests/loadtester-src/Cargo.toml @@ -2,7 +2,7 @@ name = "loadtester" version = "0.1.0" authors = ["[your_name] <[your_email]>"] -edition = "2018" +edition = "2021" [dependencies] ink_primitives = { version = "3.0.0-rc2", default-features = false } --- a/tests/src/confirmSponsorship.test.ts +++ b/tests/src/confirmSponsorship.test.ts @@ -21,6 +21,7 @@ normalizeAccountId, addCollectionAdminExpectSuccess, getCreatedCollectionCount, + UNIQUE, } from './util/helpers'; import {Keyring} from '@polkadot/api'; import {IKeyringPair} from '@polkadot/types/types'; @@ -198,7 +199,7 @@ const sponsorBalanceAfter = (await api.query.system.account(bob.address)).data.free.toBigInt(); // Try again after Zero gets some balance - now it should succeed - const balancetx = api.tx.balances.transfer(zeroBalance.address, 1e15); + const balancetx = api.tx.balances.transfer(zeroBalance.address, 1n * UNIQUE); await submitTransactionAsync(alice, balancetx); const events2 = await submitTransactionAsync(zeroBalance, zeroToAlice); const result2 = getGenericResult(events2); @@ -232,7 +233,7 @@ const sponsorBalanceAfter = (await api.query.system.account(bob.address)).data.free.toBigInt(); // Try again after Zero gets some balance - now it should succeed - const balancetx = api.tx.balances.transfer(zeroBalance.address, 1e15); + const balancetx = api.tx.balances.transfer(zeroBalance.address, 1n * UNIQUE); await submitTransactionAsync(alice, balancetx); const events2 = await submitTransactionAsync(zeroBalance, zeroToAlice); const result2 = getGenericResult(events2); @@ -268,7 +269,7 @@ expect(sponsorBalanceAfter).to.be.equal(sponsorBalanceBefore); // Try again after Zero gets some balance - now it should succeed - const balancetx = api.tx.balances.transfer(zeroBalance.address, 1e15); + const balancetx = api.tx.balances.transfer(zeroBalance.address, 1n * UNIQUE); await submitTransactionAsync(alice, balancetx); const events2 = await submitTransactionAsync(zeroBalance, zeroToAlice); const result2 = getGenericResult(events2); @@ -307,7 +308,7 @@ const sponsorBalanceAfter = (await api.query.system.account(bob.address)).data.free.toBigInt(); // Try again after Zero gets some balance - now it should succeed - const balancetx = api.tx.balances.transfer(zeroBalance.address, 1e15); + const balancetx = api.tx.balances.transfer(zeroBalance.address, 1n * UNIQUE); await submitTransactionAsync(alice, balancetx); await createItemExpectSuccess(zeroBalance, collectionId, 'NFT', zeroBalance.address); --- a/tests/src/creditFeesToTreasury.test.ts +++ b/tests/src/creditFeesToTreasury.test.ts @@ -154,8 +154,8 @@ const aliceBalanceAfter: bigint = (await api.query.system.account(alicesPublicKey)).data.free.toBigInt(); const fee = aliceBalanceBefore - aliceBalanceAfter; - expect(fee / 10n ** 15n < BigInt(Math.ceil(saneMaximumFee + createCollectionDeposit))).to.be.true; - expect(fee / 10n ** 15n < BigInt(Math.ceil(saneMinimumFee + createCollectionDeposit))).to.be.true; + expect(fee / UNIQUE < BigInt(Math.ceil(saneMaximumFee + createCollectionDeposit))).to.be.true; + expect(fee / UNIQUE < BigInt(Math.ceil(saneMinimumFee + createCollectionDeposit))).to.be.true; }); }); @@ -170,11 +170,13 @@ const aliceBalanceBefore: bigint = (await api.query.system.account(alicesPublicKey)).data.free.toBigInt(); await transferExpectSuccess(collectionId, tokenId, alice, bob, 1, 'NFT'); const aliceBalanceAfter: bigint = (await api.query.system.account(alicesPublicKey)).data.free.toBigInt(); + const fee = Number(aliceBalanceBefore - aliceBalanceAfter) / Number(UNIQUE); - const expectedTransferFee = 0.1; + // fee drifts because of NextFeeMultiplier const tolerance = 0.001; - expect(Number(fee) / Number(UNIQUE) - expectedTransferFee).to.be.lessThan(tolerance); + + expect(Math.abs(fee - expectedTransferFee)).to.be.lessThan(tolerance); }); }); --- a/tests/src/eth/api/ContractHelpers.sol +++ b/tests/src/eth/api/ContractHelpers.sol @@ -12,6 +12,7 @@ function supportsInterface(bytes4 interfaceID) external view returns (bool); } +// Selector: 31acb1fe interface ContractHelpers is Dummy, ERC165 { // Selector: contractOwner(address) 5152b14c function contractOwner(address contractAddress) --- a/tests/src/eth/api/UniqueFungible.sol +++ b/tests/src/eth/api/UniqueFungible.sol @@ -22,6 +22,7 @@ ); } +// Selector: 942e8b22 interface ERC20 is Dummy, ERC165, ERC20Events { // Selector: name() 06fdde03 function name() external view returns (string memory); --- a/tests/src/eth/api/UniqueNFT.sol +++ b/tests/src/eth/api/UniqueNFT.sol @@ -42,6 +42,13 @@ event MintingFinished(); } +// Selector: 42966c68 +interface ERC721Burnable is Dummy, ERC165 { + // Selector: burn(uint256) 42966c68 + function burn(uint256 tokenId) external; +} + +// Selector: 58800161 interface ERC721 is Dummy, ERC165, ERC721Events { // Selector: balanceOf(address) 70a08231 function balanceOf(address owner) external view returns (uint256); @@ -49,6 +56,8 @@ // Selector: ownerOf(uint256) 6352211e function ownerOf(uint256 tokenId) external view returns (address); + // Not implemented + // // Selector: safeTransferFromWithData(address,address,uint256,bytes) 60a11672 function safeTransferFromWithData( address from, @@ -57,6 +66,8 @@ bytes memory data ) external; + // Not implemented + // // Selector: safeTransferFrom(address,address,uint256) 42842e0e function safeTransferFrom( address from, @@ -74,12 +85,18 @@ // Selector: approve(address,uint256) 095ea7b3 function approve(address approved, uint256 tokenId) external; + // Not implemented + // // Selector: setApprovalForAll(address,bool) a22cb465 function setApprovalForAll(address operator, bool approved) external; + // Not implemented + // // Selector: getApproved(uint256) 081812fc function getApproved(uint256 tokenId) external view returns (address); + // Not implemented + // // Selector: isApprovedForAll(address,address) e985e9c5 function isApprovedForAll(address owner, address operator) external @@ -87,25 +104,7 @@ returns (address); } -interface ERC721Burnable is Dummy, ERC165 { - // Selector: burn(uint256) 42966c68 - function burn(uint256 tokenId) external; -} - -interface ERC721Enumerable is Dummy, ERC165 { - // Selector: tokenByIndex(uint256) 4f6ccce7 - function tokenByIndex(uint256 index) external view returns (uint256); - - // Selector: tokenOfOwnerByIndex(address,uint256) 2f745c59 - function tokenOfOwnerByIndex(address owner, uint256 index) - external - view - returns (uint256); - - // Selector: totalSupply() 18160ddd - function totalSupply() external view returns (uint256); -} - +// Selector: 5b5e139f interface ERC721Metadata is Dummy, ERC165 { // Selector: name() 06fdde03 function name() external view returns (string memory); @@ -113,17 +112,26 @@ // Selector: symbol() 95d89b41 function symbol() external view returns (string memory); + // Returns token's const_metadata + // // Selector: tokenURI(uint256) c87b56dd function tokenURI(uint256 tokenId) external view returns (string memory); } +// Selector: 68ccfe89 interface ERC721Mintable is Dummy, ERC165, ERC721MintableEvents { // Selector: mintingFinished() 05d2035b function mintingFinished() external view returns (bool); + // `token_id` should be obtained with `next_token_id` method, + // unlike standard, you can't specify it manually + // // Selector: mint(address,uint256) 40c10f19 function mint(address to, uint256 tokenId) external returns (bool); + // `token_id` should be obtained with `next_token_id` method, + // unlike standard, you can't specify it manually + // // Selector: mintWithTokenURI(address,uint256,string) 50bb4e7f function mintWithTokenURI( address to, @@ -131,10 +139,30 @@ string memory tokenUri ) external returns (bool); + // Not implemented + // // Selector: finishMinting() 7d64bcb4 function finishMinting() external returns (bool); } +// Selector: 780e9d63 +interface ERC721Enumerable is Dummy, ERC165 { + // Selector: tokenByIndex(uint256) 4f6ccce7 + function tokenByIndex(uint256 index) external view returns (uint256); + + // Not implemented + // + // Selector: tokenOfOwnerByIndex(address,uint256) 2f745c59 + function tokenOfOwnerByIndex(address owner, uint256 index) + external + view + returns (uint256); + + // Selector: totalSupply() 18160ddd + function totalSupply() external view returns (uint256); +} + +// Selector: e562194d interface ERC721UniqueExtensions is Dummy, ERC165 { // Selector: transfer(address,uint256) a9059cbb function transfer(address to, uint256 tokenId) external; --- a/tests/src/eth/base.test.ts +++ b/tests/src/eth/base.test.ts @@ -1,7 +1,9 @@ -import {createEthAccount, createEthAccountWithBalance, deployFlipper, ethBalanceViaSub, GAS_ARGS, itWeb3, recordEthFee} from './util/helpers'; +import {collectionIdToAddress, createEthAccount, createEthAccountWithBalance, deployFlipper, ethBalanceViaSub, GAS_ARGS, itWeb3, recordEthFee} from './util/helpers'; import {expect} from 'chai'; -import {UNIQUE} from '../util/helpers'; +import {createCollectionExpectSuccess, createItemExpectSuccess, UNIQUE} from '../util/helpers'; +import nonFungibleAbi from './nonFungibleAbi.json'; +import privateKey from '../substrate/privateKey'; describe('Contract calls', () => { itWeb3('Call of simple contract fee is less than 0.2 UNQ', async ({web3, api}) => { @@ -19,4 +21,26 @@ const cost = await recordEthFee(api, userA, () => web3.eth.sendTransaction({from: userA, to: userB, value: '1000000', ...GAS_ARGS})); expect(cost - await ethBalanceViaSub(api, userB) < BigInt(0.2 * Number(UNIQUE))).to.be.true; }); + + itWeb3('NFT transfer is close to 0.15 UNQ', async ({web3, api}) => { + const caller = await createEthAccountWithBalance(api, web3); + const receiver = createEthAccount(web3); + + const alice = privateKey('//Alice'); + const collection = await createCollectionExpectSuccess({ + mode: {type: 'NFT'}, + }); + const itemId = await createItemExpectSuccess(alice, collection, 'NFT', {Ethereum: caller}); + + const address = collectionIdToAddress(collection); + const contract = new web3.eth.Contract(nonFungibleAbi as any, address, {from: caller, ...GAS_ARGS}); + + const cost = await recordEthFee(api, caller, () => contract.methods.transfer(receiver, itemId).send(caller)); + + const fee = Number(cost) / Number(UNIQUE); + const expectedFee = 0.15; + const tolerance = 0.00001; + + expect(Math.abs(fee - expectedFee)).to.be.lessThan(tolerance); + }); }); --- a/tests/src/eth/fungible.test.ts +++ b/tests/src/eth/fungible.test.ts @@ -95,12 +95,12 @@ const alice = privateKey('//Alice'); const owner = createEthAccount(web3); - await transferBalanceToEth(api, alice, owner, 999999999999999); + await transferBalanceToEth(api, alice, owner); await createFungibleItemExpectSuccess(alice, collection, {Value: 200n}, {Ethereum: owner}); const spender = createEthAccount(web3); - await transferBalanceToEth(api, alice, spender, 999999999999999); + await transferBalanceToEth(api, alice, spender); const receiver = createEthAccount(web3); @@ -153,12 +153,12 @@ const alice = privateKey('//Alice'); const owner = createEthAccount(web3); - await transferBalanceToEth(api, alice, owner, 999999999999999); + await transferBalanceToEth(api, alice, owner); await createFungibleItemExpectSuccess(alice, collection, {Value: 200n}, {Ethereum: owner}); const receiver = createEthAccount(web3); - await transferBalanceToEth(api, alice, receiver, 999999999999999); + await transferBalanceToEth(api, alice, receiver); const address = collectionIdToAddress(collection); const contract = new web3.eth.Contract(fungibleAbi as any, address, {from: owner, ...GAS_ARGS}); --- a/tests/src/eth/marketplace/marketplace.test.ts +++ b/tests/src/eth/marketplace/marketplace.test.ts @@ -1,7 +1,7 @@ import {readFile} from 'fs/promises'; import {getBalanceSingle, transferBalanceExpectSuccess} from '../../substrate/get-balance'; import privateKey from '../../substrate/privateKey'; -import {addToAllowListExpectSuccess, confirmSponsorshipExpectSuccess, createCollectionExpectSuccess, createFungibleItemExpectSuccess, createItemExpectSuccess, getTokenOwner, setCollectionSponsorExpectSuccess, transferExpectSuccess, transferFromExpectSuccess} from '../../util/helpers'; +import {addToAllowListExpectSuccess, confirmSponsorshipExpectSuccess, createCollectionExpectSuccess, createFungibleItemExpectSuccess, createItemExpectSuccess, getTokenOwner, setCollectionLimitsExpectSuccess, setCollectionSponsorExpectSuccess, transferExpectSuccess, transferFromExpectSuccess} from '../../util/helpers'; import {collectionIdToAddress, contractHelpers, createEthAccountWithBalance, executeEthTxOnSub, GAS_ARGS, itWeb3, subToEth, subToEthLowercase, transferBalanceToEth} from '../util/helpers'; import {evmToAddress} from '@polkadot/util-crypto'; import nonFungibleAbi from '../nonFungibleAbi.json'; @@ -13,38 +13,42 @@ describe('Matcher contract usage', () => { itWeb3('With UNQ', async ({api, web3}) => { const alice = privateKey('//Alice'); - const collectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}}); - const evmCollection = new web3.eth.Contract(nonFungibleAbi as any, collectionIdToAddress(collectionId)); const matcherOwner = await createEthAccountWithBalance(api, web3); - const helpers = contractHelpers(web3, matcherOwner); - const matcherContract = new web3.eth.Contract(JSON.parse((await readFile(`${__dirname}/MarketPlace.abi`)).toString()), undefined, { from: matcherOwner, ...GAS_ARGS, }); const matcher = await matcherContract.deploy({data: (await readFile(`${__dirname}/MarketPlace.bin`)).toString(), arguments:[matcherOwner]}).send({from: matcherOwner}); - - await transferBalanceToEth(api, alice, matcher.options.address); + const helpers = contractHelpers(web3, matcherOwner); await helpers.methods.toggleSponsoring(matcher.options.address, true).send({from: matcherOwner}); + await helpers.methods.setSponsoringRateLimit(matcher.options.address, 1).send({from: matcherOwner}); + await transferBalanceToEth(api, alice, matcher.options.address); - await transferBalanceToEth(api, alice, subToEth(alice.address)); + const collectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}}); + await setCollectionLimitsExpectSuccess(alice, collectionId, {sponsorApproveTimeout: 1}); + const evmCollection = new web3.eth.Contract(nonFungibleAbi as any, collectionIdToAddress(collectionId), {from: matcherOwner}); await setCollectionSponsorExpectSuccess(collectionId, alice.address); + await transferBalanceToEth(api, alice, subToEth(alice.address)); await confirmSponsorshipExpectSuccess(collectionId); - const seller = privateKey('//Seller/' + Date.now()); - await addToAllowListExpectSuccess(alice, collectionId, {Ethereum:subToEth(seller.address)}); + await helpers.methods.toggleAllowed(matcher.options.address, subToEth(alice.address), true).send({from: matcherOwner}); + await addToAllowListExpectSuccess(alice, collectionId, evmToAddress(subToEth(alice.address))); + + const seller = privateKey(`//Seller/${Date.now()}`); await helpers.methods.toggleAllowed(matcher.options.address, subToEth(seller.address), true).send({from: matcherOwner}); const tokenId = await createItemExpectSuccess(alice, collectionId, 'NFT', seller.address); - // To transfer item to matcher it first needs to be transfered to EVM account of seller + // To transfer item to matcher it first needs to be transfered to EVM account of bob await transferExpectSuccess(collectionId, tokenId, seller, {Ethereum: subToEth(seller.address)}); + + // Token is owned by seller initially expect(await getTokenOwner(api, collectionId, tokenId)).to.be.deep.equal({Ethereum: subToEthLowercase(seller.address)}); // Ask { - await executeEthTxOnSub(api, seller, evmCollection, m => m.approve(matcher.options.address, tokenId)); - await executeEthTxOnSub(api, seller, matcher, m => m.addAsk(PRICE, '0x0000000000000000000000000000000000000001', evmCollection.options.address, tokenId)); + await executeEthTxOnSub(web3, api, seller, evmCollection, m => m.approve(matcher.options.address, tokenId)); + await executeEthTxOnSub(web3, api, seller, matcher, m => m.addAsk(PRICE, '0x0000000000000000000000000000000000000001', evmCollection.options.address, tokenId)); } // Token is transferred to matcher @@ -53,7 +57,7 @@ // Buy { const sellerBalanceBeforePurchase = await getBalanceSingle(api, seller.address); - await executeEthTxOnSub(api, alice, matcher, m => m.buy(evmCollection.options.address, tokenId), {value: PRICE}); + await executeEthTxOnSub(web3, api, alice, matcher, m => m.buy(evmCollection.options.address, tokenId), {value: PRICE}); expect(await getBalanceSingle(api, seller.address) - sellerBalanceBeforePurchase === PRICE); } @@ -69,6 +73,7 @@ // selling for custom tokens excluded from release itWeb3.skip('With custom ERC20', async ({api, web3}) => { + const alice = privateKey('//Alice'); const matcherOwner = await createEthAccountWithBalance(api, web3); const matcherContract = new web3.eth.Contract(JSON.parse((await readFile(`${__dirname}/MarketPlace.abi`)).toString()), undefined, { from: matcherOwner, @@ -76,7 +81,6 @@ }); const matcher = await matcherContract.deploy({data: (await readFile(`${__dirname}/MarketPlace.bin`)).toString(), arguments: [matcherOwner]}).send({from: matcherOwner}); - const alice = privateKey('//Alice'); const collectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}}); const evmCollection = new web3.eth.Contract(nonFungibleAbi as any, collectionIdToAddress(collectionId), {from: matcherOwner}); @@ -99,8 +103,8 @@ // Ask { - await executeEthTxOnSub(api, seller, evmCollection, m => m.approve(matcher.options.address, tokenId)); - await executeEthTxOnSub(api, seller, matcher, m => m.setAsk(PRICE, evmFungible.options.address, evmCollection.options.address, tokenId, 1)); + await executeEthTxOnSub(web3, api, seller, evmCollection, m => m.approve(matcher.options.address, tokenId)); + await executeEthTxOnSub(web3, api, seller, matcher, m => m.addAsk(PRICE, evmFungible.options.address, evmCollection.options.address, tokenId, 1)); } // Token is transferred to matcher @@ -111,9 +115,9 @@ const sellerBalanceBeforePurchase = BigInt(await evmFungible.methods.balanceOf(subToEth(seller.address)).call()); const buyerBalanceBeforePurchase = BigInt(await evmFungible.methods.balanceOf(subToEth(alice.address)).call()); - await executeEthTxOnSub(api, alice, evmFungible, m => m.approve(matcher.options.address, PRICE)); + await executeEthTxOnSub(web3, api, alice, evmFungible, m => m.approve(matcher.options.address, PRICE)); // There is two functions named 'buy', so we should provide full signature - await executeEthTxOnSub(api, alice, matcher, m => + await executeEthTxOnSub(web3, api, alice, matcher, m => m['buy(address,uint256,address,uint256)'](evmCollection.options.address, tokenId, evmFungible.options.address, PRICE)); // Approved price is removed from buyer balance, and added to seller @@ -134,40 +138,44 @@ itWeb3('With escrow', async ({api, web3}) => { const alice = privateKey('//Alice'); - const collectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}}); - const evmCollection = new web3.eth.Contract(nonFungibleAbi as any, collectionIdToAddress(collectionId)); const matcherOwner = await createEthAccountWithBalance(api, web3); - const helpers = contractHelpers(web3, matcherOwner); const escrow = await createEthAccountWithBalance(api, web3); - const matcherContract = new web3.eth.Contract(JSON.parse((await readFile(`${__dirname}/MarketPlace.abi`)).toString()), undefined, { from: matcherOwner, ...GAS_ARGS, }); - const matcher = await matcherContract.deploy({data: (await readFile(`${__dirname}/MarketPlace.bin`)).toString(), arguments: [matcherOwner]}).send({from: matcherOwner}); + const matcher = await matcherContract.deploy({data: (await readFile(`${__dirname}/MarketPlace.bin`)).toString(), arguments: [matcherOwner]}).send({from: matcherOwner, gas: 10000000}); await matcher.methods.setEscrow(escrow).send({from: matcherOwner}); - - await transferBalanceToEth(api, alice, matcher.options.address); + const helpers = contractHelpers(web3, matcherOwner); await helpers.methods.toggleSponsoring(matcher.options.address, true).send({from: matcherOwner}); + await helpers.methods.setSponsoringRateLimit(matcher.options.address, 1).send({from: matcherOwner}); + await transferBalanceToEth(api, alice, matcher.options.address); - await transferBalanceToEth(api, alice, subToEth(alice.address)); + const collectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}}); + await setCollectionLimitsExpectSuccess(alice, collectionId, {sponsorApproveTimeout: 1}); + const evmCollection = new web3.eth.Contract(nonFungibleAbi as any, collectionIdToAddress(collectionId), {from: matcherOwner}); await setCollectionSponsorExpectSuccess(collectionId, alice.address); + await transferBalanceToEth(api, alice, subToEth(alice.address)); await confirmSponsorshipExpectSuccess(collectionId); - const seller = privateKey('//Seller/' + Date.now()); + await helpers.methods.toggleAllowed(matcher.options.address, subToEth(alice.address), true).send({from: matcherOwner}); + await addToAllowListExpectSuccess(alice, collectionId, evmToAddress(subToEth(alice.address))); + + const seller = privateKey(`//Seller/${Date.now()}`); await helpers.methods.toggleAllowed(matcher.options.address, subToEth(seller.address), true).send({from: matcherOwner}); - await addToAllowListExpectSuccess(alice, collectionId, evmToAddress(subToEth(seller.address))); const tokenId = await createItemExpectSuccess(alice, collectionId, 'NFT', seller.address); - // To transfer item to matcher it first needs to be transfered to EVM account of seller + // To transfer item to matcher it first needs to be transfered to EVM account of bob await transferExpectSuccess(collectionId, tokenId, seller, {Ethereum: subToEth(seller.address)}); + + // Token is owned by seller initially expect(await getTokenOwner(api, collectionId, tokenId)).to.be.deep.equal({Ethereum: subToEthLowercase(seller.address)}); // Ask { - await executeEthTxOnSub(api, seller, evmCollection, m => m.approve(matcher.options.address, tokenId)); - await executeEthTxOnSub(api, seller, matcher, m => m.addAsk(PRICE, '0x0000000000000000000000000000000000000001', evmCollection.options.address, tokenId)); + await executeEthTxOnSub(web3, api, seller, evmCollection, m => m.approve(matcher.options.address, tokenId)); + await executeEthTxOnSub(web3, api, seller, matcher, m => m.addAsk(PRICE, '0x0000000000000000000000000000000000000001', evmCollection.options.address, tokenId)); } // Token is transferred to matcher @@ -181,7 +189,7 @@ expect(await matcher.methods.balanceKSM(subToEth(seller.address)).call()).to.be.equal('0'); expect(await matcher.methods.balanceKSM(subToEth(alice.address)).call()).to.be.equal(PRICE.toString()); - await executeEthTxOnSub(api, alice, matcher, m => m.buyKSM(evmCollection.options.address, tokenId, subToEth(alice.address), subToEth(alice.address))); + await executeEthTxOnSub(web3, api, alice, matcher, m => m.buyKSM(evmCollection.options.address, tokenId, subToEth(alice.address), subToEth(alice.address))); // Price is removed from buyer balance, and added to seller expect(await matcher.methods.balanceKSM(subToEth(alice.address)).call()).to.be.equal('0'); --- a/tests/src/eth/nonFungible.test.ts +++ b/tests/src/eth/nonFungible.test.ts @@ -203,7 +203,7 @@ const alice = privateKey('//Alice'); const owner = createEthAccount(web3); - await transferBalanceToEth(api, alice, owner, 999999999999999); + await transferBalanceToEth(api, alice, owner); const tokenId = await createItemExpectSuccess(alice, collection, 'NFT', {Ethereum: owner}); @@ -213,7 +213,7 @@ const contract = new web3.eth.Contract(nonFungibleAbi as any, address); { - const result = await contract.methods.approve(spender, tokenId).send({from: owner, gas: '0x1000000', gasPrice: '0x01'}); + const result = await contract.methods.approve(spender, tokenId).send({from: owner, ...GAS_ARGS}); const events = normalizeEvents(result.events); expect(events).to.be.deep.equal([ @@ -237,12 +237,12 @@ const alice = privateKey('//Alice'); const owner = createEthAccount(web3); - await transferBalanceToEth(api, alice, owner, 999999999999999); + await transferBalanceToEth(api, alice, owner); const tokenId = await createItemExpectSuccess(alice, collection, 'NFT', {Ethereum: owner}); const spender = createEthAccount(web3); - await transferBalanceToEth(api, alice, spender, 999999999999999); + await transferBalanceToEth(api, alice, spender); const receiver = createEthAccount(web3); @@ -285,12 +285,12 @@ const alice = privateKey('//Alice'); const owner = createEthAccount(web3); - await transferBalanceToEth(api, alice, owner, 999999999999999); + await transferBalanceToEth(api, alice, owner); const tokenId = await createItemExpectSuccess(alice, collection, 'NFT', {Ethereum: owner}); const receiver = createEthAccount(web3); - await transferBalanceToEth(api, alice, receiver, 999999999999999); + await transferBalanceToEth(api, alice, receiver); const address = collectionIdToAddress(collection); const contract = new web3.eth.Contract(nonFungibleAbi as any, address, {from: owner, ...GAS_ARGS}); --- a/tests/src/eth/payable.test.ts +++ b/tests/src/eth/payable.test.ts @@ -1,7 +1,7 @@ import {expect} from 'chai'; import privateKey from '../substrate/privateKey'; import {submitTransactionAsync} from '../substrate/substrate-api'; -import {createEthAccountWithBalance, deployCollector, GAS_ARGS, itWeb3, subToEth} from './util/helpers'; +import {createEthAccountWithBalance, deployCollector, GAS_ARGS, itWeb3, subToEth, transferBalanceToEth} from './util/helpers'; import {evmToAddress} from '@polkadot/util-crypto'; import {getGenericResult} from '../util/helpers'; import {getBalanceSingle, transferBalanceExpectSuccess} from '../substrate/get-balance'; @@ -23,7 +23,7 @@ // Transaction fee/value will be payed from subToEth(sender) evm balance, // which is backed by evmToAddress(subToEth(sender)) substrate balance - await transferBalanceExpectSuccess(api, alice, evmToAddress(subToEth(alice.address)), '1000000000000'); + await transferBalanceToEth(api, alice, subToEth(alice.address)); { const tx = api.tx.evm.call( @@ -32,7 +32,7 @@ contract.methods.giveMoney().encodeABI(), '10000', GAS_ARGS.gas, - GAS_ARGS.gasPrice, + await web3.eth.getGasPrice(), null, ); const events = await submitTransactionAsync(alice, tx); --- a/tests/src/eth/proxy/nonFungibleProxy.test.ts +++ b/tests/src/eth/proxy/nonFungibleProxy.test.ts @@ -224,7 +224,7 @@ const tokenId = await createItemExpectSuccess(alice, collection, 'NFT', {Ethereum: contract.options.address}); { - const result = await contract.methods.approve(spender, tokenId).send({from: caller, gas: '0x1000000', gasPrice: '0x01'}); + const result = await contract.methods.approve(spender, tokenId).send({from: caller, ...GAS_ARGS}); const events = normalizeEvents(result.events); expect(events).to.be.deep.equal([ --- a/tests/src/eth/util/helpers.ts +++ b/tests/src/eth/util/helpers.ts @@ -12,14 +12,14 @@ import usingApi, {submitTransactionAsync} from '../../substrate/substrate-api'; import {IKeyringPair} from '@polkadot/types/types'; import {expect} from 'chai'; -import {getGenericResult} from '../../util/helpers'; +import {getGenericResult, UNIQUE} from '../../util/helpers'; import * as solc from 'solc'; import config from '../../config'; import privateKey from '../../substrate/privateKey'; import contractHelpersAbi from './contractHelpersAbi.json'; import getBalance from '../../substrate/get-balance'; -export const GAS_ARGS = {gas: 0x1000000, gasPrice: '0x01'}; +export const GAS_ARGS = {gas: 2500000}; let web3Connected = false; export async function usingWeb3(cb: (web3: Web3) => Promise | T): Promise { @@ -63,7 +63,7 @@ return account; } -export async function transferBalanceToEth(api: ApiPromise, source: IKeyringPair, target: string, amount = 999999999999999) { +export async function transferBalanceToEth(api: ApiPromise, source: IKeyringPair, target: string, amount = 1000n * UNIQUE) { const tx = api.tx.balances.transfer(evmToAddress(target), amount); const events = await submitTransactionAsync(source, tx); const result = getGenericResult(events); @@ -234,20 +234,20 @@ * @param mkTx - closure, receiving `contract.methods`, and returning method call, * to be used as following (assuming `to` = erc20 contract): * `m => m.transfer(to, amount)` - * + * * # Example * ```ts * executeEthTxOnSub(api, alice, erc20Contract, m => m.transfer(target, amount)); * ``` */ -export async function executeEthTxOnSub(api: ApiPromise, from: IKeyringPair, to: any, mkTx: (methods: any) => any, {value = 0}: {value?: bigint | number} = { }) { +export async function executeEthTxOnSub(web3: Web3, api: ApiPromise, from: IKeyringPair, to: any, mkTx: (methods: any) => any, {value = 0}: {value?: bigint | number} = { }) { const tx = api.tx.evm.call( subToEth(from.address), to.options.address, mkTx(to.methods).encodeABI(), value, GAS_ARGS.gas, - GAS_ARGS.gasPrice, + await web3.eth.getGasPrice(), null, ); const events = await submitTransactionAsync(from, tx); @@ -260,7 +260,7 @@ /** * Measure how much gas given closure consumes - * + * * @param user which user balance will be checked */ export async function recordEthFee(api: ApiPromise, user: string, call: () => Promise): Promise { --- a/tests/src/util/helpers.ts +++ b/tests/src/util/helpers.ts @@ -69,7 +69,7 @@ export const U128_MAX = (1n << 128n) - 1n; -const MICROUNIQUE = 1_000_000_000n; +const MICROUNIQUE = 1_000_000_000_000n; const MILLIUNIQUE = 1_000n * MICROUNIQUE; const CENTIUNIQUE = 10n * MILLIUNIQUE; export const UNIQUE = 100n * CENTIUNIQUE;