diff --git a/Cargo.lock b/Cargo.lock index 7e0248ec11..d7c7b65e46 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -300,15 +300,6 @@ version = "6.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d9b1c5a481ec30a5abd8dfbd94ab5cf1bb4e9a66be7f1b3b322f2f1170c200fd" -[[package]] -name = "array-init" -version = "0.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23589ecb866b460d3a0f1278834750268c607e8e28a1b982c907219f3178cd72" -dependencies = [ - "nodrop", -] - [[package]] name = "arrayref" version = "0.3.7" @@ -614,7 +605,7 @@ dependencies = [ "polkadot-primitives", "polkadot-runtime-common", "scale-info", - "smallvec 1.11.0", + "smallvec", "sp-api", "sp-block-builder", "sp-consensus-aura", @@ -634,6 +625,33 @@ dependencies = [ "xcm-executor", ] +[[package]] +name = "astar-xcm-benchmarks" +version = "0.1.0" +dependencies = [ + "astar-primitives", + "frame-benchmarking", + "frame-support", + "frame-system", + "log", + "pallet-assets", + "pallet-balances", + "pallet-xc-asset-config", + "pallet-xcm", + "parity-scale-codec", + "paste", + "scale-info", + "serde", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", + "sp-tracing", + "xcm", + "xcm-builder", + "xcm-executor", +] + [[package]] name = "async-channel" version = "1.9.0" @@ -687,9 +705,9 @@ dependencies = [ [[package]] name = "async-trait" -version = "0.1.73" +version = "0.1.74" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc00ceb34980c03614e35a3a4e218276a0a824e911d07651cd0d858a51e8c0f0" +checksum = "a66537f1bb974b254c98ed142ff995236e81b9d0fe4db0575f46612cb15eb0f9" dependencies = [ "proc-macro2", "quote", @@ -1182,7 +1200,7 @@ version = "0.15.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "215c0072ecc28f92eeb0eea38ba63ddfcb65c2828c46311d646f1a3ff5f9841c" dependencies = [ - "smallvec 1.11.0", + "smallvec", ] [[package]] @@ -1454,9 +1472,9 @@ dependencies = [ [[package]] name = "const-hex" -version = "1.8.0" +version = "1.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08849ed393c907c90016652a01465a12d86361cd38ad2a7de026c56a520cc259" +checksum = "c37be52ef5e3b394db27a2341010685ad5103c72ac15ce2e9420a7e8f93f342c" dependencies = [ "cfg-if", "cpufeatures", @@ -1566,7 +1584,7 @@ dependencies = [ "hashbrown 0.13.2", "log", "regalloc2", - "smallvec 1.11.0", + "smallvec", "target-lexicon", ] @@ -1602,7 +1620,7 @@ checksum = "64a25d9d0a0ae3079c463c34115ec59507b4707175454f0eee0891e83e30e82d" dependencies = [ "cranelift-codegen", "log", - "smallvec 1.11.0", + "smallvec", "target-lexicon", ] @@ -1634,7 +1652,7 @@ dependencies = [ "cranelift-frontend", "itertools", "log", - "smallvec 1.11.0", + "smallvec", "wasmparser", "wasmtime-types", ] @@ -2858,9 +2876,9 @@ dependencies = [ [[package]] name = "enr" -version = "0.9.0" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0be7b2ac146c1f99fe245c02d16af0696450d8e06c135db75e10eeb9e642c20d" +checksum = "fe81b5c06ecfdbc71dd845216f225f53b62a10cb8a16c946836a3467f701d05b" dependencies = [ "base64 0.21.2", "bytes", @@ -2870,7 +2888,6 @@ dependencies = [ "rand 0.8.5", "rlp", "serde", - "serde-hex", "sha3", "zeroize", ] @@ -3067,9 +3084,9 @@ dependencies = [ [[package]] name = "ethers" -version = "2.0.9" +version = "2.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ba3fd516c15a9a587135229466dbbfc85796de55c5660afbbb1b1c78517d85c" +checksum = "1ad13497f6e0a24292fc7b408e30d22fe9dc262da1f40d7b542c3a44e7fc0476" dependencies = [ "ethers-addressbook", "ethers-contract", @@ -3082,9 +3099,9 @@ dependencies = [ [[package]] name = "ethers-addressbook" -version = "2.0.9" +version = "2.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0245617f11b8178fa50b52e433e2c34ac69f39116b62c8be2437decf2edf1986" +checksum = "c6e9e8acd0ed348403cc73a670c24daba3226c40b98dc1a41903766b3ab6240a" dependencies = [ "ethers-core", "once_cell", @@ -3094,9 +3111,9 @@ dependencies = [ [[package]] name = "ethers-contract" -version = "2.0.9" +version = "2.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02bb80fd2c22631a5eb8a02cbf373cc5fd86937fc966bb670b9a884580c8e71c" +checksum = "d79269278125006bb0552349c03593ffa9702112ca88bc7046cc669f148fb47c" dependencies = [ "const-hex", "ethers-contract-abigen", @@ -3113,9 +3130,9 @@ dependencies = [ [[package]] name = "ethers-contract-abigen" -version = "2.0.9" +version = "2.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22c54db0d393393e732a5b20273e4f8ab89f0cce501c84e75fab9c126799a6e6" +checksum = "ce95a43c939b2e4e2f3191c5ad4a1f279780b8a39139c9905b43a7433531e2ab" dependencies = [ "Inflector", "const-hex", @@ -3135,9 +3152,9 @@ dependencies = [ [[package]] name = "ethers-contract-derive" -version = "2.0.9" +version = "2.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62ee4f216184a1304b707ed258f4f70aa40bf7e1522ab8963d127a8d516eaa1a" +checksum = "8e9ce44906fc871b3ee8c69a695ca7ec7f70e50cb379c9b9cb5e532269e492f6" dependencies = [ "Inflector", "const-hex", @@ -3151,9 +3168,9 @@ dependencies = [ [[package]] name = "ethers-core" -version = "2.0.9" +version = "2.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c29523f73c12753165781c6e5dc11c84d3e44c080a15f7c6cfbd70b514cb6f1" +checksum = "c0a17f0708692024db9956b31d7a20163607d2745953f5ae8125ab368ba280ad" dependencies = [ "arrayvec 0.7.4", "bytes", @@ -3181,9 +3198,9 @@ dependencies = [ [[package]] name = "ethers-etherscan" -version = "2.0.9" +version = "2.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4aab5af432b3fe5b7756b60df5c9ddeb85a13414575ad8a9acd707c24f0a77a5" +checksum = "0e53451ea4a8128fbce33966da71132cf9e1040dcfd2a2084fd7733ada7b2045" dependencies = [ "ethers-core", "reqwest", @@ -3196,9 +3213,9 @@ dependencies = [ [[package]] name = "ethers-middleware" -version = "2.0.9" +version = "2.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "356151d5ded56d4918146366abc9dfc9df367cf0096492a7a5477b21b7693615" +checksum = "473f1ccd0c793871bbc248729fa8df7e6d2981d6226e4343e3bbaa9281074d5d" dependencies = [ "async-trait", "auto_impl", @@ -3223,9 +3240,9 @@ dependencies = [ [[package]] name = "ethers-providers" -version = "2.0.9" +version = "2.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00c84664b294e47fc2860d6db0db0246f79c4c724e552549631bb9505b834bee" +checksum = "6838fa110e57d572336178b7c79e94ff88ef976306852d8cb87d9e5b1fc7c0b5" dependencies = [ "async-trait", "auto_impl", @@ -3259,9 +3276,9 @@ dependencies = [ [[package]] name = "ethers-signers" -version = "2.0.9" +version = "2.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "170b299698702ef1f53d2275af7d6d97409cfa4f9398ee9ff518f6bc9102d0ad" +checksum = "5ea44bec930f12292866166f9ddbea6aa76304850e4d8dcd66dc492b43d00ff1" dependencies = [ "async-trait", "coins-bip32", @@ -3448,9 +3465,9 @@ dependencies = [ [[package]] name = "fastrand" -version = "2.0.0" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6999dc1837253364c2ebb0704ba97994bd874e8f195d665c50b7548f6ea92764" +checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" [[package]] name = "fatality" @@ -3506,7 +3523,7 @@ dependencies = [ "parity-scale-codec", "parking_lot 0.12.1", "sc-client-db", - "smallvec 1.11.0", + "smallvec", "sp-blockchain", "sp-core", "sp-database", @@ -4020,7 +4037,7 @@ dependencies = [ "paste", "scale-info", "serde", - "smallvec 1.11.0", + "smallvec", "sp-api", "sp-arithmetic", "sp-core", @@ -5301,7 +5318,7 @@ dependencies = [ "scale-info", "serde", "serde_derive", - "smallvec 1.11.0", + "smallvec", "sp-api", "sp-arithmetic", "sp-authority-discovery", @@ -5335,7 +5352,7 @@ dependencies = [ "frame-support", "polkadot-primitives", "polkadot-runtime-common", - "smallvec 1.11.0", + "smallvec", "sp-core", "sp-runtime", "sp-weights", @@ -5347,7 +5364,7 @@ version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e7d770dcb02bf6835887c3a979b5107a04ff4bbde97a5f0928d27404a155add9" dependencies = [ - "smallvec 1.11.0", + "smallvec", ] [[package]] @@ -5371,7 +5388,7 @@ dependencies = [ "parking_lot 0.12.1", "regex", "rocksdb", - "smallvec 1.11.0", + "smallvec", ] [[package]] @@ -5497,7 +5514,7 @@ dependencies = [ "quick-protobuf", "rand 0.8.5", "rw-stream-sink", - "smallvec 1.11.0", + "smallvec", "thiserror", "unsigned-varint", "void", @@ -5513,7 +5530,7 @@ dependencies = [ "libp2p-core", "log", "parking_lot 0.12.1", - "smallvec 1.11.0", + "smallvec", "trust-dns-resolver", ] @@ -5534,7 +5551,7 @@ dependencies = [ "lru 0.10.1", "quick-protobuf", "quick-protobuf-codec", - "smallvec 1.11.0", + "smallvec", "thiserror", "void", ] @@ -5578,7 +5595,7 @@ dependencies = [ "quick-protobuf", "rand 0.8.5", "sha2 0.10.7", - "smallvec 1.11.0", + "smallvec", "thiserror", "uint", "unsigned-varint", @@ -5599,7 +5616,7 @@ dependencies = [ "libp2p-swarm", "log", "rand 0.8.5", - "smallvec 1.11.0", + "smallvec", "socket2 0.4.9", "tokio", "trust-dns-proto", @@ -5695,7 +5712,7 @@ dependencies = [ "libp2p-identity", "libp2p-swarm", "rand 0.8.5", - "smallvec 1.11.0", + "smallvec", ] [[package]] @@ -5714,7 +5731,7 @@ dependencies = [ "libp2p-swarm-derive", "log", "rand 0.8.5", - "smallvec 1.11.0", + "smallvec", "tokio", "void", ] @@ -6030,7 +6047,7 @@ dependencies = [ "pallet-xvm", "parity-scale-codec", "scale-info", - "smallvec 1.11.0", + "smallvec", "sp-api", "sp-block-builder", "sp-consensus-aura", @@ -6164,12 +6181,6 @@ dependencies = [ "rawpointer", ] -[[package]] -name = "maybe-uninit" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00" - [[package]] name = "md-5" version = "0.10.5" @@ -6660,7 +6671,7 @@ dependencies = [ "futures 0.3.28", "log", "pin-project", - "smallvec 1.11.0", + "smallvec", "unsigned-varint", ] @@ -6784,12 +6795,6 @@ dependencies = [ "memoffset 0.6.5", ] -[[package]] -name = "nodrop" -version = "0.1.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb" - [[package]] name = "nohash-hasher" version = "0.2.0" @@ -7559,7 +7564,7 @@ dependencies = [ "rand_pcg", "scale-info", "serde", - "smallvec 1.11.0", + "smallvec", "sp-api", "sp-core", "sp-io", @@ -8928,7 +8933,7 @@ dependencies = [ "instant", "libc", "redox_syscall 0.2.16", - "smallvec 1.11.0", + "smallvec", "winapi", ] @@ -8941,7 +8946,7 @@ dependencies = [ "cfg-if", "libc", "redox_syscall 0.3.5", - "smallvec 1.11.0", + "smallvec", "windows-targets 0.48.1", ] @@ -9818,7 +9823,7 @@ dependencies = [ "polkadot-primitives", "polkadot-statement-table", "sc-network", - "smallvec 1.11.0", + "smallvec", "sp-api", "sp-authority-discovery", "sp-consensus-babe", @@ -10044,7 +10049,7 @@ dependencies = [ "scale-info", "serde", "serde_derive", - "smallvec 1.11.0", + "smallvec", "sp-api", "sp-arithmetic", "sp-authority-discovery", @@ -10124,7 +10129,7 @@ dependencies = [ "frame-support", "polkadot-primitives", "polkadot-runtime-common", - "smallvec 1.11.0", + "smallvec", "sp-core", "sp-runtime", "sp-weights", @@ -10705,9 +10710,9 @@ dependencies = [ [[package]] name = "quinn-proto" -version = "0.9.5" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c956be1b23f4261676aed05a0046e204e8a6836e50203902683a718af0797989" +checksum = "67c10f662eee9c94ddd7135043e544f3c82fa839a1e7b865911331961b53186c" dependencies = [ "bytes", "rand 0.8.5", @@ -10940,7 +10945,7 @@ dependencies = [ "fxhash", "log", "slice-group-by", - "smallvec 1.11.0", + "smallvec", ] [[package]] @@ -10989,9 +10994,9 @@ checksum = "2ab07dc67230e4a4718e70fd5c20055a4334b121f1f9db8fe63ef39ce9b8c846" [[package]] name = "reqwest" -version = "0.11.20" +version = "0.11.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e9ad3fe7488d7e34558a2033d45a0c90b72d97b4f80705666fea71472e2e6a1" +checksum = "046cd98826c46c2ac8ddecae268eb5c2e58628688a5fc7a2643704a73faba95b" dependencies = [ "base64 0.21.2", "bytes", @@ -11012,6 +11017,7 @@ dependencies = [ "serde", "serde_json", "serde_urlencoded", + "system-configuration", "tokio", "tower-service", "url", @@ -11171,7 +11177,7 @@ dependencies = [ "scale-info", "serde", "serde_derive", - "smallvec 1.11.0", + "smallvec", "sp-api", "sp-authority-discovery", "sp-block-builder", @@ -11203,7 +11209,7 @@ dependencies = [ "frame-support", "polkadot-primitives", "polkadot-runtime-common", - "smallvec 1.11.0", + "smallvec", "sp-core", "sp-runtime", "sp-weights", @@ -12039,7 +12045,7 @@ dependencies = [ "sc-utils", "serde", "serde_json", - "smallvec 1.11.0", + "smallvec", "snow", "sp-arithmetic", "sp-blockchain", @@ -12091,7 +12097,7 @@ dependencies = [ "sc-peerset", "sc-utils", "serde", - "smallvec 1.11.0", + "smallvec", "sp-blockchain", "sp-consensus", "sp-consensus-grandpa", @@ -12167,7 +12173,7 @@ dependencies = [ "sc-network-common", "sc-peerset", "sc-utils", - "smallvec 1.11.0", + "smallvec", "sp-arithmetic", "sp-blockchain", "sp-consensus", @@ -12845,17 +12851,6 @@ dependencies = [ "serde_derive", ] -[[package]] -name = "serde-hex" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca37e3e4d1b39afd7ff11ee4e947efae85adfddf4841787bfa47c470e96dc26d" -dependencies = [ - "array-init", - "serde", - "smallvec 0.6.14", -] - [[package]] name = "serde_derive" version = "1.0.171" @@ -12984,6 +12979,7 @@ version = "5.20.0" dependencies = [ "array-bytes 6.1.0", "astar-primitives", + "astar-xcm-benchmarks", "cumulus-pallet-aura-ext", "cumulus-pallet-dmp-queue", "cumulus-pallet-parachain-system", @@ -13064,7 +13060,7 @@ dependencies = [ "polkadot-primitives", "polkadot-runtime-common", "scale-info", - "smallvec 1.11.0", + "smallvec", "sp-api", "sp-block-builder", "sp-consensus-aura", @@ -13158,7 +13154,7 @@ dependencies = [ "polkadot-primitives", "polkadot-runtime-common", "scale-info", - "smallvec 1.11.0", + "smallvec", "sp-api", "sp-block-builder", "sp-consensus-aura", @@ -13312,15 +13308,6 @@ dependencies = [ "version_check", ] -[[package]] -name = "smallvec" -version = "0.6.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b97fcaeba89edba30f044a10c6a3cc39df9c3f17d7cd829dd1446cab35f890e0" -dependencies = [ - "maybe-uninit", -] - [[package]] name = "smallvec" version = "1.11.0" @@ -13930,7 +13917,7 @@ dependencies = [ "parity-scale-codec", "parking_lot 0.12.1", "rand 0.8.5", - "smallvec 1.11.0", + "smallvec", "sp-core", "sp-externalities", "sp-panic-handler", @@ -14101,7 +14088,7 @@ dependencies = [ "parity-scale-codec", "scale-info", "serde", - "smallvec 1.11.0", + "smallvec", "sp-arithmetic", "sp-core", "sp-debug-derive", @@ -14252,7 +14239,7 @@ version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "290d54ea6f91c969195bdbcd7442c8c2a2ba87da8bf60a7ee86a235d4bc1e125" dependencies = [ - "strum_macros 0.25.2", + "strum_macros 0.25.3", ] [[package]] @@ -14270,9 +14257,9 @@ dependencies = [ [[package]] name = "strum_macros" -version = "0.25.2" +version = "0.25.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad8d03b598d3d0fff69bf533ee3ef19b8eeb342729596df84bcc7e1f96ec4059" +checksum = "23dc1fa9ac9c169a78ba62f0b841814b7abae11bdd047b9c58f893439e309ea0" dependencies = [ "heck", "proc-macro2", @@ -14503,7 +14490,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cb94d2f3cc536af71caac6b6fcebf65860b347e7ce0cc9ebe8f70d3e521054ef" dependencies = [ "cfg-if", - "fastrand 2.0.0", + "fastrand 2.0.1", "redox_syscall 0.3.5", "rustix 0.38.3", "windows-sys 0.48.0", @@ -14696,9 +14683,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.32.0" +version = "1.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17ed6077ed6cd6c74735e21f37eb16dc3935f96878b1fe961074089cc80893f9" +checksum = "4f38200e3ef7995e5ef13baec2f432a6da0aa9ac495b2c0e8f3b7eec2c92d653" dependencies = [ "backtrace", "bytes", @@ -14960,7 +14947,7 @@ dependencies = [ "serde", "serde_json", "sharded-slab", - "smallvec 1.11.0", + "smallvec", "thread_local", "tracing", "tracing-core", @@ -14978,7 +14965,7 @@ dependencies = [ "hashbrown 0.13.2", "log", "rustc-hex", - "smallvec 1.11.0", + "smallvec", ] [[package]] @@ -15017,7 +15004,7 @@ dependencies = [ "ipnet", "lazy_static", "rand 0.8.5", - "smallvec 1.11.0", + "smallvec", "socket2 0.4.9", "thiserror", "tinyvec", @@ -15039,7 +15026,7 @@ dependencies = [ "lru-cache", "parking_lot 0.12.1", "resolv-conf", - "smallvec 1.11.0", + "smallvec", "thiserror", "tokio", "tracing", @@ -15122,7 +15109,7 @@ checksum = "97fee6b57c6a41524a810daee9286c02d7752c4253064d0b05472833a438f675" dependencies = [ "cfg-if", "digest 0.10.7", - "rand 0.7.3", + "rand 0.8.5", "static_assertions", ] @@ -16071,7 +16058,7 @@ dependencies = [ "scale-info", "serde", "serde_derive", - "smallvec 1.11.0", + "smallvec", "sp-api", "sp-authority-discovery", "sp-block-builder", @@ -16104,7 +16091,7 @@ dependencies = [ "frame-support", "polkadot-primitives", "polkadot-runtime-common", - "smallvec 1.11.0", + "smallvec", "sp-core", "sp-runtime", "sp-weights", @@ -16575,7 +16562,7 @@ dependencies = [ "polkadot-primitives", "polkadot-runtime-parachains", "scale-info", - "smallvec 1.11.0", + "smallvec", "sp-core", "sp-io", "sp-runtime", diff --git a/Cargo.toml b/Cargo.toml index 570b9d2940..810f1947d6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -277,6 +277,7 @@ pallet-xvm = { path = "./pallets/xvm", default-features = false } pallet-ethereum-checked = { path = "./pallets/ethereum-checked", default-features = false } pallet-dynamic-evm-base-fee = { path = "./pallets/dynamic-evm-base-fee", default-features = false } pallet-unified-accounts = { path = "./pallets/unified-accounts", default-features = false } +astar-xcm-benchmarks = { path = "./pallets/astar-xcm-benchmarks", default-features = false } astar-primitives = { path = "./primitives", default-features = false } diff --git a/pallets/astar-xcm-benchmarks/Cargo.toml b/pallets/astar-xcm-benchmarks/Cargo.toml new file mode 100644 index 0000000000..de5c7a3a63 --- /dev/null +++ b/pallets/astar-xcm-benchmarks/Cargo.toml @@ -0,0 +1,73 @@ +[package] +name = "astar-xcm-benchmarks" +version = "0.1.0" +authors.workspace = true +edition.workspace = true +homepage.workspace = true +repository.workspace = true + +[dependencies] +log = { workspace = true } +serde = { workspace = true, optional = true } + +# Substrate +frame-support = { workspace = true, default-features = false } +frame-system = { workspace = true } +parity-scale-codec = { workspace = true } +scale-info = { workspace = true } +sp-std = { workspace = true } + +# Polkadot / XCM +astar-primitives = { workspace = true } +sp-io = { workspace = true } +sp-runtime = { workspace = true } +xcm = { workspace = true } +xcm-builder = { workspace = true } +xcm-executor = { workspace = true } + +# Benchmarks +frame-benchmarking = { workspace = true } + +[dev-dependencies] +pallet-assets = { workspace = true } +pallet-balances = { workspace = true } +pallet-xc-asset-config = { workspace = true } +pallet-xcm = { workspace = true } +paste = { workspace = true } +sp-core = { workspace = true } +sp-tracing = { workspace = true } + +[features] +default = ["std"] +std = [ + "frame-benchmarking/std", + "frame-support/std", + "frame-system/std", + "parity-scale-codec/std", + "sp-std/std", + "xcm-builder/std", + "xcm-executor/std", + "xcm/std", + "sp-io/std", + "sp-runtime/std", + "sp-core/std", + "astar-primitives/std", + "scale-info/std", + "astar-primitives/std", + "pallet-balances/std", + "pallet-assets/std", + "pallet-xc-asset-config/std", +] + +runtime-benchmarks = [ + "xcm-builder/runtime-benchmarks", + "xcm-executor/runtime-benchmarks", + "pallet-xcm/runtime-benchmarks", + "frame-benchmarking/runtime-benchmarks", + "frame-system/runtime-benchmarks", + "frame-support/runtime-benchmarks", + "astar-primitives/runtime-benchmarks", + "sp-runtime/runtime-benchmarks", +] + +try-runtime = ["frame-support/try-runtime"] diff --git a/pallets/astar-xcm-benchmarks/src/fungible/assets/benchmarking.rs b/pallets/astar-xcm-benchmarks/src/fungible/assets/benchmarking.rs new file mode 100644 index 0000000000..76b4c79d92 --- /dev/null +++ b/pallets/astar-xcm-benchmarks/src/fungible/assets/benchmarking.rs @@ -0,0 +1,291 @@ +// This file is part of Astar. + +// Copyright (C) 2019-2023 Stake Technologies Pte.Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later + +// Astar is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Astar is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Astar. If not, see . + +// Copyright (C) Parity Technologies (UK) Ltd. +use super::*; +use crate::{account_and_location, new_executor, AssetTransactorOf, XcmCallOf}; +use frame_benchmarking::v2::*; +use frame_support::traits::fungible::Inspect; +use sp_runtime::traits::Zero; +use sp_std::{prelude::*, vec}; +use xcm::latest::{prelude::*, Weight}; +use xcm_executor::traits::{Convert, TransactAsset}; + +#[benchmarks( + where + < + < + ::TransactAsset + as + Inspect + >::Balance + as + TryInto + >::Error: sp_std::fmt::Debug, + + < ::TransactAsset + as + Inspect + >::Balance : Into +)] +mod benchmarks { + use super::*; + + #[benchmark] + fn withdraw_asset() -> Result<(), BenchmarkError> { + let (sender_account, sender_location) = account_and_location::(1); + let worst_case_holding = T::worst_case_holding(0); + let asset = T::get_multi_asset(); + + >::deposit_asset( + &asset, + &sender_location, + &XcmContext { + origin: Some(sender_location.clone()), + message_hash: [0; 32], + topic: None, + }, + ) + .unwrap(); + // check the assets of origin. + assert!(!T::TransactAsset::balance(&sender_account).is_zero()); + + let mut executor = new_executor::(sender_location); + executor.set_holding(worst_case_holding.into()); + let instruction = Instruction::>::WithdrawAsset(vec![asset.clone()].into()); + let xcm = Xcm(vec![instruction]); + #[block] + { + executor.bench_process(xcm)?; + } + // check one of the assets of origin. + assert!(T::TransactAsset::balance(&sender_account).is_zero()); + assert!(executor + .holding() + .ensure_contains(&vec![asset].into()) + .is_ok()); + Ok(()) + } + + #[benchmark] + fn transfer_asset() -> Result<(), BenchmarkError> { + let (sender_account, sender_location) = account_and_location::(1); + let mut asset = T::get_multi_asset(); + // this xcm doesn't use holding + + let dest_location = T::valid_destination()?; + let dest_account = T::AccountIdConverter::convert(dest_location.clone()).unwrap(); + >::deposit_asset( + &asset, + &sender_location, + &XcmContext { + origin: Some(sender_location.clone()), + message_hash: [0; 32], + topic: None, + }, + ) + .unwrap(); + assert!(T::TransactAsset::balance(&dest_account).is_zero()); + + // reducing some assets for Existential deposit + if let Fungible(x) = asset.fun { + asset.fun = Fungible(x / 10) + }; + + let assets: MultiAssets = vec![asset.clone()].into(); + log::trace!( + target: "xcm::process", + "assets is {:?}",assets.clone()); + + >::transfer_asset( + &asset, + &sender_location, + &dest_location, + &XcmContext { + origin: Some(sender_location.clone()), + message_hash: [0; 32], + topic: None, + }, + ) + .unwrap(); + let mut executor = new_executor::(sender_location); + let instruction = Instruction::TransferAsset { + assets, + beneficiary: dest_location, + }; + let xcm = Xcm(vec![instruction]); + log::trace!( + target: "xcm::process", + "destination balance is {:?}, sender balance is {:?}",T::TransactAsset::balance(&dest_account),T::TransactAsset::balance(&sender_account)); + assert!(!T::TransactAsset::balance(&dest_account).is_zero()); + let previous_balance: u128 = T::TransactAsset::balance(&dest_account).into(); + + #[block] + { + executor.bench_process(xcm)?; + } + + log::trace!( + target: "xcm::process", + "destination balance is {:?}, sender balance is {:?}",T::TransactAsset::balance(&dest_account),T::TransactAsset::balance(&sender_account)); + assert!(T::TransactAsset::balance(&dest_account).into() == 2 * previous_balance); + Ok(()) + } + + #[benchmark] + fn transfer_reserve_asset() -> Result<(), BenchmarkError> { + let (_, sender_location) = account_and_location::(1); + let dest_location = T::valid_destination()?; + let dest_account = T::AccountIdConverter::convert(dest_location.clone()).unwrap(); + + let mut asset = T::get_multi_asset(); + >::deposit_asset( + &asset, + &sender_location, + &XcmContext { + origin: Some(sender_location.clone()), + message_hash: [0; 32], + topic: None, + }, + ) + .unwrap(); + + assert!(T::TransactAsset::balance(&dest_account).is_zero()); + + if let Fungible(x) = asset.fun { + asset.fun = Fungible(x / 10) + }; + + >::transfer_asset( + &asset, + &sender_location, + &dest_location, + &XcmContext { + origin: Some(sender_location.clone()), + message_hash: [0; 32], + topic: None, + }, + ) + .unwrap(); + let assets: MultiAssets = vec![asset].into(); + let mut executor = new_executor::(sender_location); + let instruction = Instruction::TransferReserveAsset { + assets, + dest: dest_location, + xcm: Xcm::new(), + }; + let xcm = Xcm(vec![instruction]); + assert!(!T::TransactAsset::balance(&dest_account).is_zero()); + let previous_balance: u128 = T::TransactAsset::balance(&dest_account).into(); + + #[block] + { + executor.bench_process(xcm)?; + } + + assert!(T::TransactAsset::balance(&dest_account).into() == 2 * previous_balance); + Ok(()) + } + + #[benchmark] + fn receive_teleported_asset() -> Result<(), BenchmarkError> { + // need to add an empty block as it is necessary to have either #[block] or #[extrinsic_call] + #[block] + {} + Err(BenchmarkError::Override(BenchmarkResult::from_weight( + Weight::MAX, + ))) + } + + #[benchmark] + fn deposit_asset() -> Result<(), BenchmarkError> { + let asset = T::get_multi_asset(); + let mut holding = T::worst_case_holding(1); + + // Add our asset to the holding. + holding.push(asset.clone()); + + // our dest must have no balance initially. + let dest_location = T::valid_destination()?; + let dest_account = T::AccountIdConverter::convert(dest_location.clone()).unwrap(); + assert!(T::TransactAsset::balance(&dest_account).is_zero()); + + let mut executor = new_executor::(Default::default()); + executor.set_holding(holding.into()); + let instruction = Instruction::>::DepositAsset { + assets: asset.into(), + beneficiary: dest_location, + }; + let xcm = Xcm(vec![instruction]); + + #[block] + { + executor.bench_process(xcm)?; + } + // dest should have received some asset. + assert!(!T::TransactAsset::balance(&dest_account).is_zero()); + Ok(()) + } + + #[benchmark] + fn deposit_reserve_asset() -> Result<(), BenchmarkError> { + let asset = T::get_multi_asset(); + let mut holding = T::worst_case_holding(1); + + // Add our asset to the holding. + holding.push(asset.clone()); + + // our dest must have no balance initially. + let dest_location = T::valid_destination()?; + let dest_account = T::AccountIdConverter::convert(dest_location.clone()).unwrap(); + assert!(T::TransactAsset::balance(&dest_account).is_zero()); + + let mut executor = new_executor::(Default::default()); + executor.set_holding(holding.into()); + let instruction = Instruction::>::DepositReserveAsset { + assets: asset.into(), + dest: dest_location, + xcm: Xcm::new(), + }; + let xcm = Xcm(vec![instruction]); + + #[block] + { + executor.bench_process(xcm)?; + } + + // dest should have received some asset. + assert!(!T::TransactAsset::balance(&dest_account).is_zero()); + Ok(()) + } + + #[benchmark] + fn initiate_teleport() -> Result<(), BenchmarkError> { + #[block] + {} + Err(BenchmarkError::Override(BenchmarkResult::from_weight( + Weight::MAX, + ))) + } + + impl_benchmark_test_suite!( + Pallet, + crate::fungible::assets::mock::new_test_ext(), + crate::fungible::assets::mock::Test + ); +} diff --git a/pallets/astar-xcm-benchmarks/src/fungible/assets/mock.rs b/pallets/astar-xcm-benchmarks/src/fungible/assets/mock.rs new file mode 100644 index 0000000000..842b320382 --- /dev/null +++ b/pallets/astar-xcm-benchmarks/src/fungible/assets/mock.rs @@ -0,0 +1,304 @@ +// This file is part of Astar. + +// Copyright (C) 2019-2023 Stake Technologies Pte.Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later + +// Astar is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Astar is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Astar. If not, see . + +// Copyright (C) Parity Technologies (UK) Ltd. +//! A mock runtime for XCM benchmarking. + +use crate::{fungible::assets as xcm_assets_benchmark, mock::*}; +use frame_benchmarking::BenchmarkError; +use frame_support::{ + assert_ok, parameter_types, + traits::{tokens::fungible::ItemOf, AsEnsureOriginWithArg, ConstU32, Everything, Nothing}, + weights::Weight, +}; +use frame_system::{EnsureRoot, EnsureSigned}; +use parity_scale_codec::Compact; +use sp_core::{ConstU64, H256}; +use sp_runtime::{ + testing::Header, + traits::{BlakeTwo256, IdentityLookup}, +}; +use sp_std::borrow::Borrow; +use xcm::latest::prelude::*; +use xcm_builder::{AllowUnpaidExecutionFrom, ConvertedConcreteId, MintLocation}; +use xcm_executor::traits::{Convert, JustTry}; + +type Block = frame_system::mocking::MockBlock; +type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic; + +// For testing the pallet, we construct a mock runtime. +frame_support::construct_runtime!( + pub struct Test + where + Block = Block, + NodeBlock = Block, + UncheckedExtrinsic = UncheckedExtrinsic, + { + System: frame_system, + Balances: pallet_balances, + XcmAssetsBenchmark: xcm_assets_benchmark, + Assets: pallet_assets, + XcAssetConfig: pallet_xc_asset_config, + } +); + +parameter_types! { + pub const BlockHashCount: u64 = 250; + pub BlockWeights: frame_system::limits::BlockWeights = + frame_system::limits::BlockWeights::simple_max(Weight::from_parts(1024, u64::MAX)); +} +impl frame_system::Config for Test { + type BaseCallFilter = Everything; + type BlockWeights = (); + type BlockLength = (); + type DbWeight = (); + type RuntimeOrigin = RuntimeOrigin; + type Hash = H256; + type Index = u64; + type Header = Header; + type BlockNumber = u64; + type RuntimeCall = RuntimeCall; + type Hashing = BlakeTwo256; + type AccountId = u64; + type Lookup = IdentityLookup; + type RuntimeEvent = RuntimeEvent; + type BlockHashCount = BlockHashCount; + type Version = (); + type PalletInfo = PalletInfo; + type AccountData = pallet_balances::AccountData; + type OnNewAccount = (); + type OnKilledAccount = (); + type SystemWeightInfo = (); + type SS58Prefix = (); + type OnSetCode = (); + type MaxConsumers = ConstU32<16>; +} + +parameter_types! { + pub const ExistentialDeposit: u64 = 7; +} + +impl pallet_balances::Config for Test { + type MaxLocks = (); + type MaxReserves = (); + type ReserveIdentifier = [u8; 8]; + type Balance = u64; + type DustRemoval = (); + type RuntimeEvent = RuntimeEvent; + type ExistentialDeposit = ExistentialDeposit; + type AccountStore = System; + type WeightInfo = (); + type FreezeIdentifier = (); + type MaxHolds = ConstU32<0>; + type MaxFreezes = ConstU32<0>; + type HoldIdentifier = (); +} + +parameter_types! { + pub const AssetDeposit: u64 = 100 * ExistentialDeposit::get(); + pub const ApprovalDeposit: u64 = 1 * ExistentialDeposit::get(); + pub const StringLimit: u32 = 50; + pub const MetadataDepositBase: u64 = 10 * ExistentialDeposit::get(); + pub const MetadataDepositPerByte: u64 = 1 * ExistentialDeposit::get(); + pub const AssetAccountDeposit: u64 = 1 * ExistentialDeposit::get(); + pub const AssetsStringLimit: u32 = 50; + +} + +impl pallet_xc_asset_config::Config for Test { + type RuntimeEvent = RuntimeEvent; + type AssetId = u64; + type ManagerOrigin = EnsureRoot; + type WeightInfo = (); +} + +impl pallet_assets::Config for Test { + type RuntimeEvent = RuntimeEvent; + type Balance = u64; + type AssetId = u64; + type Currency = Balances; + type CreateOrigin = AsEnsureOriginWithArg>; + type ForceOrigin = EnsureRoot; + type AssetDeposit = AssetDeposit; + type MetadataDepositBase = MetadataDepositBase; + type MetadataDepositPerByte = MetadataDepositPerByte; + type AssetAccountDeposit = AssetAccountDeposit; + type ApprovalDeposit = ExistentialDeposit; + type StringLimit = AssetsStringLimit; + type Freezer = (); + type Extra = (); + type WeightInfo = (); + type RemoveItemsLimit = ConstU32<1000>; + type AssetIdParameter = Compact; + type CallbackHandle = (); + #[cfg(feature = "runtime-benchmarks")] + type BenchmarkHelper = AssetsBenchmarkHelper; +} + +pub struct AssetsBenchmarkHelper; +impl> pallet_assets::BenchmarkHelper + for AssetsBenchmarkHelper +{ + fn create_asset_id_parameter(id: u32) -> AssetIdParameter { + u64::from(id).into() + } +} + +parameter_types! { + pub const DummyCheckingAccount : u64 = 0; +} +// Use fungible transactor as the asset transactor. +pub type AssetTransactor = xcm_builder::FungiblesAdapter< + Assets, + ConvertedConcreteId, + AccountIdConverter, + u64, + xcm_builder::NoChecking, + DummyCheckingAccount, +>; + +pub struct AssetLocationIdConverter; +impl Convert for AssetLocationIdConverter { + fn convert_ref(location: impl Borrow) -> Result { + if let X1(GeneralIndex(i)) = location.borrow().clone().interior { + Ok(>::try_into(i).map_err(|_| ())?) + } else { + Err(()) + } + } + + fn reverse_ref(id: impl Borrow) -> Result { + Ok(Junction::GeneralIndex(id.borrow().clone().into()).into()) + } +} + +parameter_types! { + /// Maximum number of instructions in a single XCM fragment. A sanity check against weight + /// calculations getting too crazy. + pub const MaxInstructions: u32 = 100; + pub const MaxAssetsIntoHolding: u32 = 64; +} + +pub struct XcmConfig; +impl xcm_executor::Config for XcmConfig { + type RuntimeCall = RuntimeCall; + type XcmSender = DevNull; + type AssetTransactor = AssetTransactor; + type OriginConverter = (); + type IsReserve = (); + type IsTeleporter = TrustedTeleporters; + type UniversalLocation = UniversalLocation; + type Barrier = AllowUnpaidExecutionFrom; + type Weigher = xcm_builder::FixedWeightBounds; + type Trader = xcm_builder::FixedRateOfFungible; + type ResponseHandler = DevNull; + type AssetTrap = (); + type AssetLocker = (); + type AssetExchanger = (); + type AssetClaims = (); + type SubscriptionService = (); + type PalletInstancesInfo = AllPalletsWithSystem; + type MaxAssetsIntoHolding = MaxAssetsIntoHolding; + type FeeManager = (); + type MessageExporter = (); + type UniversalAliases = Nothing; + type CallDispatcher = RuntimeCall; + type SafeCallFilter = Everything; +} + +impl crate::Config for Test { + type XcmConfig = XcmConfig; + type AccountIdConverter = AccountIdConverter; + fn valid_destination() -> Result { + let valid_destination: MultiLocation = X1(AccountId32 { + network: None, + id: [0u8; 32], + }) + .into(); + + Ok(valid_destination) + } + fn worst_case_holding(depositable_count: u32) -> MultiAssets { + crate::mock_worst_case_holding( + depositable_count, + ::MaxAssetsIntoHolding::get(), + ) + } +} +pub type TrustedTeleporters = (xcm_builder::Case,); + +parameter_types! { + pub const CheckingAccount: Option<(u64, MintLocation)> = Some((100, MintLocation::Local)); + pub const ChildTeleporter: MultiLocation = Parachain(1000).into_location(); + pub const TrustedTeleporter: Option<(MultiLocation, MultiAsset)> = Some(( + ChildTeleporter::get(), + MultiAsset { id: Concrete(Here.into_location()), fun: Fungible(100) }, + )); + pub const TeleportConcreteFungible: (MultiAssetFilter, MultiLocation) = + (Wild(AllOf { fun: WildFungible, id: Concrete(Here.into_location()) }), ChildTeleporter::get()); + pub const ReserveConcreteFungible: (MultiAssetFilter, MultiLocation) = + (Wild(AllOf { fun: WildFungible, id: Concrete(Here.into_location()) }), ChildTeleporter::get()); + pub const NoCheckingAccount: Option<(::AccountId, MintLocation)> = None; + pub const NoTeleporter: Option<(xcm::latest::MultiLocation, xcm::latest::MultiAsset)> = None; +} + +impl xcm_assets_benchmark::Config for Test { + type TransactAsset = ItemOf, u64>; + type CheckedAccount = NoCheckingAccount; + type TrustedTeleporter = NoTeleporter; + + fn get_multi_asset() -> MultiAsset { + // create an asset and make it sufficient + assert_ok!(pallet_assets::Pallet::::force_create( + RuntimeOrigin::root(), + parity_scale_codec::Compact(1), + 0_u64, + true, + 1 + )); + let location = MultiLocation { + parents: 0, + interior: X1(GeneralIndex(1)), + }; + // convert mapping for asset id + assert_ok!( + pallet_xc_asset_config::Pallet::::register_asset_location( + RuntimeOrigin::root(), + Box::new(location.clone().into_versioned()), + 1 + ) + ); + + MultiAsset { + id: Concrete(location), + fun: Fungible(100_000_000_000u128), + } + } +} + +#[cfg(feature = "runtime-benchmarks")] +pub fn new_test_ext() -> sp_io::TestExternalities { + use sp_runtime::BuildStorage; + let t = GenesisConfig { + ..Default::default() + } + .build_storage() + .unwrap(); + sp_tracing::try_init_simple(); + t.into() +} diff --git a/pallets/astar-xcm-benchmarks/src/fungible/assets/mod.rs b/pallets/astar-xcm-benchmarks/src/fungible/assets/mod.rs new file mode 100644 index 0000000000..1fa633681e --- /dev/null +++ b/pallets/astar-xcm-benchmarks/src/fungible/assets/mod.rs @@ -0,0 +1,51 @@ +// This file is part of Astar. + +// Copyright (C) 2019-2023 Stake Technologies Pte.Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later + +// Astar is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Astar is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Astar. If not, see . + +// Copyright (C) Parity Technologies (UK) Ltd. +// Benchmarking for the `AssetTransactor` trait via `Fungible`. + +pub use pallet::*; + +#[cfg(feature = "runtime-benchmarks")] +pub mod benchmarking; +#[cfg(test)] +mod mock; + +#[frame_support::pallet] +pub mod pallet { + use frame_support::pallet_prelude::Get; + #[pallet::config] + pub trait Config: frame_system::Config + crate::Config { + /// The type of `fungible` that is being used under the hood. + /// + /// This is useful for testing and checking. + type TransactAsset: frame_support::traits::fungible::Mutate; + + /// The account used to check assets being teleported. + type CheckedAccount: Get>; + + /// A trusted location which we allow teleports from, and the asset we allow to teleport. + type TrustedTeleporter: Get>; + + /// Give me a fungible asset that your asset transactor is going to accept. + fn get_multi_asset() -> xcm::latest::MultiAsset; + } + + #[pallet::pallet] + pub struct Pallet(_); +} diff --git a/pallets/astar-xcm-benchmarks/src/fungible/balances/benchmarking.rs b/pallets/astar-xcm-benchmarks/src/fungible/balances/benchmarking.rs new file mode 100644 index 0000000000..464a0169e3 --- /dev/null +++ b/pallets/astar-xcm-benchmarks/src/fungible/balances/benchmarking.rs @@ -0,0 +1,242 @@ +// This file is part of Astar. + +// Copyright (C) 2019-2023 Stake Technologies Pte.Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later + +// Astar is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Astar is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Astar. If not, see . + +// Copyright (C) Parity Technologies (UK) Ltd. +use super::*; +use crate::{account_and_location, new_executor, AssetTransactorOf, XcmCallOf}; +use frame_benchmarking::v2::*; +use frame_support::traits::fungible::Inspect; +use sp_runtime::traits::Zero; +use sp_std::{prelude::*, vec}; +use xcm::latest::{prelude::*, Weight}; +use xcm_executor::traits::{Convert, TransactAsset}; + +#[benchmarks( + where + < + < + ::TransactAsset + as + Inspect + >::Balance + as + TryInto + >::Error: sp_std::fmt::Debug, +)] +mod benchmarks { + use super::*; + + #[benchmark] + fn withdraw_asset() -> Result<(), BenchmarkError> { + let (sender_account, sender_location) = account_and_location::(1); + let worst_case_holding = T::worst_case_holding(0); + let asset = T::get_multi_asset(); + + >::deposit_asset( + &asset, + &sender_location, + &XcmContext { + origin: Some(sender_location.clone()), + message_hash: [0; 32], + topic: None, + }, + ) + .unwrap(); + // check the assets of origin. + assert!(!T::TransactAsset::balance(&sender_account).is_zero()); + + let mut executor = new_executor::(sender_location); + executor.set_holding(worst_case_holding.into()); + let instruction = Instruction::>::WithdrawAsset(vec![asset.clone()].into()); + let xcm = Xcm(vec![instruction]); + #[block] + { + executor.bench_process(xcm)?; + } + // check one of the assets of origin. + assert!(T::TransactAsset::balance(&sender_account).is_zero()); + assert!(executor + .holding() + .ensure_contains(&vec![asset].into()) + .is_ok()); + Ok(()) + } + + #[benchmark] + fn transfer_asset() -> Result<(), BenchmarkError> { + let (sender_account, sender_location) = account_and_location::(1); + let asset = T::get_multi_asset(); + let assets: MultiAssets = vec![asset.clone()].into(); + // this xcm doesn't use holding + + let dest_location = T::valid_destination()?; + let dest_account = T::AccountIdConverter::convert(dest_location.clone()).unwrap(); + + >::deposit_asset( + &asset, + &sender_location, + &XcmContext { + origin: Some(sender_location.clone()), + message_hash: [0; 32], + topic: None, + }, + ) + .unwrap(); + assert!(T::TransactAsset::balance(&dest_account).is_zero()); + + let mut executor = new_executor::(sender_location); + let instruction = Instruction::TransferAsset { + assets, + beneficiary: dest_location, + }; + let xcm = Xcm(vec![instruction]); + + #[block] + { + executor.bench_process(xcm)?; + } + + assert!(T::TransactAsset::balance(&sender_account).is_zero()); + assert!(!T::TransactAsset::balance(&dest_account).is_zero()); + Ok(()) + } + + #[benchmark] + fn transfer_reserve_asset() -> Result<(), BenchmarkError> { + let (sender_account, sender_location) = account_and_location::(1); + let dest_location = T::valid_destination()?; + let dest_account = T::AccountIdConverter::convert(dest_location.clone()).unwrap(); + + let asset = T::get_multi_asset(); + >::deposit_asset( + &asset, + &sender_location, + &XcmContext { + origin: Some(sender_location.clone()), + message_hash: [0; 32], + topic: None, + }, + ) + .unwrap(); + let assets: MultiAssets = vec![asset].into(); + assert!(T::TransactAsset::balance(&dest_account).is_zero()); + + let mut executor = new_executor::(sender_location); + let instruction = Instruction::TransferReserveAsset { + assets, + dest: dest_location, + xcm: Xcm::new(), + }; + let xcm = Xcm(vec![instruction]); + + #[block] + { + executor.bench_process(xcm)?; + } + + assert!(T::TransactAsset::balance(&sender_account).is_zero()); + assert!(!T::TransactAsset::balance(&dest_account).is_zero()); + Ok(()) + } + + #[benchmark] + fn receive_teleported_asset() -> Result<(), BenchmarkError> { + // need to add an empty block as it is necessary to have either #[block] or #[extrinsic_call] + #[block] + {} + Err(BenchmarkError::Override(BenchmarkResult::from_weight( + Weight::MAX, + ))) + } + + #[benchmark] + fn deposit_asset() -> Result<(), BenchmarkError> { + let asset = T::get_multi_asset(); + let mut holding = T::worst_case_holding(1); + + // Add our asset to the holding. + holding.push(asset.clone()); + + // our dest must have no balance initially. + let dest_location = T::valid_destination()?; + let dest_account = T::AccountIdConverter::convert(dest_location.clone()).unwrap(); + assert!(T::TransactAsset::balance(&dest_account).is_zero()); + + let mut executor = new_executor::(Default::default()); + executor.set_holding(holding.into()); + let instruction = Instruction::>::DepositAsset { + assets: asset.into(), + beneficiary: dest_location, + }; + let xcm = Xcm(vec![instruction]); + + #[block] + { + executor.bench_process(xcm)?; + } + // dest should have received some asset. + assert!(!T::TransactAsset::balance(&dest_account).is_zero()); + Ok(()) + } + + #[benchmark] + fn deposit_reserve_asset() -> Result<(), BenchmarkError> { + let asset = T::get_multi_asset(); + let mut holding = T::worst_case_holding(1); + + // Add our asset to the holding. + holding.push(asset.clone()); + + // our dest must have no balance initially. + let dest_location = T::valid_destination()?; + let dest_account = T::AccountIdConverter::convert(dest_location.clone()).unwrap(); + assert!(T::TransactAsset::balance(&dest_account).is_zero()); + + let mut executor = new_executor::(Default::default()); + executor.set_holding(holding.into()); + let instruction = Instruction::>::DepositReserveAsset { + assets: asset.into(), + dest: dest_location, + xcm: Xcm::new(), + }; + let xcm = Xcm(vec![instruction]); + + #[block] + { + executor.bench_process(xcm)?; + } + + // dest should have received some asset. + assert!(!T::TransactAsset::balance(&dest_account).is_zero()); + Ok(()) + } + + #[benchmark] + fn initiate_teleport() -> Result<(), BenchmarkError> { + #[block] + {} + Err(BenchmarkError::Override(BenchmarkResult::from_weight( + Weight::MAX, + ))) + } + impl_benchmark_test_suite!( + Pallet, + crate::fungible::balances::mock::new_test_ext(), + crate::fungible::balances::mock::Test + ); +} diff --git a/pallets/astar-xcm-benchmarks/src/fungible/balances/mock.rs b/pallets/astar-xcm-benchmarks/src/fungible/balances/mock.rs new file mode 100644 index 0000000000..e8ed442036 --- /dev/null +++ b/pallets/astar-xcm-benchmarks/src/fungible/balances/mock.rs @@ -0,0 +1,229 @@ +// This file is part of Astar. + +// Copyright (C) 2019-2023 Stake Technologies Pte.Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later + +// Astar is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Astar is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Astar. If not, see . + +// Copyright (C) Parity Technologies (UK) Ltd. +//! A mock runtime for XCM benchmarking. + +use crate::{fungible::balances as xcm_balances_benchmark, mock::*}; +use frame_benchmarking::BenchmarkError; +use frame_support::{ + parameter_types, + traits::{ConstU32, Everything, Nothing}, + weights::Weight, +}; +use sp_core::H256; +use sp_runtime::{ + testing::Header, + traits::{BlakeTwo256, IdentityLookup}, +}; +use xcm::latest::prelude::*; +use xcm_builder::{AllowUnpaidExecutionFrom, MintLocation}; + +type Block = frame_system::mocking::MockBlock; +type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic; + +// For testing the pallet, we construct a mock runtime. +frame_support::construct_runtime!( + pub struct Test + where + Block = Block, + NodeBlock = Block, + UncheckedExtrinsic = UncheckedExtrinsic, + { + System: frame_system, + Balances: pallet_balances, + XcmBalancesBenchmark: xcm_balances_benchmark, + } +); + +parameter_types! { + pub const BlockHashCount: u64 = 250; + pub BlockWeights: frame_system::limits::BlockWeights = + frame_system::limits::BlockWeights::simple_max(Weight::from_parts(1024, u64::MAX)); +} +impl frame_system::Config for Test { + type BaseCallFilter = Everything; + type BlockWeights = (); + type BlockLength = (); + type DbWeight = (); + type RuntimeOrigin = RuntimeOrigin; + type Hash = H256; + type Index = u64; + type Header = Header; + type BlockNumber = u64; + type RuntimeCall = RuntimeCall; + type Hashing = BlakeTwo256; + type AccountId = u64; + type Lookup = IdentityLookup; + type RuntimeEvent = RuntimeEvent; + type BlockHashCount = BlockHashCount; + type Version = (); + type PalletInfo = PalletInfo; + type AccountData = pallet_balances::AccountData; + type OnNewAccount = (); + type OnKilledAccount = (); + type SystemWeightInfo = (); + type SS58Prefix = (); + type OnSetCode = (); + type MaxConsumers = ConstU32<16>; +} + +parameter_types! { + pub const ExistentialDeposit: u64 = 7; +} + +impl pallet_balances::Config for Test { + type MaxLocks = (); + type MaxReserves = (); + type ReserveIdentifier = [u8; 8]; + type Balance = u64; + type DustRemoval = (); + type RuntimeEvent = RuntimeEvent; + type ExistentialDeposit = ExistentialDeposit; + type AccountStore = System; + type WeightInfo = (); + type FreezeIdentifier = (); + type MaxHolds = ConstU32<0>; + type MaxFreezes = ConstU32<0>; + type HoldIdentifier = (); +} + +parameter_types! { + pub const AssetDeposit: u64 = 100 * ExistentialDeposit::get(); + pub const ApprovalDeposit: u64 = 1 * ExistentialDeposit::get(); + pub const StringLimit: u32 = 50; + pub const MetadataDepositBase: u64 = 10 * ExistentialDeposit::get(); + pub const MetadataDepositPerByte: u64 = 1 * ExistentialDeposit::get(); +} + +pub struct MatchAnyFungible; +impl xcm_executor::traits::MatchesFungible for MatchAnyFungible { + fn matches_fungible(m: &MultiAsset) -> Option { + use sp_runtime::traits::SaturatedConversion; + match m { + MultiAsset { + fun: Fungible(amount), + .. + } => Some((*amount).saturated_into::()), + _ => None, + } + } +} + +// Use balances as the asset transactor. +pub type AssetTransactor = xcm_builder::CurrencyAdapter< + Balances, + MatchAnyFungible, + AccountIdConverter, + u64, + CheckingAccount, +>; + +parameter_types! { + pub const MaxInstructions: u32 = 100; + pub const MaxAssetsIntoHolding: u32 = 64; +} + +pub struct XcmConfig; +impl xcm_executor::Config for XcmConfig { + type RuntimeCall = RuntimeCall; + type XcmSender = DevNull; + type AssetTransactor = AssetTransactor; + type OriginConverter = (); + type IsReserve = (); + type IsTeleporter = TrustedTeleporters; + type UniversalLocation = UniversalLocation; + type Barrier = AllowUnpaidExecutionFrom; + type Weigher = xcm_builder::FixedWeightBounds; + type Trader = xcm_builder::FixedRateOfFungible; + type ResponseHandler = DevNull; + type AssetTrap = (); + type AssetLocker = (); + type AssetExchanger = (); + type AssetClaims = (); + type SubscriptionService = (); + type PalletInstancesInfo = AllPalletsWithSystem; + type MaxAssetsIntoHolding = MaxAssetsIntoHolding; + type FeeManager = (); + type MessageExporter = (); + type UniversalAliases = Nothing; + type CallDispatcher = RuntimeCall; + type SafeCallFilter = Everything; +} + +impl crate::Config for Test { + type XcmConfig = XcmConfig; + type AccountIdConverter = AccountIdConverter; + fn valid_destination() -> Result { + let valid_destination: MultiLocation = X1(AccountId32 { + network: None, + id: [0u8; 32], + }) + .into(); + + Ok(valid_destination) + } + fn worst_case_holding(depositable_count: u32) -> MultiAssets { + crate::mock_worst_case_holding( + depositable_count, + ::MaxAssetsIntoHolding::get(), + ) + } +} + +pub type TrustedTeleporters = (xcm_builder::Case,); + +parameter_types! { + pub const CheckingAccount: Option<(u64, MintLocation)> = Some((100, MintLocation::Local)); + pub const ChildTeleporter: MultiLocation = Parachain(1000).into_location(); + pub const TrustedTeleporter: Option<(MultiLocation, MultiAsset)> = Some(( + ChildTeleporter::get(), + MultiAsset { id: Concrete(Here.into_location()), fun: Fungible(100) }, + )); + pub const TeleportConcreteFungible: (MultiAssetFilter, MultiLocation) = + (Wild(AllOf { fun: WildFungible, id: Concrete(Here.into_location()) }), ChildTeleporter::get()); + pub const ReserveConcreteFungible: (MultiAssetFilter, MultiLocation) = + (Wild(AllOf { fun: WildFungible, id: Concrete(Here.into_location()) }), ChildTeleporter::get()); +} + +impl xcm_balances_benchmark::Config for Test { + type TransactAsset = Balances; + type CheckedAccount = CheckingAccount; + type TrustedTeleporter = TrustedTeleporter; + + fn get_multi_asset() -> MultiAsset { + let amount = + >::minimum_balance() as u128; + MultiAsset { + id: Concrete(Here.into()), + fun: Fungible(amount), + } + } +} + +#[cfg(feature = "runtime-benchmarks")] +pub fn new_test_ext() -> sp_io::TestExternalities { + use sp_runtime::BuildStorage; + let t = GenesisConfig { + ..Default::default() + } + .build_storage() + .unwrap(); + sp_tracing::try_init_simple(); + t.into() +} diff --git a/pallets/astar-xcm-benchmarks/src/fungible/balances/mod.rs b/pallets/astar-xcm-benchmarks/src/fungible/balances/mod.rs new file mode 100644 index 0000000000..1fa633681e --- /dev/null +++ b/pallets/astar-xcm-benchmarks/src/fungible/balances/mod.rs @@ -0,0 +1,51 @@ +// This file is part of Astar. + +// Copyright (C) 2019-2023 Stake Technologies Pte.Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later + +// Astar is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Astar is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Astar. If not, see . + +// Copyright (C) Parity Technologies (UK) Ltd. +// Benchmarking for the `AssetTransactor` trait via `Fungible`. + +pub use pallet::*; + +#[cfg(feature = "runtime-benchmarks")] +pub mod benchmarking; +#[cfg(test)] +mod mock; + +#[frame_support::pallet] +pub mod pallet { + use frame_support::pallet_prelude::Get; + #[pallet::config] + pub trait Config: frame_system::Config + crate::Config { + /// The type of `fungible` that is being used under the hood. + /// + /// This is useful for testing and checking. + type TransactAsset: frame_support::traits::fungible::Mutate; + + /// The account used to check assets being teleported. + type CheckedAccount: Get>; + + /// A trusted location which we allow teleports from, and the asset we allow to teleport. + type TrustedTeleporter: Get>; + + /// Give me a fungible asset that your asset transactor is going to accept. + fn get_multi_asset() -> xcm::latest::MultiAsset; + } + + #[pallet::pallet] + pub struct Pallet(_); +} diff --git a/pallets/astar-xcm-benchmarks/src/fungible/mod.rs b/pallets/astar-xcm-benchmarks/src/fungible/mod.rs new file mode 100644 index 0000000000..629e2b80e3 --- /dev/null +++ b/pallets/astar-xcm-benchmarks/src/fungible/mod.rs @@ -0,0 +1,22 @@ +// This file is part of Astar. + +// Copyright (C) 2019-2023 Stake Technologies Pte.Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later + +// Astar is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Astar is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Astar. If not, see . + +// Copyright (C) Parity Technologies (UK) Ltd. + +pub mod assets; +pub mod balances; diff --git a/pallets/astar-xcm-benchmarks/src/generic/benchmarking.rs b/pallets/astar-xcm-benchmarks/src/generic/benchmarking.rs new file mode 100644 index 0000000000..0fe0a6c4d5 --- /dev/null +++ b/pallets/astar-xcm-benchmarks/src/generic/benchmarking.rs @@ -0,0 +1,692 @@ +// This file is part of Astar. + +// Copyright (C) 2019-2023 Stake Technologies Pte.Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later + +// Astar is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Astar is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Astar. If not, see . + +// Copyright (C) Parity Technologies (UK) Ltd. + +use super::*; +use crate::{new_executor, XcmCallOf}; +use frame_benchmarking::v2::*; +use frame_support::dispatch::GetDispatchInfo; +use parity_scale_codec::Encode; +use sp_std::vec; +use xcm::{ + latest::{prelude::*, MaxDispatchErrorLen, MaybeErrorCode, Weight}, + DoubleEncoded, +}; +use xcm_executor::{ExecutorError, FeesMode}; + +#[benchmarks] +mod benchmarks { + use super::*; + + #[benchmark] + fn report_holding() -> Result<(), BenchmarkError> { + let holding = T::worst_case_holding(0); + + let mut executor = new_executor::(Default::default()); + executor.set_holding(holding.clone().into()); + + let instruction = Instruction::>::ReportHolding { + response_info: QueryResponseInfo { + destination: T::valid_destination()?, + query_id: Default::default(), + max_weight: Weight::MAX, + }, + // Worst case is looking through all holdings for every asset explicitly. + assets: Definite(holding), + }; + let xcm = Xcm(vec![instruction]); + + #[block] + { + executor.bench_process(xcm)?; + } + // The completion of execution above is enough to validate this is completed. + Ok(()) + } + + #[benchmark] + fn buy_execution() -> Result<(), BenchmarkError> { + let holding = T::worst_case_holding(0).into(); + + let mut executor = new_executor::(Default::default()); + executor.set_holding(holding); + + let fee_asset = Concrete(Here.into()); + + let instruction = Instruction::>::BuyExecution { + fees: (fee_asset, 100_000_000_000u128).into(), // should be something inside of holding + weight_limit: WeightLimit::Limited(Weight::from_parts(1u64, 64 * 1024)), + }; + + let xcm = Xcm(vec![instruction]); + + #[block] + { + executor.bench_process(xcm)?; + } + Ok(()) + } + + #[benchmark] + fn query_response() -> Result<(), BenchmarkError> { + let mut executor = new_executor::(Default::default()); + let (query_id, response) = T::worst_case_response(); + let max_weight = Weight::MAX; + let querier: Option = Some(Here.into()); + let instruction = Instruction::QueryResponse { + query_id, + response, + max_weight, + querier, + }; + let xcm = Xcm(vec![instruction]); + + #[block] + { + executor.bench_process(xcm)?; + } + Ok(()) + } + + // We don't care about the call itself, since that is accounted for in the weight parameter + // and included in the final weight calculation. So this is just the overhead of submitting + // a noop call. + #[benchmark] + fn transact() -> Result<(), BenchmarkError> { + let (origin, noop_call) = T::transact_origin_and_runtime_call()?; + let mut executor = new_executor::(origin); + let double_encoded_noop_call: DoubleEncoded<_> = noop_call.encode().into(); + + let instruction = Instruction::Transact { + origin_kind: OriginKind::SovereignAccount, + require_weight_at_most: noop_call.get_dispatch_info().weight, + call: double_encoded_noop_call, + }; + let xcm = Xcm(vec![instruction]); + + #[block] + { + executor.bench_process(xcm)?; + } + // The assert above is enough to show this XCM succeeded + Ok(()) + } + + #[benchmark] + fn refund_surplus() -> Result<(), BenchmarkError> { + let holding = T::worst_case_holding(0).into(); + let mut executor = new_executor::(Default::default()); + executor.set_holding(holding); + executor.set_total_surplus(Weight::from_parts(1337, 1337)); + executor.set_total_refunded(Weight::zero()); + + let instruction = Instruction::>::RefundSurplus; + let xcm = Xcm(vec![instruction]); + + #[block] + { + executor.bench_process(xcm)?; + } + + assert_eq!(executor.total_surplus(), &Weight::from_parts(1337, 1337)); + assert_eq!(executor.total_refunded(), &Weight::from_parts(1337, 1337)); + Ok(()) + } + + #[benchmark] + fn set_error_handler() -> Result<(), BenchmarkError> { + let mut executor = new_executor::(Default::default()); + let instruction = Instruction::>::SetErrorHandler(Xcm(vec![])); + let xcm = Xcm(vec![instruction]); + + #[block] + { + executor.bench_process(xcm)?; + } + assert_eq!(executor.error_handler(), &Xcm(vec![])); + Ok(()) + } + + #[benchmark] + fn set_appendix() -> Result<(), BenchmarkError> { + let mut executor = new_executor::(Default::default()); + let appendix = Xcm(vec![]); + let instruction = Instruction::>::SetAppendix(appendix); + let xcm = Xcm(vec![instruction]); + #[block] + { + executor.bench_process(xcm)?; + } + assert_eq!(executor.appendix(), &Xcm(vec![])); + Ok(()) + } + + #[benchmark] + fn clear_error() -> Result<(), BenchmarkError> { + let mut executor = new_executor::(Default::default()); + executor.set_error(Some((5u32, XcmError::Overflow))); + let instruction = Instruction::>::ClearError; + let xcm = Xcm(vec![instruction]); + #[block] + { + executor.bench_process(xcm)?; + } + assert!(executor.error().is_none()); + Ok(()) + } + + #[benchmark] + fn descend_origin() -> Result<(), BenchmarkError> { + let mut executor = new_executor::(Default::default()); + let who = X2(OnlyChild, OnlyChild); + let instruction = Instruction::DescendOrigin(who.clone()); + let xcm = Xcm(vec![instruction]); + #[block] + { + executor.bench_process(xcm)?; + } + assert_eq!( + executor.origin(), + &Some(MultiLocation { + parents: 0, + interior: who, + }), + ); + Ok(()) + } + + #[benchmark] + fn clear_origin() -> Result<(), BenchmarkError> { + let mut executor = new_executor::(Default::default()); + let instruction = Instruction::ClearOrigin; + let xcm = Xcm(vec![instruction]); + #[block] + { + executor.bench_process(xcm)?; + } + assert_eq!(executor.origin(), &None); + Ok(()) + } + + #[benchmark] + fn report_error() -> Result<(), BenchmarkError> { + let mut executor = new_executor::(Default::default()); + executor.set_error(Some((0u32, XcmError::Unimplemented))); + let query_id = Default::default(); + let destination = T::valid_destination().map_err(|_| BenchmarkError::Skip)?; + let max_weight = Default::default(); + + let instruction = Instruction::ReportError(QueryResponseInfo { + query_id, + destination, + max_weight, + }); + let xcm = Xcm(vec![instruction]); + #[block] + { + executor.bench_process(xcm)?; + } + // the execution succeeding is all we need to verify this xcm was successful + Ok(()) + } + + #[benchmark] + fn claim_asset() -> Result<(), BenchmarkError> { + use xcm_executor::traits::DropAssets; + + let (origin, ticket, assets) = T::claimable_asset()?; + + // We place some items into the asset trap to claim. + ::AssetTrap::drop_assets( + &origin, + assets.clone().into(), + &XcmContext { + origin: Some(origin.clone()), + message_hash: [0; 32], + topic: None, + }, + ); + + // Assets should be in the trap now. + + let mut executor = new_executor::(origin); + let instruction = Instruction::ClaimAsset { + assets: assets.clone(), + ticket, + }; + let xcm = Xcm(vec![instruction]); + #[block] + { + executor.bench_process(xcm)?; + } + assert!(executor.holding().ensure_contains(&assets).is_ok()); + Ok(()) + } + + #[benchmark] + fn trap() -> Result<(), BenchmarkError> { + let mut executor = new_executor::(Default::default()); + let instruction = Instruction::Trap(10); + let xcm = Xcm(vec![instruction]); + // In order to access result in the verification below, it needs to be defined here. + let mut _result = Ok(()); + + #[block] + { + _result = executor.bench_process(xcm); + } + assert!(matches!( + _result, + Err(ExecutorError { + xcm_error: XcmError::Trap(10), + .. + }) + )); + Ok(()) + } + + #[benchmark] + fn subscribe_version() -> Result<(), BenchmarkError> { + use xcm_executor::traits::VersionChangeNotifier; + let origin = T::subscribe_origin()?; + let query_id = Default::default(); + let max_response_weight = Default::default(); + let mut executor = new_executor::(origin.clone()); + let instruction = Instruction::SubscribeVersion { + query_id, + max_response_weight, + }; + let xcm = Xcm(vec![instruction]); + #[block] + { + executor.bench_process(xcm)?; + } + assert!( + ::SubscriptionService::is_subscribed(&origin) + ); + Ok(()) + } + + #[benchmark] + fn unsubscribe_version() -> Result<(), BenchmarkError> { + use xcm_executor::traits::VersionChangeNotifier; + // First we need to subscribe to notifications. + let origin = T::subscribe_origin()?; + let query_id = Default::default(); + let max_response_weight = Default::default(); + ::SubscriptionService::start( + &origin, + query_id, + max_response_weight, + &XcmContext { + origin: Some(origin.clone()), + message_hash: [0; 32], + topic: None, + }, + ) + .map_err(|_| "Could not start subscription")?; + assert!( + ::SubscriptionService::is_subscribed(&origin) + ); + + let mut executor = new_executor::(origin.clone()); + let instruction = Instruction::UnsubscribeVersion; + let xcm = Xcm(vec![instruction]); + #[block] + { + executor.bench_process(xcm)?; + } + assert!( + !::SubscriptionService::is_subscribed(&origin) + ); + Ok(()) + } + + #[benchmark] + fn initiate_reserve_withdraw() -> Result<(), BenchmarkError> { + let holding = T::worst_case_holding(1); + let assets_filter = MultiAssetFilter::Definite(holding.clone()); + let reserve = T::valid_destination().map_err(|_| BenchmarkError::Skip)?; + let mut executor = new_executor::(Default::default()); + executor.set_holding(holding.into()); + let instruction = Instruction::InitiateReserveWithdraw { + assets: assets_filter, + reserve, + xcm: Xcm(vec![]), + }; + let xcm = Xcm(vec![instruction]); + #[block] + { + executor.bench_process(xcm)?; + } + // The execute completing successfully is as good as we can check. + Ok(()) + } + + #[benchmark] + fn burn_asset() -> Result<(), BenchmarkError> { + let holding = T::worst_case_holding(0); + let assets = holding.clone(); + + let mut executor = new_executor::(Default::default()); + executor.set_holding(holding.into()); + + let instruction = Instruction::BurnAsset(assets.into()); + let xcm = Xcm(vec![instruction]); + #[block] + { + executor.bench_process(xcm)?; + } + assert!(executor.holding().is_empty()); + Ok(()) + } + + #[benchmark] + fn expect_asset() -> Result<(), BenchmarkError> { + let holding = T::worst_case_holding(0); + let assets = holding.clone(); + + let mut executor = new_executor::(Default::default()); + executor.set_holding(holding.into()); + + let instruction = Instruction::ExpectAsset(assets.into()); + let xcm = Xcm(vec![instruction]); + #[block] + { + executor.bench_process(xcm)?; + } + // `execute` completing successfully is as good as we can check. + Ok(()) + } + + #[benchmark] + fn expect_origin() -> Result<(), BenchmarkError> { + let expected_origin = Parent.into(); + let mut executor = new_executor::(Default::default()); + + let instruction = Instruction::ExpectOrigin(Some(expected_origin)); + let xcm = Xcm(vec![instruction]); + let mut _result = Ok(()); + #[block] + { + _result = executor.bench_process(xcm); + } + assert!(matches!( + _result, + Err(ExecutorError { + xcm_error: XcmError::ExpectationFalse, + .. + }) + )); + Ok(()) + } + + #[benchmark] + fn expect_error() -> Result<(), BenchmarkError> { + let mut executor = new_executor::(Default::default()); + executor.set_error(Some((3u32, XcmError::Overflow))); + + let instruction = Instruction::ExpectError(None); + let xcm = Xcm(vec![instruction]); + let mut _result = Ok(()); + #[block] + { + _result = executor.bench_process(xcm); + } + assert!(matches!( + _result, + Err(ExecutorError { + xcm_error: XcmError::ExpectationFalse, + .. + }) + )); + Ok(()) + } + + #[benchmark] + fn expect_transact_status() -> Result<(), BenchmarkError> { + let mut executor = new_executor::(Default::default()); + let worst_error = + || -> MaybeErrorCode { vec![0; MaxDispatchErrorLen::get() as usize].into() }; + executor.set_transact_status(worst_error()); + + let instruction = Instruction::ExpectTransactStatus(worst_error()); + let xcm = Xcm(vec![instruction]); + let mut _result = Ok(()); + #[block] + { + _result = executor.bench_process(xcm); + } + assert!(matches!(_result, Ok(..))); + Ok(()) + } + + #[benchmark] + fn query_pallet() -> Result<(), BenchmarkError> { + let query_id = Default::default(); + let destination = T::valid_destination().map_err(|_| BenchmarkError::Skip)?; + let max_weight = Default::default(); + let mut executor = new_executor::(Default::default()); + + let instruction = Instruction::QueryPallet { + module_name: b"frame_system".to_vec(), + response_info: QueryResponseInfo { + destination, + query_id, + max_weight, + }, + }; + let xcm = Xcm(vec![instruction]); + #[block] + { + executor.bench_process(xcm)?; + } + Ok(()) + } + + #[benchmark] + fn expect_pallet() -> Result<(), BenchmarkError> { + let mut executor = new_executor::(Default::default()); + + let instruction = Instruction::ExpectPallet { + index: 10, + name: b"System".to_vec(), + module_name: b"frame_system".to_vec(), + crate_major: 4, + min_crate_minor: 0, + }; + let xcm = Xcm(vec![instruction]); + #[block] + { + executor.bench_process(xcm)?; + } + // the execution succeeding is all we need to verify this xcm was successful + Ok(()) + } + + #[benchmark] + fn report_transact_status() -> Result<(), BenchmarkError> { + let query_id = Default::default(); + let destination = T::valid_destination().map_err(|_| BenchmarkError::Skip)?; + let max_weight = Default::default(); + + let mut executor = new_executor::(Default::default()); + executor.set_transact_status(b"MyError".to_vec().into()); + + let instruction = Instruction::ReportTransactStatus(QueryResponseInfo { + query_id, + destination, + max_weight, + }); + let xcm = Xcm(vec![instruction]); + #[block] + { + executor.bench_process(xcm)?; + } + Ok(()) + } + + #[benchmark] + fn clear_transact_status() -> Result<(), BenchmarkError> { + let mut executor = new_executor::(Default::default()); + executor.set_transact_status(b"MyError".to_vec().into()); + + let instruction = Instruction::ClearTransactStatus; + let xcm = Xcm(vec![instruction]); + #[block] + { + executor.bench_process(xcm)?; + } + assert_eq!(executor.transact_status(), &MaybeErrorCode::Success); + Ok(()) + } + + #[benchmark] + fn set_topic() -> Result<(), BenchmarkError> { + let mut executor = new_executor::(Default::default()); + + let instruction = Instruction::SetTopic([1; 32]); + let xcm = Xcm(vec![instruction]); + #[block] + { + executor.bench_process(xcm)?; + } + assert_eq!(executor.topic(), &Some([1; 32])); + Ok(()) + } + + #[benchmark] + fn clear_topic() -> Result<(), BenchmarkError> { + let mut executor = new_executor::(Default::default()); + executor.set_topic(Some([2; 32])); + + let instruction = Instruction::ClearTopic; + let xcm = Xcm(vec![instruction]); + #[block] + { + executor.bench_process(xcm)?; + } + assert_eq!(executor.topic(), &None); + Ok(()) + } + + #[benchmark] + fn set_fees_mode() -> Result<(), BenchmarkError> { + let mut executor = new_executor::(Default::default()); + executor.set_fees_mode(FeesMode { + jit_withdraw: false, + }); + + let instruction = Instruction::SetFeesMode { jit_withdraw: true }; + let xcm = Xcm(vec![instruction]); + #[block] + { + executor.bench_process(xcm)?; + } + assert_eq!(executor.fees_mode(), &FeesMode { jit_withdraw: true }); + Ok(()) + } + + #[benchmark] + fn unpaid_execution() -> Result<(), BenchmarkError> { + let mut executor = new_executor::(Default::default()); + executor.set_origin(Some(Here.into())); + + let instruction = Instruction::>::UnpaidExecution { + weight_limit: WeightLimit::Unlimited, + check_origin: Some(Here.into()), + }; + + let xcm = Xcm(vec![instruction]); + #[block] + { + executor.bench_process(xcm)?; + } + Ok(()) + } + + #[benchmark] + fn exchange_asset() -> Result<(), BenchmarkError> { + #[block] + {} + Err(BenchmarkError::Override(BenchmarkResult::from_weight( + Weight::MAX, + ))) + } + + #[benchmark] + fn export_message() -> Result<(), BenchmarkError> { + #[block] + {} + Err(BenchmarkError::Override(BenchmarkResult::from_weight( + Weight::MAX, + ))) + } + + #[benchmark] + fn lock_asset() -> Result<(), BenchmarkError> { + #[block] + {} + Err(BenchmarkError::Override(BenchmarkResult::from_weight( + Weight::MAX, + ))) + } + + #[benchmark] + fn unlock_asset() -> Result<(), BenchmarkError> { + #[block] + {} + Err(BenchmarkError::Override(BenchmarkResult::from_weight( + Weight::MAX, + ))) + } + + #[benchmark] + fn note_unlockable() -> Result<(), BenchmarkError> { + #[block] + {} + Err(BenchmarkError::Override(BenchmarkResult::from_weight( + Weight::MAX, + ))) + } + + #[benchmark] + fn request_unlock() -> Result<(), BenchmarkError> { + #[block] + {} + Err(BenchmarkError::Override(BenchmarkResult::from_weight( + Weight::MAX, + ))) + } + + #[benchmark] + fn universal_origin() -> Result<(), BenchmarkError> { + #[block] + {} + Err(BenchmarkError::Override(BenchmarkResult::from_weight( + Weight::MAX, + ))) + } + + impl_benchmark_test_suite!( + Pallet, + crate::generic::mock::new_test_ext(), + crate::generic::mock::Test + ); +} diff --git a/pallets/astar-xcm-benchmarks/src/generic/mock.rs b/pallets/astar-xcm-benchmarks/src/generic/mock.rs new file mode 100644 index 0000000000..76a9493373 --- /dev/null +++ b/pallets/astar-xcm-benchmarks/src/generic/mock.rs @@ -0,0 +1,242 @@ +// This file is part of Astar. + +// Copyright (C) 2019-2023 Stake Technologies Pte.Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later + +// Astar is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Astar is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Astar. If not, see . + +// Copyright (C) Parity Technologies (UK) Ltd. +//! A mock runtime for XCM benchmarking. + +use crate::{generic, mock::*, *}; +use frame_support::{ + match_types, parameter_types, + traits::{Everything, OriginTrait}, + weights::Weight, +}; +use parity_scale_codec::Decode; +use sp_core::H256; +use sp_runtime::{ + testing::Header, + traits::{BlakeTwo256, IdentityLookup, TrailingZeroInput}, +}; +use xcm_builder::{ + test_utils::{ + Assets, TestAssetExchanger, TestAssetLocker, TestAssetTrap, TestSubscriptionService, + TestUniversalAliases, + }, + AllowUnpaidExecutionFrom, +}; +use xcm_executor::traits::ConvertOrigin; + +type Block = frame_system::mocking::MockBlock; +type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic; + +frame_support::construct_runtime!( + pub struct Test + where + Block = Block, + NodeBlock = Block, + UncheckedExtrinsic = UncheckedExtrinsic, + { + System: frame_system = 10, + XcmGenericBenchmarks: generic, + } +); + +parameter_types! { + pub const BlockHashCount: u64 = 250; + pub BlockWeights: frame_system::limits::BlockWeights = + frame_system::limits::BlockWeights::simple_max(Weight::from_parts(1024, u64::MAX)); +} + +impl frame_system::Config for Test { + type BaseCallFilter = Everything; + type BlockWeights = (); + type BlockLength = (); + type DbWeight = (); + type RuntimeOrigin = RuntimeOrigin; + type Hash = H256; + type RuntimeCall = RuntimeCall; + type Hashing = BlakeTwo256; + type AccountId = u64; + type Lookup = IdentityLookup; + type RuntimeEvent = RuntimeEvent; + type BlockHashCount = BlockHashCount; + type Version = (); + type PalletInfo = PalletInfo; + type AccountData = pallet_balances::AccountData; + type OnNewAccount = (); + type OnKilledAccount = (); + type SystemWeightInfo = (); + type SS58Prefix = (); + type OnSetCode = (); + type MaxConsumers = frame_support::traits::ConstU32<16>; + type Index = u64; + type Header = Header; + type BlockNumber = u64; +} + +/// The benchmarks in this pallet should never need an asset transactor to begin with. +pub struct NoAssetTransactor; +impl xcm_executor::traits::TransactAsset for NoAssetTransactor { + fn deposit_asset(_: &MultiAsset, _: &MultiLocation, _: &XcmContext) -> Result<(), XcmError> { + unreachable!(); + } + + fn withdraw_asset( + _: &MultiAsset, + _: &MultiLocation, + _: Option<&XcmContext>, + ) -> Result { + unreachable!(); + } +} + +parameter_types! { + pub const MaxInstructions: u32 = 100; + pub const MaxAssetsIntoHolding: u32 = 64; +} + +match_types! { + pub type OnlyParachains: impl Contains = { + MultiLocation { parents: 0, interior: X1(Parachain(_)) } + }; +} + +pub struct XcmConfig; +impl xcm_executor::Config for XcmConfig { + type RuntimeCall = RuntimeCall; + type XcmSender = DevNull; + type AssetTransactor = NoAssetTransactor; + type OriginConverter = AlwaysSignedByDefault; + type IsReserve = AllAssetLocationsPass; + type IsTeleporter = (); + type UniversalLocation = UniversalLocation; + type Barrier = AllowUnpaidExecutionFrom; + type Weigher = xcm_builder::FixedWeightBounds; + type Trader = xcm_builder::FixedRateOfFungible; + type ResponseHandler = DevNull; + type AssetTrap = TestAssetTrap; + type AssetLocker = TestAssetLocker; + type AssetExchanger = TestAssetExchanger; + type AssetClaims = TestAssetTrap; + type SubscriptionService = TestSubscriptionService; + type PalletInstancesInfo = AllPalletsWithSystem; + type MaxAssetsIntoHolding = MaxAssetsIntoHolding; + type FeeManager = (); + // No bridges yet... + type MessageExporter = (); + type UniversalAliases = TestUniversalAliases; + type CallDispatcher = RuntimeCall; + type SafeCallFilter = Everything; +} + +impl crate::Config for Test { + type XcmConfig = XcmConfig; + type AccountIdConverter = AccountIdConverter; + fn valid_destination() -> Result { + let valid_destination: MultiLocation = Junction::AccountId32 { + network: None, + id: [0u8; 32], + } + .into(); + + Ok(valid_destination) + } + fn worst_case_holding(depositable_count: u32) -> MultiAssets { + crate::mock_worst_case_holding( + depositable_count, + ::MaxAssetsIntoHolding::get(), + ) + } +} + +impl generic::Config for Test { + type RuntimeCall = RuntimeCall; + + fn worst_case_response() -> (u64, Response) { + let assets: MultiAssets = (Concrete(Here.into()), 100).into(); + (0, Response::Assets(assets)) + } + + fn worst_case_asset_exchange() -> Result<(MultiAssets, MultiAssets), BenchmarkError> { + Ok(Default::default()) + } + + fn universal_alias() -> Result<(MultiLocation, Junction), BenchmarkError> { + Ok((Here.into(), GlobalConsensus(ByGenesis([0; 32])))) + } + + fn transact_origin_and_runtime_call( + ) -> Result<(MultiLocation, ::RuntimeCall), BenchmarkError> { + Ok(( + Default::default(), + frame_system::Call::remark_with_event { remark: vec![] }.into(), + )) + } + + fn subscribe_origin() -> Result { + Ok(Default::default()) + } + + fn claimable_asset() -> Result<(MultiLocation, MultiLocation, MultiAssets), BenchmarkError> { + let assets: MultiAssets = (Concrete(Here.into()), 100).into(); + let ticket = MultiLocation { + parents: 0, + interior: X1(GeneralIndex(0)), + }; + Ok((Default::default(), ticket, assets)) + } + + fn unlockable_asset() -> Result<(MultiLocation, MultiLocation, MultiAsset), BenchmarkError> { + let assets: MultiAsset = (Concrete(Here.into()), 100).into(); + Ok((Default::default(), Default::default(), assets)) + } + + fn export_message_origin_and_destination( + ) -> Result<(MultiLocation, NetworkId, InteriorMultiLocation), BenchmarkError> { + // No MessageExporter in tests + Err(BenchmarkError::Skip) + } +} + +#[cfg(feature = "runtime-benchmarks")] +pub fn new_test_ext() -> sp_io::TestExternalities { + use sp_runtime::BuildStorage; + let t = GenesisConfig { + ..Default::default() + } + .build_storage() + .unwrap(); + sp_tracing::try_init_simple(); + t.into() +} + +pub struct AlwaysSignedByDefault(core::marker::PhantomData); +impl ConvertOrigin for AlwaysSignedByDefault +where + RuntimeOrigin: OriginTrait, + ::AccountId: Decode, +{ + fn convert_origin( + _origin: impl Into, + _kind: OriginKind, + ) -> Result { + Ok(RuntimeOrigin::signed( + ::AccountId::decode(&mut TrailingZeroInput::zeroes()) + .expect("infinite length input; no invalid inputs for type; qed"), + )) + } +} diff --git a/pallets/astar-xcm-benchmarks/src/generic/mod.rs b/pallets/astar-xcm-benchmarks/src/generic/mod.rs new file mode 100644 index 0000000000..7c00229365 --- /dev/null +++ b/pallets/astar-xcm-benchmarks/src/generic/mod.rs @@ -0,0 +1,95 @@ +// This file is part of Astar. + +// Copyright (C) 2019-2023 Stake Technologies Pte.Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later + +// Astar is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Astar is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Astar. If not, see . + +// Copyright (C) Parity Technologies (UK) Ltd. +pub use pallet::*; + +#[cfg(feature = "runtime-benchmarks")] +pub mod benchmarking; +#[cfg(test)] +mod mock; + +#[frame_support::pallet] +pub mod pallet { + use frame_benchmarking::BenchmarkError; + use frame_support::{ + dispatch::{Dispatchable, GetDispatchInfo}, + pallet_prelude::Encode, + }; + use xcm::latest::{ + InteriorMultiLocation, Junction, MultiAsset, MultiAssets, MultiLocation, NetworkId, + Response, + }; + + #[pallet::config] + pub trait Config: frame_system::Config + crate::Config { + type RuntimeCall: Dispatchable + + GetDispatchInfo + + From> + + Encode; + + /// The response which causes the most runtime weight. + fn worst_case_response() -> (u64, Response); + + /// The pair of asset collections which causes the most runtime weight if demanded to be + /// exchanged. + /// + /// The first element in the returned tuple represents the assets that are being exchanged + /// from, whereas the second element represents the assets that are being exchanged to. + /// + /// If set to `Err`, benchmarks which rely on an `exchange_asset` will be skipped. + fn worst_case_asset_exchange() -> Result<(MultiAssets, MultiAssets), BenchmarkError>; + + /// A `(MultiLocation, Junction)` that is one of the `UniversalAliases` configured by the XCM executor. + /// + /// If set to `Err`, benchmarks which rely on a universal alias will be skipped. + fn universal_alias() -> Result<(MultiLocation, Junction), BenchmarkError>; + + /// The `MultiLocation` and `RuntimeCall` used for successful transaction XCMs. + /// + /// If set to `Err`, benchmarks which rely on a `transact_origin_and_runtime_call` will be + /// skipped. + fn transact_origin_and_runtime_call() -> Result< + ( + MultiLocation, + >::RuntimeCall, + ), + BenchmarkError, + >; + + /// A valid `MultiLocation` we can successfully subscribe to. + /// + /// If set to `Err`, benchmarks which rely on a `subscribe_origin` will be skipped. + fn subscribe_origin() -> Result; + + /// Return an origin, ticket, and assets that can be trapped and claimed. + fn claimable_asset() -> Result<(MultiLocation, MultiLocation, MultiAssets), BenchmarkError>; + + /// Return an unlocker, owner and assets that can be locked and unlocked. + fn unlockable_asset() -> Result<(MultiLocation, MultiLocation, MultiAsset), BenchmarkError>; + + /// A `(MultiLocation, NetworkId, InteriorMultiLocation)` we can successfully export message to. + /// + /// If set to `Err`, benchmarks which rely on `export_message` will be skipped. + fn export_message_origin_and_destination( + ) -> Result<(MultiLocation, NetworkId, InteriorMultiLocation), BenchmarkError>; + } + + #[pallet::pallet] + pub struct Pallet(_); +} diff --git a/pallets/astar-xcm-benchmarks/src/lib.rs b/pallets/astar-xcm-benchmarks/src/lib.rs new file mode 100644 index 0000000000..4de6e2aaf2 --- /dev/null +++ b/pallets/astar-xcm-benchmarks/src/lib.rs @@ -0,0 +1,120 @@ +// This file is part of Astar. + +// Copyright (C) 2019-2023 Stake Technologies Pte.Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later + +// Astar is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Astar is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Astar. If not, see . + +// Copyright (C) Parity Technologies (UK) Ltd.ww.gnu.org/licenses/>. + +//! Pallet that serves no other purpose than benchmarking raw messages [`Xcm`]. + +#![cfg_attr(not(feature = "std"), no_std)] + +use frame_benchmarking::{account, BenchmarkError}; +use parity_scale_codec::Encode; +use sp_std::prelude::*; +use xcm::latest::prelude::*; +use xcm_executor::{traits::Convert, Config as XcmConfig}; + +pub mod fungible; +pub mod generic; + +#[cfg(feature = "runtime-benchmarks")] +pub use generic::{benchmarking, Pallet}; + +#[cfg(test)] +mod mock; + +/// A base trait for all individual pallets +pub trait Config: frame_system::Config { + /// The XCM configurations. + /// + /// These might affect the execution of XCM messages, such as defining how the + /// `TransactAsset` is implemented. + type XcmConfig: XcmConfig; + + /// A converter between a multi-location to a sovereign account. + type AccountIdConverter: Convert; + + /// Does any necessary setup to create a valid destination for XCM messages. + /// Returns that destination's multi-location to be used in benchmarks. + fn valid_destination() -> Result; + + /// Worst case scenario for a holding account in this runtime. + fn worst_case_holding(depositable_count: u32) -> MultiAssets; +} + +const SEED: u32 = 0; + +/// The XCM executor to use for doing stuff. +pub type ExecutorOf = xcm_executor::XcmExecutor<::XcmConfig>; +/// The overarching call type. +pub type OverArchingCallOf = ::RuntimeCall; +/// The asset transactor of our executor +pub type AssetTransactorOf = <::XcmConfig as XcmConfig>::AssetTransactor; +/// The call type of executor's config. Should eventually resolve to the same overarching call type. +pub type XcmCallOf = <::XcmConfig as XcmConfig>::RuntimeCall; + +pub fn mock_worst_case_holding(depositable_count: u32, max_assets: u32) -> MultiAssets { + let fungibles_amount: u128 = 100; + let holding_fungibles = max_assets / 2 - depositable_count; + let holding_non_fungibles = holding_fungibles; + (0..holding_fungibles) + .map(|i| { + MultiAsset { + id: Concrete(GeneralIndex(i as u128).into()), + fun: Fungible(fungibles_amount * i as u128), + } + .into() + }) + .chain(core::iter::once(MultiAsset { + id: Concrete(Here.into()), + fun: Fungible(u128::MAX), + })) + .chain((0..holding_non_fungibles).map(|i| MultiAsset { + id: Concrete(GeneralIndex(i as u128).into()), + fun: NonFungible(asset_instance_from(i)), + })) + .collect::>() + .into() +} + +pub fn asset_instance_from(x: u32) -> AssetInstance { + let bytes = x.encode(); + let mut instance = [0u8; 4]; + instance.copy_from_slice(&bytes); + AssetInstance::Array4(instance) +} + +pub fn new_executor(origin: MultiLocation) -> ExecutorOf { + ExecutorOf::::new(origin, [0; 32]) +} + +/// Build a multi-location from an account id. +fn account_id_junction(index: u32) -> Junction { + let account: T::AccountId = account("account", index, SEED); + let mut encoded = account.encode(); + encoded.resize(32, 0u8); + let mut id = [0u8; 32]; + id.copy_from_slice(&encoded); + Junction::AccountId32 { network: None, id } +} + +pub fn account_and_location(index: u32) -> (T::AccountId, MultiLocation) { + let location: MultiLocation = account_id_junction::(index).into(); + let account = T::AccountIdConverter::convert(location.clone()).unwrap(); + + (account, location) +} diff --git a/pallets/astar-xcm-benchmarks/src/mock.rs b/pallets/astar-xcm-benchmarks/src/mock.rs new file mode 100644 index 0000000000..3f783859df --- /dev/null +++ b/pallets/astar-xcm-benchmarks/src/mock.rs @@ -0,0 +1,79 @@ +// This file is part of Astar. + +// Copyright (C) 2019-2023 Stake Technologies Pte.Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later + +// Astar is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Astar is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Astar. If not, see . + +// Copyright (C) Parity Technologies (UK) Ltd. +use crate::*; +use frame_support::{parameter_types, traits::ContainsPair}; +use xcm::latest::Weight; + +// An xcm sender/receiver akin to > /dev/null +pub struct DevNull; +impl xcm::opaque::latest::SendXcm for DevNull { + type Ticket = (); + fn validate(_: &mut Option, _: &mut Option>) -> SendResult<()> { + Ok(((), MultiAssets::new())) + } + fn deliver(_: ()) -> Result { + Ok([0; 32]) + } +} + +impl xcm_executor::traits::OnResponse for DevNull { + fn expecting_response(_: &MultiLocation, _: u64, _: Option<&MultiLocation>) -> bool { + false + } + fn on_response( + _: &MultiLocation, + _: u64, + _: Option<&MultiLocation>, + _: Response, + _: Weight, + _: &XcmContext, + ) -> Weight { + Weight::zero() + } +} + +pub struct AccountIdConverter; +impl xcm_executor::traits::Convert for AccountIdConverter { + fn convert(ml: MultiLocation) -> Result { + match ml { + MultiLocation { + parents: 0, + interior: X1(Junction::AccountId32 { id, .. }), + } => Ok(::decode(&mut &*id.to_vec()).unwrap()), + _ => Err(ml), + } + } + fn reverse(acc: u64) -> Result { + Err(acc) + } +} + +parameter_types! { + pub UniversalLocation: InteriorMultiLocation = Junction::Parachain(101).into(); + pub UnitWeightCost: Weight = Weight::from_parts(10, 10); + pub WeightPrice: (AssetId, u128, u128) = (Concrete(Here.into()), 1_000_000, 1024); +} + +pub struct AllAssetLocationsPass; +impl ContainsPair for AllAssetLocationsPass { + fn contains(_: &MultiAsset, _: &MultiLocation) -> bool { + true + } +} diff --git a/primitives/src/xcm/mod.rs b/primitives/src/xcm/mod.rs index a0945c7532..27d2bcfc68 100644 --- a/primitives/src/xcm/mod.rs +++ b/primitives/src/xcm/mod.rs @@ -49,6 +49,8 @@ use orml_traits::location::{RelativeReserveProvider, Reserve}; use pallet_xc_asset_config::{ExecutionPaymentRate, XcAssetLocation}; +/// Max assets allowed in holding register +pub const MAX_ASSETS: u64 = 64; #[cfg(test)] mod tests; diff --git a/runtime/astar/src/xcm_config.rs b/runtime/astar/src/xcm_config.rs index 62299f6b77..5f01ba0bbf 100644 --- a/runtime/astar/src/xcm_config.rs +++ b/runtime/astar/src/xcm_config.rs @@ -136,8 +136,8 @@ pub type XcmOriginToTransactDispatchOrigin = ( parameter_types! { // One XCM operation is 1_000_000_000 weight - almost certainly a conservative estimate. - // For the PoV size, we estimate 4 kB per instruction. This will be changed when we benchmark the instructions. - pub UnitWeightCost: Weight = Weight::from_parts(1_000_000_000, 4 * 1024); + // For the PoV size, we estimate 4 kB per instruction. This will be changed when we benchmark the instructions. + pub UnitWeightCost: Weight = Weight::from_parts(1_000_000_000, 4 * 1024); pub const MaxInstructions: u32 = 100; } diff --git a/runtime/shibuya/Cargo.toml b/runtime/shibuya/Cargo.toml index f6f158ec9d..f500d443b3 100644 --- a/runtime/shibuya/Cargo.toml +++ b/runtime/shibuya/Cargo.toml @@ -33,6 +33,7 @@ sp-transaction-pool = { workspace = true } sp-version = { workspace = true } # frame dependencies +astar-xcm-benchmarks = { workspace = true } frame-executive = { workspace = true } frame-support = { workspace = true } frame-system = { workspace = true } @@ -253,6 +254,7 @@ runtime-benchmarks = [ "orml-xtokens/runtime-benchmarks", "astar-primitives/runtime-benchmarks", "pallet-assets/runtime-benchmarks", + "astar-xcm-benchmarks/runtime-benchmarks", "pallet-dynamic-evm-base-fee/runtime-benchmarks", ] try-runtime = [ diff --git a/runtime/shibuya/src/lib.rs b/runtime/shibuya/src/lib.rs index b4ceb150a9..063b96ed9a 100644 --- a/runtime/shibuya/src/lib.rs +++ b/runtime/shibuya/src/lib.rs @@ -28,9 +28,9 @@ use frame_support::{ dispatch::DispatchClass, parameter_types, traits::{ - AsEnsureOriginWithArg, ConstU32, Contains, Currency, EitherOfDiverse, EqualPrivilegeOnly, - FindAuthor, Get, Imbalance, InstanceFilter, Nothing, OnFinalize, OnUnbalanced, - WithdrawReasons, + fungible::ItemOf, AsEnsureOriginWithArg, ConstU32, Contains, Currency, EitherOfDiverse, + EqualPrivilegeOnly, FindAuthor, Get, Imbalance, InstanceFilter, Nothing, OnFinalize, + OnUnbalanced, WithdrawReasons, }, weights::{ constants::{ @@ -53,7 +53,7 @@ use pallet_transaction_payment::{ use parity_scale_codec::{Compact, Decode, Encode, MaxEncodedLen}; use polkadot_runtime_common::BlockHashCount; use sp_api::impl_runtime_apis; -use sp_core::{ConstBool, OpaqueMetadata, H160, H256, U256}; +use sp_core::{ConstBool, ConstU128, OpaqueMetadata, H160, H256, U256}; use sp_inherents::{CheckInherentsResult, InherentData}; use sp_runtime::{ create_runtime_str, generic, impl_opaque_keys, @@ -1441,6 +1441,9 @@ mod benches { [pallet_xvm, Xvm] [pallet_dynamic_evm_base_fee, DynamicEvmBaseFee] [pallet_unified_accounts, UnifiedAccounts] + [astar_xcm_benchmarks::generic, astar_xcm_benchmarks::generic::Pallet::] + [astar_xcm_benchmarks::fungible::balances, astar_xcm_benchmarks::fungible::balances::Pallet::] + [astar_xcm_benchmarks::fungible::assets, astar_xcm_benchmarks::fungible::assets::Pallet::] ); } @@ -1920,14 +1923,158 @@ impl_runtime_apis! { fn dispatch_benchmark( config: frame_benchmarking::BenchmarkConfig ) -> Result, sp_runtime::RuntimeString> { - use frame_benchmarking::{baseline, Benchmarking, BenchmarkBatch, TrackedStorageKey}; + use frame_benchmarking::{baseline, Benchmarking, BenchmarkBatch, TrackedStorageKey, BenchmarkError}; use frame_system_benchmarking::Pallet as SystemBench; use baseline::Pallet as BaselineBench; + use xcm_config::{XcmConfig, LocationToAccountId}; + use xcm::latest::prelude::*; + use xcm_builder::MintLocation; + use sp_runtime::AccountId32; impl frame_system_benchmarking::Config for Runtime {} impl baseline::Config for Runtime {} - use frame_support::traits::WhitelistedStorageKeys; + parameter_types! { + pub const NoCheckingAccount: Option<(::AccountId, MintLocation)> = None; + pub const NoTeleporter: Option<(xcm::latest::MultiLocation, xcm::latest::MultiAsset)> = None; + } + use frame_support::{traits::WhitelistedStorageKeys,assert_ok}; + impl astar_xcm_benchmarks::Config for Runtime { + type XcmConfig = XcmConfig; + type AccountIdConverter = LocationToAccountId; + fn valid_destination() -> Result { + Ok(MultiLocation::parent()) + } + fn worst_case_holding(_depositable_count: u32) -> MultiAssets { + // we can have max of 64 assets in holding so this should be + // a good estimate for worst case + const HOLDING_FUNGIBLES: u32 = 62; + let fungibles_amount: u128 = 100; + let assets = (0..HOLDING_FUNGIBLES).map(|i| { + let location: MultiLocation = GeneralIndex(i as u128).into(); + MultiAsset { + id: Concrete(location), + fun: Fungible(fungibles_amount * i as u128), + } + .into() + }) + .chain( + core::iter::once( + MultiAsset { + id: Concrete(MultiLocation::parent()), + fun: Fungible(u128::MAX) + } + ) + ) + .chain( + core::iter::once( + MultiAsset { + id: Concrete(MultiLocation::here()), + fun: Fungible(u128::MAX) + } + ) + ) + .collect::>(); + assets.into() + } + } + impl astar_xcm_benchmarks::generic::Config for Runtime { + type RuntimeCall = RuntimeCall; + + fn worst_case_response() -> (u64, Response) { + let assets: Vec = vec![MultiAsset { + id: Concrete(MultiLocation::parent()), + fun: Fungible(u128::MAX), + }]; + (0u64, Response::Assets(assets.into())) + + } + + fn worst_case_asset_exchange() -> Result<(MultiAssets, MultiAssets), BenchmarkError> { + // Shibuya doesn't support asset exchanges + Err(BenchmarkError::Skip) + } + + fn universal_alias() -> Result<(MultiLocation, Junction), BenchmarkError> { + // The XCM executor of Shibuya doesn't have a configured `UniversalAliases` + Err(BenchmarkError::Skip) + } + + fn transact_origin_and_runtime_call() -> Result<(MultiLocation, RuntimeCall), BenchmarkError> { + // We don't care about the call itself, since that is accounted for in the weight parameter + // and included in the final weight calculation. So this is just the overhead of submitting + // a noop call. + Ok((MultiLocation::parent(), frame_system::Call::remark_with_event { + remark: vec![] + }.into())) + } + + fn subscribe_origin() -> Result { + Ok(MultiLocation::parent()) + } + + fn claimable_asset() -> Result<(MultiLocation, MultiLocation, MultiAssets), BenchmarkError> { + let origin = MultiLocation::parent(); + let assets: MultiAssets = (Concrete(MultiLocation::parent()), 1_000u128) + .into(); + let ticket = MultiLocation { parents: 0, interior: Here }; + Ok((origin, ticket, assets)) + } + + fn unlockable_asset() -> Result<(MultiLocation, MultiLocation, MultiAsset), BenchmarkError> { + // Shibuya doesn't support asset locking + Err(BenchmarkError::Skip) + } + + fn export_message_origin_and_destination( + ) -> Result<(MultiLocation, NetworkId, InteriorMultiLocation), BenchmarkError> { + // Shibuya doesn't support exporting messages + Err(BenchmarkError::Skip) + } + } + + impl astar_xcm_benchmarks::fungible::balances::Config for Runtime { + type TransactAsset = Balances; + + /// The account used to check assets being teleported. + type CheckedAccount = NoCheckingAccount; + + /// A trusted location which we allow teleports from, and the asset we allow to teleport. + type TrustedTeleporter = NoTeleporter; + + /// Give me a fungible asset that your asset transactor is going to accept. + fn get_multi_asset() -> MultiAsset { + MultiAsset { + id: Concrete(Here.into()), + fun: Fungible(u128::MAX), + } + } + } + + impl astar_xcm_benchmarks::fungible::assets::Config for Runtime { + type TransactAsset = ItemOf, AccountId>; + + /// The account used to check assets being teleported. + type CheckedAccount = NoCheckingAccount; + + /// A trusted location which we allow teleports from, and the asset we allow to teleport. + type TrustedTeleporter = NoTeleporter; + + /// Give me a fungible asset that your asset transactor is going to accept. + fn get_multi_asset() -> MultiAsset { + // create an asset and make it sufficient + assert_ok!(pallet_assets::Pallet::::force_create(RuntimeOrigin::root(),parity_scale_codec::Compact(1),sp_runtime::MultiAddress::Id(AccountId32::new([0u8; 32])),true,1)); + let location = MultiLocation { parents : 0, interior :X1(GeneralIndex(1)) }; + // convert mapping for asset id + assert_ok!(pallet_xc_asset_config::Pallet::::register_asset_location(RuntimeOrigin::root(),Box::new(location.clone().into_versioned()),1)); + + MultiAsset { + id: Concrete(location), + fun: Fungible(100_000_000_000u128), + } + } + } + let whitelist: Vec = AllPalletsWithSystem::whitelisted_storage_keys(); let mut batches = Vec::::new(); diff --git a/runtime/shibuya/src/weights/mod.rs b/runtime/shibuya/src/weights/mod.rs index f1df12d585..f71ef213ad 100644 --- a/runtime/shibuya/src/weights/mod.rs +++ b/runtime/shibuya/src/weights/mod.rs @@ -19,3 +19,4 @@ pub mod pallet_assets; pub mod pallet_balances; pub mod pallet_xcm; +pub mod xcm_instruction_benchmarks; diff --git a/runtime/shibuya/src/weights/xcm_instruction_benchmarks/fungible_assets_benchmarks.rs b/runtime/shibuya/src/weights/xcm_instruction_benchmarks/fungible_assets_benchmarks.rs new file mode 100644 index 0000000000..dae5969057 --- /dev/null +++ b/runtime/shibuya/src/weights/xcm_instruction_benchmarks/fungible_assets_benchmarks.rs @@ -0,0 +1,183 @@ + +// This file is part of Astar. + +// Copyright (C) 2019-2023 Stake Technologies Pte.Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later + +// Astar is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Astar is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Astar. If not, see . + +//! Autogenerated weights for astar_xcm_benchmarks::fungible::assets +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-10-20, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `devserver-01`, CPU: `Intel(R) Xeon(R) E-2236 CPU @ 3.40GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("shibuya-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/release/astar-collator +// benchmark +// pallet +// --chain=shibuya-dev +// --steps=50 +// --repeat=20 +// --pallet=astar_xcm_benchmarks::fungible::assets +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --heap-pages=4096 +// --output=./benchmark-results/shibuya-dev/xcm_benchmarks_fungible_assets_weights.rs +// --template=./scripts/templates/weight-template.hbs + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] + +use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; +use core::marker::PhantomData; + +/// Weights for astar_xcm_benchmarks::fungible::assets using the Substrate node and recommended hardware. +pub struct WeightInfo(PhantomData); +impl WeightInfo { + /// Storage: XcAssetConfig AssetLocationToId (r:1 w:0) + /// Proof Skipped: XcAssetConfig AssetLocationToId (max_values: None, max_size: None, mode: Measured) + /// Storage: Assets Asset (r:1 w:1) + /// Proof: Assets Asset (max_values: None, max_size: Some(222), added: 2697, mode: MaxEncodedLen) + /// Storage: Assets Account (r:1 w:1) + /// Proof: Assets Account (max_values: None, max_size: Some(146), added: 2621, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: UnifiedAccounts NativeToEvm (r:1 w:0) + /// Proof: UnifiedAccounts NativeToEvm (max_values: None, max_size: Some(68), added: 2543, mode: MaxEncodedLen) + pub(crate) fn withdraw_asset() -> Weight { + // Proof Size summary in bytes: + // Measured: `688` + // Estimated: `4153` + // Minimum execution time: 48_407_000 picoseconds. + Weight::from_parts(48_710_000, 4153) + .saturating_add(T::DbWeight::get().reads(5_u64)) + .saturating_add(T::DbWeight::get().writes(3_u64)) + } + /// Storage: XcAssetConfig AssetLocationToId (r:1 w:0) + /// Proof Skipped: XcAssetConfig AssetLocationToId (max_values: None, max_size: None, mode: Measured) + /// Storage: Assets Asset (r:1 w:1) + /// Proof: Assets Asset (max_values: None, max_size: Some(222), added: 2697, mode: MaxEncodedLen) + /// Storage: Assets Account (r:2 w:2) + /// Proof: Assets Account (max_values: None, max_size: Some(146), added: 2621, mode: MaxEncodedLen) + pub(crate) fn transfer_asset() -> Weight { + // Proof Size summary in bytes: + // Measured: `622` + // Estimated: `6232` + // Minimum execution time: 43_069_000 picoseconds. + Weight::from_parts(44_006_000, 6232) + .saturating_add(T::DbWeight::get().reads(4_u64)) + .saturating_add(T::DbWeight::get().writes(3_u64)) + } + /// Storage: XcAssetConfig AssetLocationToId (r:1 w:0) + /// Proof Skipped: XcAssetConfig AssetLocationToId (max_values: None, max_size: None, mode: Measured) + /// Storage: Assets Asset (r:1 w:1) + /// Proof: Assets Asset (max_values: None, max_size: Some(222), added: 2697, mode: MaxEncodedLen) + /// Storage: Assets Account (r:2 w:2) + /// Proof: Assets Account (max_values: None, max_size: Some(146), added: 2621, mode: MaxEncodedLen) + /// Storage: ParachainInfo ParachainId (r:1 w:0) + /// Proof: ParachainInfo ParachainId (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: PolkadotXcm SupportedVersion (r:1 w:0) + /// Proof Skipped: PolkadotXcm SupportedVersion (max_values: None, max_size: None, mode: Measured) + /// Storage: PolkadotXcm VersionDiscoveryQueue (r:1 w:1) + /// Proof Skipped: PolkadotXcm VersionDiscoveryQueue (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: PolkadotXcm SafeXcmVersion (r:1 w:0) + /// Proof Skipped: PolkadotXcm SafeXcmVersion (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParachainSystem HostConfiguration (r:1 w:0) + /// Proof Skipped: ParachainSystem HostConfiguration (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParachainSystem PendingUpwardMessages (r:1 w:1) + /// Proof Skipped: ParachainSystem PendingUpwardMessages (max_values: Some(1), max_size: None, mode: Measured) + pub(crate) fn transfer_reserve_asset() -> Weight { + // Proof Size summary in bytes: + // Measured: `836` + // Estimated: `6232` + // Minimum execution time: 68_124_000 picoseconds. + Weight::from_parts(68_800_000, 6232) + .saturating_add(T::DbWeight::get().reads(10_u64)) + .saturating_add(T::DbWeight::get().writes(5_u64)) + } + /// Storage: Benchmark Override (r:0 w:0) + /// Proof Skipped: Benchmark Override (max_values: None, max_size: None, mode: Measured) + pub(crate) fn receive_teleported_asset() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 18_446_744_073_709_551_000 picoseconds. + Weight::from_parts(18_446_744_073_709_551_000, 0) + } + /// Storage: XcAssetConfig AssetLocationToId (r:1 w:0) + /// Proof Skipped: XcAssetConfig AssetLocationToId (max_values: None, max_size: None, mode: Measured) + /// Storage: Assets Asset (r:1 w:1) + /// Proof: Assets Asset (max_values: None, max_size: Some(222), added: 2697, mode: MaxEncodedLen) + /// Storage: Assets Account (r:1 w:1) + /// Proof: Assets Account (max_values: None, max_size: Some(146), added: 2621, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + pub(crate) fn deposit_asset() -> Weight { + // Proof Size summary in bytes: + // Measured: `424` + // Estimated: `3889` + // Minimum execution time: 37_158_000 picoseconds. + Weight::from_parts(37_598_000, 3889) + .saturating_add(T::DbWeight::get().reads(4_u64)) + .saturating_add(T::DbWeight::get().writes(3_u64)) + } + /// Storage: XcAssetConfig AssetLocationToId (r:1 w:0) + /// Proof Skipped: XcAssetConfig AssetLocationToId (max_values: None, max_size: None, mode: Measured) + /// Storage: Assets Asset (r:1 w:1) + /// Proof: Assets Asset (max_values: None, max_size: Some(222), added: 2697, mode: MaxEncodedLen) + /// Storage: Assets Account (r:1 w:1) + /// Proof: Assets Account (max_values: None, max_size: Some(146), added: 2621, mode: MaxEncodedLen) + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: ParachainInfo ParachainId (r:1 w:0) + /// Proof: ParachainInfo ParachainId (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: PolkadotXcm SupportedVersion (r:1 w:0) + /// Proof Skipped: PolkadotXcm SupportedVersion (max_values: None, max_size: None, mode: Measured) + /// Storage: PolkadotXcm VersionDiscoveryQueue (r:1 w:1) + /// Proof Skipped: PolkadotXcm VersionDiscoveryQueue (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: PolkadotXcm SafeXcmVersion (r:1 w:0) + /// Proof Skipped: PolkadotXcm SafeXcmVersion (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParachainSystem HostConfiguration (r:1 w:0) + /// Proof Skipped: ParachainSystem HostConfiguration (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParachainSystem PendingUpwardMessages (r:1 w:1) + /// Proof Skipped: ParachainSystem PendingUpwardMessages (max_values: Some(1), max_size: None, mode: Measured) + pub(crate) fn deposit_reserve_asset() -> Weight { + // Proof Size summary in bytes: + // Measured: `638` + // Estimated: `4103` + // Minimum execution time: 61_240_000 picoseconds. + Weight::from_parts(61_987_000, 4103) + .saturating_add(T::DbWeight::get().reads(10_u64)) + .saturating_add(T::DbWeight::get().writes(5_u64)) + } + /// Storage: Benchmark Override (r:0 w:0) + /// Proof Skipped: Benchmark Override (max_values: None, max_size: None, mode: Measured) + pub(crate) fn initiate_teleport() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 18_446_744_073_709_551_000 picoseconds. + Weight::from_parts(18_446_744_073_709_551_000, 0) + } + + pub(crate) fn reserve_asset_deposited() -> Weight { + // This instruction is a no-op for PoV (no storage access) + Weight::from_parts(200_000_000 as u64, 0) + } +} diff --git a/runtime/shibuya/src/weights/xcm_instruction_benchmarks/fungible_balances_benchmarks.rs b/runtime/shibuya/src/weights/xcm_instruction_benchmarks/fungible_balances_benchmarks.rs new file mode 100644 index 0000000000..7369c496ca --- /dev/null +++ b/runtime/shibuya/src/weights/xcm_instruction_benchmarks/fungible_balances_benchmarks.rs @@ -0,0 +1,165 @@ + +// This file is part of Astar. + +// Copyright (C) 2019-2023 Stake Technologies Pte.Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later + +// Astar is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Astar is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Astar. If not, see . +//! Autogenerated weights for `astar_xcm_benchmarks::fungible::assets` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-10-18, STEPS: `50`, REPEAT: `1`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `Deepanshu.local`, CPU: `` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("shibuya-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/release/astar-collator +// benchmark +// pallet +// --chain +// shibuya-dev +// --execution=wasm +// --wasm-execution=compiled +// --pallet +// astar_xcm_benchmarks::fungible::assets +// --extrinsic +// * +// --steps +// 50 +// --repeat +// 1 +// --output +// pallets/transfer-weight.rs + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `astar_xcm_benchmarks::fungible::assets`. +pub struct WeightInfo(PhantomData); +impl WeightInfo { + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: UnifiedAccounts NativeToEvm (r:1 w:0) + /// Proof: UnifiedAccounts NativeToEvm (max_values: None, max_size: Some(68), added: 2543, mode: MaxEncodedLen) + pub(crate) fn withdraw_asset() -> Weight { + // Proof Size summary in bytes: + // Measured: `182` + // Estimated: `3593` + // Minimum execution time: 29_196_000 picoseconds. + Weight::from_parts(29_523_000, 3593) + .saturating_add(T::DbWeight::get().reads(2_u64)) + .saturating_add(T::DbWeight::get().writes(1_u64)) + } + /// Storage: System Account (r:2 w:2) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: UnifiedAccounts NativeToEvm (r:1 w:0) + /// Proof: UnifiedAccounts NativeToEvm (max_values: None, max_size: Some(68), added: 2543, mode: MaxEncodedLen) + pub(crate) fn transfer_asset() -> Weight { + // Proof Size summary in bytes: + // Measured: `182` + // Estimated: `6196` + // Minimum execution time: 51_481_000 picoseconds. + Weight::from_parts(52_599_000, 6196) + .saturating_add(T::DbWeight::get().reads(3_u64)) + .saturating_add(T::DbWeight::get().writes(2_u64)) + } + /// Storage: System Account (r:2 w:2) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: UnifiedAccounts NativeToEvm (r:1 w:0) + /// Proof: UnifiedAccounts NativeToEvm (max_values: None, max_size: Some(68), added: 2543, mode: MaxEncodedLen) + /// Storage: ParachainInfo ParachainId (r:1 w:0) + /// Proof: ParachainInfo ParachainId (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: PolkadotXcm SupportedVersion (r:1 w:0) + /// Proof Skipped: PolkadotXcm SupportedVersion (max_values: None, max_size: None, mode: Measured) + /// Storage: PolkadotXcm VersionDiscoveryQueue (r:1 w:1) + /// Proof Skipped: PolkadotXcm VersionDiscoveryQueue (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: PolkadotXcm SafeXcmVersion (r:1 w:0) + /// Proof Skipped: PolkadotXcm SafeXcmVersion (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParachainSystem HostConfiguration (r:1 w:0) + /// Proof Skipped: ParachainSystem HostConfiguration (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParachainSystem PendingUpwardMessages (r:1 w:1) + /// Proof Skipped: ParachainSystem PendingUpwardMessages (max_values: Some(1), max_size: None, mode: Measured) + pub(crate) fn transfer_reserve_asset() -> Weight { + // Proof Size summary in bytes: + // Measured: `396` + // Estimated: `6196` + // Minimum execution time: 74_937_000 picoseconds. + Weight::from_parts(75_528_000, 6196) + .saturating_add(T::DbWeight::get().reads(9_u64)) + .saturating_add(T::DbWeight::get().writes(4_u64)) + } + /// Storage: Benchmark Override (r:0 w:0) + /// Proof Skipped: Benchmark Override (max_values: None, max_size: None, mode: Measured) + pub(crate) fn receive_teleported_asset() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 18_446_744_073_709_551_000 picoseconds. + Weight::from_parts(18_446_744_073_709_551_000, 0) + } + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + pub(crate) fn deposit_asset() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `3593` + // Minimum execution time: 25_946_000 picoseconds. + Weight::from_parts(26_173_000, 3593) + .saturating_add(T::DbWeight::get().reads(1_u64)) + .saturating_add(T::DbWeight::get().writes(1_u64)) + } + /// Storage: System Account (r:1 w:1) + /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) + /// Storage: ParachainInfo ParachainId (r:1 w:0) + /// Proof: ParachainInfo ParachainId (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: PolkadotXcm SupportedVersion (r:1 w:0) + /// Proof Skipped: PolkadotXcm SupportedVersion (max_values: None, max_size: None, mode: Measured) + /// Storage: PolkadotXcm VersionDiscoveryQueue (r:1 w:1) + /// Proof Skipped: PolkadotXcm VersionDiscoveryQueue (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: PolkadotXcm SafeXcmVersion (r:1 w:0) + /// Proof Skipped: PolkadotXcm SafeXcmVersion (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParachainSystem HostConfiguration (r:1 w:0) + /// Proof Skipped: ParachainSystem HostConfiguration (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParachainSystem PendingUpwardMessages (r:1 w:1) + /// Proof Skipped: ParachainSystem PendingUpwardMessages (max_values: Some(1), max_size: None, mode: Measured) + pub(crate) fn deposit_reserve_asset() -> Weight { + // Proof Size summary in bytes: + // Measured: `214` + // Estimated: `3679` + // Minimum execution time: 51_389_000 picoseconds. + Weight::from_parts(51_915_000, 3679) + .saturating_add(T::DbWeight::get().reads(7_u64)) + .saturating_add(T::DbWeight::get().writes(3_u64)) + } + /// Storage: Benchmark Override (r:0 w:0) + /// Proof Skipped: Benchmark Override (max_values: None, max_size: None, mode: Measured) + pub(crate) fn initiate_teleport() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 18_446_744_073_709_551_000 picoseconds. + Weight::from_parts(18_446_744_073_709_551_000, 0) + } + + pub(crate) fn reserve_asset_deposited() -> Weight { + // This instruction is a no-op for PoV (no storage access) + Weight::from_parts(200_000_000 as u64, 0) + } +} diff --git a/runtime/shibuya/src/weights/xcm_instruction_benchmarks/generic_benchmarks.rs b/runtime/shibuya/src/weights/xcm_instruction_benchmarks/generic_benchmarks.rs new file mode 100644 index 0000000000..174dd56875 --- /dev/null +++ b/runtime/shibuya/src/weights/xcm_instruction_benchmarks/generic_benchmarks.rs @@ -0,0 +1,413 @@ + +// This file is part of Astar. + +// Copyright (C) 2019-2023 Stake Technologies Pte.Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later + +// Astar is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Astar is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Astar. If not, see . + +//! Autogenerated weights for astar_xcm_benchmarks::generic +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-10-20, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `devserver-01`, CPU: `Intel(R) Xeon(R) E-2236 CPU @ 3.40GHz` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("shibuya-dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/release/astar-collator +// benchmark +// pallet +// --chain=shibuya-dev +// --steps=50 +// --repeat=20 +// --pallet=astar_xcm_benchmarks::generic +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --heap-pages=4096 +// --output=./benchmark-results/shibuya-dev/xcm_benchmarks_generic_weights.rs +// --template=./scripts/templates/weight-template.hbs + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] + +use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; +use core::marker::PhantomData; + +/// Weights for astar_xcm_benchmarks::generic using the Substrate node and recommended hardware. +pub struct WeightInfo(PhantomData); +impl WeightInfo { + /// Storage: ParachainInfo ParachainId (r:1 w:0) + /// Proof: ParachainInfo ParachainId (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: PolkadotXcm SupportedVersion (r:1 w:0) + /// Proof Skipped: PolkadotXcm SupportedVersion (max_values: None, max_size: None, mode: Measured) + /// Storage: PolkadotXcm VersionDiscoveryQueue (r:1 w:1) + /// Proof Skipped: PolkadotXcm VersionDiscoveryQueue (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: PolkadotXcm SafeXcmVersion (r:1 w:0) + /// Proof Skipped: PolkadotXcm SafeXcmVersion (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParachainSystem HostConfiguration (r:1 w:0) + /// Proof Skipped: ParachainSystem HostConfiguration (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParachainSystem PendingUpwardMessages (r:1 w:1) + /// Proof Skipped: ParachainSystem PendingUpwardMessages (max_values: Some(1), max_size: None, mode: Measured) + pub(crate) fn report_holding() -> Weight { + // Proof Size summary in bytes: + // Measured: `214` + // Estimated: `3679` + // Minimum execution time: 367_936_000 picoseconds. + Weight::from_parts(369_906_000, 3679) + .saturating_add(T::DbWeight::get().reads(6_u64)) + .saturating_add(T::DbWeight::get().writes(2_u64)) + } + pub(crate) fn buy_execution() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 48_101_000 picoseconds. + Weight::from_parts(48_508_000, 0) + } + /// Storage: PolkadotXcm Queries (r:1 w:0) + /// Proof Skipped: PolkadotXcm Queries (max_values: None, max_size: None, mode: Measured) + pub(crate) fn query_response() -> Weight { + // Proof Size summary in bytes: + // Measured: `69` + // Estimated: `3534` + // Minimum execution time: 11_817_000 picoseconds. + Weight::from_parts(12_036_000, 3534) + .saturating_add(T::DbWeight::get().reads(1_u64)) + } + pub(crate) fn transact() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 11_443_000 picoseconds. + Weight::from_parts(11_718_000, 0) + } + pub(crate) fn refund_surplus() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 3_771_000 picoseconds. + Weight::from_parts(3_878_000, 0) + } + pub(crate) fn set_error_handler() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 2_643_000 picoseconds. + Weight::from_parts(2_790_000, 0) + } + pub(crate) fn set_appendix() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 2_615_000 picoseconds. + Weight::from_parts(2_686_000, 0) + } + pub(crate) fn clear_error() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 2_541_000 picoseconds. + Weight::from_parts(2_678_000, 0) + } + pub(crate) fn descend_origin() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 3_485_000 picoseconds. + Weight::from_parts(3_604_000, 0) + } + pub(crate) fn clear_origin() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 2_599_000 picoseconds. + Weight::from_parts(2_719_000, 0) + } + /// Storage: ParachainInfo ParachainId (r:1 w:0) + /// Proof: ParachainInfo ParachainId (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: PolkadotXcm SupportedVersion (r:1 w:0) + /// Proof Skipped: PolkadotXcm SupportedVersion (max_values: None, max_size: None, mode: Measured) + /// Storage: PolkadotXcm VersionDiscoveryQueue (r:1 w:1) + /// Proof Skipped: PolkadotXcm VersionDiscoveryQueue (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: PolkadotXcm SafeXcmVersion (r:1 w:0) + /// Proof Skipped: PolkadotXcm SafeXcmVersion (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParachainSystem HostConfiguration (r:1 w:0) + /// Proof Skipped: ParachainSystem HostConfiguration (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParachainSystem PendingUpwardMessages (r:1 w:1) + /// Proof Skipped: ParachainSystem PendingUpwardMessages (max_values: Some(1), max_size: None, mode: Measured) + pub(crate) fn report_error() -> Weight { + // Proof Size summary in bytes: + // Measured: `214` + // Estimated: `3679` + // Minimum execution time: 26_327_000 picoseconds. + Weight::from_parts(26_810_000, 3679) + .saturating_add(T::DbWeight::get().reads(6_u64)) + .saturating_add(T::DbWeight::get().writes(2_u64)) + } + /// Storage: PolkadotXcm AssetTraps (r:1 w:1) + /// Proof Skipped: PolkadotXcm AssetTraps (max_values: None, max_size: None, mode: Measured) + pub(crate) fn claim_asset() -> Weight { + // Proof Size summary in bytes: + // Measured: `126` + // Estimated: `3591` + // Minimum execution time: 15_575_000 picoseconds. + Weight::from_parts(15_829_000, 3591) + .saturating_add(T::DbWeight::get().reads(1_u64)) + .saturating_add(T::DbWeight::get().writes(1_u64)) + } + pub(crate) fn trap() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 2_551_000 picoseconds. + Weight::from_parts(2_648_000, 0) + } + /// Storage: PolkadotXcm VersionNotifyTargets (r:1 w:1) + /// Proof Skipped: PolkadotXcm VersionNotifyTargets (max_values: None, max_size: None, mode: Measured) + /// Storage: PolkadotXcm SupportedVersion (r:1 w:0) + /// Proof Skipped: PolkadotXcm SupportedVersion (max_values: None, max_size: None, mode: Measured) + /// Storage: PolkadotXcm VersionDiscoveryQueue (r:1 w:1) + /// Proof Skipped: PolkadotXcm VersionDiscoveryQueue (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: PolkadotXcm SafeXcmVersion (r:1 w:0) + /// Proof Skipped: PolkadotXcm SafeXcmVersion (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParachainSystem HostConfiguration (r:1 w:0) + /// Proof Skipped: ParachainSystem HostConfiguration (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParachainSystem PendingUpwardMessages (r:1 w:1) + /// Proof Skipped: ParachainSystem PendingUpwardMessages (max_values: Some(1), max_size: None, mode: Measured) + pub(crate) fn subscribe_version() -> Weight { + // Proof Size summary in bytes: + // Measured: `111` + // Estimated: `3576` + // Minimum execution time: 26_081_000 picoseconds. + Weight::from_parts(26_533_000, 3576) + .saturating_add(T::DbWeight::get().reads(6_u64)) + .saturating_add(T::DbWeight::get().writes(3_u64)) + } + /// Storage: PolkadotXcm VersionNotifyTargets (r:0 w:1) + /// Proof Skipped: PolkadotXcm VersionNotifyTargets (max_values: None, max_size: None, mode: Measured) + pub(crate) fn unsubscribe_version() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 4_433_000 picoseconds. + Weight::from_parts(4_546_000, 0) + .saturating_add(T::DbWeight::get().writes(1_u64)) + } + /// Storage: ParachainInfo ParachainId (r:1 w:0) + /// Proof: ParachainInfo ParachainId (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: PolkadotXcm SupportedVersion (r:1 w:0) + /// Proof Skipped: PolkadotXcm SupportedVersion (max_values: None, max_size: None, mode: Measured) + /// Storage: PolkadotXcm VersionDiscoveryQueue (r:1 w:1) + /// Proof Skipped: PolkadotXcm VersionDiscoveryQueue (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: PolkadotXcm SafeXcmVersion (r:1 w:0) + /// Proof Skipped: PolkadotXcm SafeXcmVersion (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParachainSystem HostConfiguration (r:1 w:0) + /// Proof Skipped: ParachainSystem HostConfiguration (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParachainSystem PendingUpwardMessages (r:1 w:1) + /// Proof Skipped: ParachainSystem PendingUpwardMessages (max_values: Some(1), max_size: None, mode: Measured) + pub(crate) fn initiate_reserve_withdraw() -> Weight { + // Proof Size summary in bytes: + // Measured: `214` + // Estimated: `3679` + // Minimum execution time: 415_251_000 picoseconds. + Weight::from_parts(417_527_000, 3679) + .saturating_add(T::DbWeight::get().reads(6_u64)) + .saturating_add(T::DbWeight::get().writes(2_u64)) + } + pub(crate) fn burn_asset() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 118_820_000 picoseconds. + Weight::from_parts(121_105_000, 0) + } + pub(crate) fn expect_asset() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 9_352_000 picoseconds. + Weight::from_parts(9_648_000, 0) + } + pub(crate) fn expect_origin() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 2_700_000 picoseconds. + Weight::from_parts(2_789_000, 0) + } + pub(crate) fn expect_error() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 2_552_000 picoseconds. + Weight::from_parts(2_654_000, 0) + } + pub(crate) fn expect_transact_status() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 2_693_000 picoseconds. + Weight::from_parts(2_822_000, 0) + } + /// Storage: ParachainInfo ParachainId (r:1 w:0) + /// Proof: ParachainInfo ParachainId (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: PolkadotXcm SupportedVersion (r:1 w:0) + /// Proof Skipped: PolkadotXcm SupportedVersion (max_values: None, max_size: None, mode: Measured) + /// Storage: PolkadotXcm VersionDiscoveryQueue (r:1 w:1) + /// Proof Skipped: PolkadotXcm VersionDiscoveryQueue (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: PolkadotXcm SafeXcmVersion (r:1 w:0) + /// Proof Skipped: PolkadotXcm SafeXcmVersion (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParachainSystem HostConfiguration (r:1 w:0) + /// Proof Skipped: ParachainSystem HostConfiguration (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParachainSystem PendingUpwardMessages (r:1 w:1) + /// Proof Skipped: ParachainSystem PendingUpwardMessages (max_values: Some(1), max_size: None, mode: Measured) + pub(crate) fn query_pallet() -> Weight { + // Proof Size summary in bytes: + // Measured: `214` + // Estimated: `3679` + // Minimum execution time: 31_400_000 picoseconds. + Weight::from_parts(31_951_000, 3679) + .saturating_add(T::DbWeight::get().reads(6_u64)) + .saturating_add(T::DbWeight::get().writes(2_u64)) + } + pub(crate) fn expect_pallet() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 6_829_000 picoseconds. + Weight::from_parts(6_963_000, 0) + } + /// Storage: ParachainInfo ParachainId (r:1 w:0) + /// Proof: ParachainInfo ParachainId (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + /// Storage: PolkadotXcm SupportedVersion (r:1 w:0) + /// Proof Skipped: PolkadotXcm SupportedVersion (max_values: None, max_size: None, mode: Measured) + /// Storage: PolkadotXcm VersionDiscoveryQueue (r:1 w:1) + /// Proof Skipped: PolkadotXcm VersionDiscoveryQueue (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: PolkadotXcm SafeXcmVersion (r:1 w:0) + /// Proof Skipped: PolkadotXcm SafeXcmVersion (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParachainSystem HostConfiguration (r:1 w:0) + /// Proof Skipped: ParachainSystem HostConfiguration (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: ParachainSystem PendingUpwardMessages (r:1 w:1) + /// Proof Skipped: ParachainSystem PendingUpwardMessages (max_values: Some(1), max_size: None, mode: Measured) + pub(crate) fn report_transact_status() -> Weight { + // Proof Size summary in bytes: + // Measured: `214` + // Estimated: `3679` + // Minimum execution time: 26_405_000 picoseconds. + Weight::from_parts(27_466_000, 3679) + .saturating_add(T::DbWeight::get().reads(6_u64)) + .saturating_add(T::DbWeight::get().writes(2_u64)) + } + pub(crate) fn clear_transact_status() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 2_569_000 picoseconds. + Weight::from_parts(2_691_000, 0) + } + pub(crate) fn set_topic() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 2_542_000 picoseconds. + Weight::from_parts(2_648_000, 0) + } + pub(crate) fn clear_topic() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 2_511_000 picoseconds. + Weight::from_parts(2_634_000, 0) + } + pub(crate) fn set_fees_mode() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 2_519_000 picoseconds. + Weight::from_parts(2_619_000, 0) + } + pub(crate) fn unpaid_execution() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 2_695_000 picoseconds. + Weight::from_parts(2_828_000, 0) + } + /// Storage: Benchmark Override (r:0 w:0) + /// Proof Skipped: Benchmark Override (max_values: None, max_size: None, mode: Measured) + pub(crate) fn exchange_asset() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 18_446_744_073_709_551_000 picoseconds. + Weight::from_parts(18_446_744_073_709_551_000, 0) + } + /// Storage: Benchmark Override (r:0 w:0) + /// Proof Skipped: Benchmark Override (max_values: None, max_size: None, mode: Measured) + pub(crate) fn export_message() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 18_446_744_073_709_551_000 picoseconds. + Weight::from_parts(18_446_744_073_709_551_000, 0) + } + /// Storage: Benchmark Override (r:0 w:0) + /// Proof Skipped: Benchmark Override (max_values: None, max_size: None, mode: Measured) + pub(crate) fn lock_asset() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 18_446_744_073_709_551_000 picoseconds. + Weight::from_parts(18_446_744_073_709_551_000, 0) + } + /// Storage: Benchmark Override (r:0 w:0) + /// Proof Skipped: Benchmark Override (max_values: None, max_size: None, mode: Measured) + pub(crate) fn unlock_asset() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 18_446_744_073_709_551_000 picoseconds. + Weight::from_parts(18_446_744_073_709_551_000, 0) + } + /// Storage: Benchmark Override (r:0 w:0) + /// Proof Skipped: Benchmark Override (max_values: None, max_size: None, mode: Measured) + pub(crate) fn note_unlockable() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 18_446_744_073_709_551_000 picoseconds. + Weight::from_parts(18_446_744_073_709_551_000, 0) + } + /// Storage: Benchmark Override (r:0 w:0) + /// Proof Skipped: Benchmark Override (max_values: None, max_size: None, mode: Measured) + pub(crate) fn request_unlock() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 18_446_744_073_709_551_000 picoseconds. + Weight::from_parts(18_446_744_073_709_551_000, 0) + } + /// Storage: Benchmark Override (r:0 w:0) + /// Proof Skipped: Benchmark Override (max_values: None, max_size: None, mode: Measured) + pub(crate) fn universal_origin() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 18_446_744_073_709_551_000 picoseconds. + Weight::from_parts(18_446_744_073_709_551_000, 0) + } +} diff --git a/runtime/shibuya/src/weights/xcm_instruction_benchmarks/mod.rs b/runtime/shibuya/src/weights/xcm_instruction_benchmarks/mod.rs new file mode 100644 index 0000000000..55fa4dab29 --- /dev/null +++ b/runtime/shibuya/src/weights/xcm_instruction_benchmarks/mod.rs @@ -0,0 +1,277 @@ +// This file is part of Astar. + +// Copyright (C) 2019-2023 Stake Technologies Pte.Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later + +// Astar is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Astar is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Astar. If not, see . + +mod fungible_assets_benchmarks; +mod fungible_balances_benchmarks; +mod generic_benchmarks; + +use crate::Runtime; +use frame_support::weights::Weight; +use sp_std::prelude::*; +use xcm::{ + latest::{prelude::*, Weight as XCMWeight}, + DoubleEncoded, +}; + +use astar_primitives::xcm::MAX_ASSETS; +use core::cmp::min; +use fungible_assets_benchmarks::WeightInfo as XcmFungibleAssetsWeight; +use fungible_balances_benchmarks::WeightInfo as XcmFungibleBalancesWeight; +use generic_benchmarks::WeightInfo as XcmGeneric; + +trait WeighMultiAssets { + fn weigh_multi_assets(&self, weight: Weight) -> XCMWeight; +} + +impl WeighMultiAssets for MultiAssets { + fn weigh_multi_assets(&self, weight: Weight) -> XCMWeight { + weight.saturating_mul(self.inner().into_iter().count() as u64) + } +} + +trait WeighMultiAssetsFilter { + fn weigh_multi_assets_filter(&self, weight: Weight) -> XCMWeight; +} + +impl WeighMultiAssetsFilter for MultiAssetFilter { + fn weigh_multi_assets_filter(&self, weight: Weight) -> XCMWeight { + match self { + Self::Definite(assets) => { + weight.saturating_mul(assets.inner().into_iter().count() as u64) + } + Self::Wild(AllCounted(count) | AllOfCounted { count, .. }) => { + weight.saturating_mul(min(MAX_ASSETS, (*count).into()) as u64) + } + Self::Wild(All | AllOf { .. }) => weight.saturating_mul(MAX_ASSETS as u64), + } + } +} + +pub struct ShibuyaXcmWeight(core::marker::PhantomData); +impl XcmWeightInfo for ShibuyaXcmWeight { + fn withdraw_asset(assets: &MultiAssets) -> XCMWeight { + assets.weigh_multi_assets( + XcmFungibleBalancesWeight::::withdraw_asset() + .max(XcmFungibleAssetsWeight::::withdraw_asset()), + ) + } + fn reserve_asset_deposited(assets: &MultiAssets) -> XCMWeight { + assets.weigh_multi_assets( + XcmFungibleBalancesWeight::::reserve_asset_deposited() + .max(XcmFungibleAssetsWeight::::reserve_asset_deposited()), + ) + } + fn receive_teleported_asset(assets: &MultiAssets) -> XCMWeight { + assets.weigh_multi_assets( + XcmFungibleBalancesWeight::::receive_teleported_asset() + .max(XcmFungibleAssetsWeight::::receive_teleported_asset()), + ) + } + fn query_response( + _query_id: &u64, + _response: &Response, + _max_weight: &Weight, + _querier: &Option, + ) -> XCMWeight { + XcmGeneric::::query_response() + } + fn transfer_asset(assets: &MultiAssets, _dest: &MultiLocation) -> XCMWeight { + assets.weigh_multi_assets( + XcmFungibleBalancesWeight::::transfer_asset() + .max(XcmFungibleAssetsWeight::::transfer_asset()), + ) + } + fn transfer_reserve_asset( + assets: &MultiAssets, + _dest: &MultiLocation, + _xcm: &Xcm<()>, + ) -> XCMWeight { + assets.weigh_multi_assets( + XcmFungibleBalancesWeight::::transfer_reserve_asset() + .max(XcmFungibleAssetsWeight::::transfer_reserve_asset()), + ) + } + fn transact( + _origin_type: &OriginKind, + _require_weight_at_most: &Weight, + _call: &DoubleEncoded, + ) -> XCMWeight { + XcmGeneric::::transact() + } + fn hrmp_new_channel_open_request( + _sender: &u32, + _max_message_size: &u32, + _max_capacity: &u32, + ) -> XCMWeight { + // XCM Executor does not currently support HRMP channel operations + Weight::MAX + } + fn hrmp_channel_accepted(_recipient: &u32) -> XCMWeight { + // XCM Executor does not currently support HRMP channel operations + Weight::MAX + } + fn hrmp_channel_closing(_initiator: &u32, _sender: &u32, _recipient: &u32) -> XCMWeight { + // XCM Executor does not currently support HRMP channel operations + Weight::MAX + } + fn clear_origin() -> XCMWeight { + XcmGeneric::::clear_origin() + } + fn descend_origin(_who: &InteriorMultiLocation) -> XCMWeight { + XcmGeneric::::descend_origin() + } + fn report_error(_query_response_info: &QueryResponseInfo) -> XCMWeight { + XcmGeneric::::report_error() + } + fn deposit_asset(assets: &MultiAssetFilter, _dest: &MultiLocation) -> XCMWeight { + assets.weigh_multi_assets_filter( + XcmFungibleBalancesWeight::::deposit_asset() + .max(XcmFungibleAssetsWeight::::deposit_asset()), + ) + } + fn deposit_reserve_asset( + assets: &MultiAssetFilter, + _dest: &MultiLocation, + _xcm: &Xcm<()>, + ) -> XCMWeight { + assets.weigh_multi_assets_filter( + XcmFungibleBalancesWeight::::deposit_reserve_asset() + .max(XcmFungibleAssetsWeight::::deposit_reserve_asset()), + ) + } + fn exchange_asset( + _give: &MultiAssetFilter, + _receive: &MultiAssets, + _maximal: &bool, + ) -> XCMWeight { + XcmGeneric::::exchange_asset() + } + fn initiate_reserve_withdraw( + _assets: &MultiAssetFilter, + _reserve: &MultiLocation, + _xcm: &Xcm<()>, + ) -> XCMWeight { + XcmGeneric::::initiate_reserve_withdraw() + } + fn initiate_teleport( + _assets: &MultiAssetFilter, + _dest: &MultiLocation, + _xcm: &Xcm<()>, + ) -> XCMWeight { + // max weight + XcmFungibleBalancesWeight::::initiate_teleport() + .max(XcmFungibleAssetsWeight::::initiate_teleport()) + } + fn report_holding(_response_info: &QueryResponseInfo, _assets: &MultiAssetFilter) -> Weight { + XcmGeneric::::report_holding() + } + fn buy_execution(_fees: &MultiAsset, _weight_limit: &WeightLimit) -> XCMWeight { + XcmGeneric::::buy_execution() + } + fn refund_surplus() -> XCMWeight { + XcmGeneric::::refund_surplus() + } + fn set_error_handler(_xcm: &Xcm) -> XCMWeight { + XcmGeneric::::set_error_handler() + } + fn set_appendix(_xcm: &Xcm) -> XCMWeight { + XcmGeneric::::set_appendix() + } + fn clear_error() -> XCMWeight { + XcmGeneric::::clear_error() + } + fn claim_asset(_assets: &MultiAssets, _ticket: &MultiLocation) -> XCMWeight { + XcmGeneric::::claim_asset() + } + fn trap(_code: &u64) -> XCMWeight { + XcmGeneric::::trap() + } + fn subscribe_version(_query_id: &QueryId, _max_response_weight: &Weight) -> XCMWeight { + XcmGeneric::::subscribe_version() + } + fn unsubscribe_version() -> XCMWeight { + XcmGeneric::::unsubscribe_version() + } + fn burn_asset(assets: &MultiAssets) -> Weight { + assets.weigh_multi_assets(XcmGeneric::::burn_asset()) + } + fn expect_asset(assets: &MultiAssets) -> Weight { + assets.weigh_multi_assets(XcmGeneric::::expect_asset()) + } + fn expect_origin(_origin: &Option) -> Weight { + XcmGeneric::::expect_origin() + } + fn expect_error(_error: &Option<(u32, XcmError)>) -> Weight { + XcmGeneric::::expect_error() + } + fn expect_transact_status(_transact_status: &MaybeErrorCode) -> Weight { + XcmGeneric::::expect_transact_status() + } + fn query_pallet(_module_name: &Vec, _response_info: &QueryResponseInfo) -> Weight { + XcmGeneric::::query_pallet() + } + fn expect_pallet( + _index: &u32, + _name: &Vec, + _module_name: &Vec, + _crate_major: &u32, + _min_crate_minor: &u32, + ) -> Weight { + XcmGeneric::::expect_pallet() + } + fn report_transact_status(_response_info: &QueryResponseInfo) -> Weight { + XcmGeneric::::report_transact_status() + } + fn clear_transact_status() -> Weight { + XcmGeneric::::clear_transact_status() + } + fn universal_origin(_: &Junction) -> Weight { + XcmGeneric::::universal_origin() + } + fn export_message(_: &NetworkId, _: &Junctions, _: &Xcm<()>) -> Weight { + XcmGeneric::::export_message() + } + fn lock_asset(_: &MultiAsset, _: &MultiLocation) -> Weight { + XcmGeneric::::lock_asset() + } + fn unlock_asset(_: &MultiAsset, _: &MultiLocation) -> Weight { + XcmGeneric::::unlock_asset() + } + fn note_unlockable(_: &MultiAsset, _: &MultiLocation) -> Weight { + XcmGeneric::::note_unlockable() + } + fn request_unlock(_: &MultiAsset, _: &MultiLocation) -> Weight { + XcmGeneric::::request_unlock() + } + fn set_fees_mode(_: &bool) -> Weight { + XcmGeneric::::set_fees_mode() + } + fn set_topic(_topic: &[u8; 32]) -> Weight { + XcmGeneric::::set_topic() + } + fn clear_topic() -> Weight { + XcmGeneric::::clear_topic() + } + fn alias_origin(_: &MultiLocation) -> Weight { + // XCM Executor does not currently support alias origin operations + Weight::MAX + } + fn unpaid_execution(_: &WeightLimit, _: &Option) -> Weight { + XcmGeneric::::unpaid_execution() + } +} diff --git a/runtime/shibuya/src/xcm_config.rs b/runtime/shibuya/src/xcm_config.rs index 32c66e08af..3df22afd3c 100644 --- a/runtime/shibuya/src/xcm_config.rs +++ b/runtime/shibuya/src/xcm_config.rs @@ -35,10 +35,10 @@ use xcm::latest::prelude::*; use xcm_builder::{ AccountId32Aliases, AllowKnownQueryResponses, AllowSubscriptionsFrom, AllowTopLevelPaidExecutionFrom, AllowUnpaidExecutionFrom, ConvertedConcreteId, CurrencyAdapter, - EnsureXcmOrigin, FixedWeightBounds, FungiblesAdapter, IsConcrete, NoChecking, - ParentAsSuperuser, ParentIsPreset, RelayChainAsNative, SiblingParachainAsNative, - SiblingParachainConvertsVia, SignedAccountId32AsNative, SignedToAccountId32, - SovereignSignedViaLocation, TakeWeightCredit, UsingComponents, WithComputedOrigin, + EnsureXcmOrigin, FungiblesAdapter, IsConcrete, NoChecking, ParentAsSuperuser, ParentIsPreset, + RelayChainAsNative, SiblingParachainAsNative, SiblingParachainConvertsVia, + SignedAccountId32AsNative, SignedToAccountId32, SovereignSignedViaLocation, TakeWeightCredit, + UsingComponents, WeightInfoBounds, WithComputedOrigin, }; use xcm_executor::{ traits::{Convert as XcmConvert, JustTry}, @@ -171,7 +171,11 @@ pub type ShibuyaXcmFungibleFeeHandler = XcmFungibleFeeHandler< TreasuryAccountId, >; -pub type Weigher = FixedWeightBounds; +pub type Weigher = WeightInfoBounds< + crate::weights::xcm_instruction_benchmarks::ShibuyaXcmWeight, + RuntimeCall, + MaxInstructions, +>; pub struct XcmConfig; impl xcm_executor::Config for XcmConfig {