From 7c2eac2b9dd24c2a50eba53cdd6670bba2f51f8c Mon Sep 17 00:00:00 2001 From: R0GUE Date: Fri, 5 Apr 2024 17:58:06 +0200 Subject: [PATCH 001/112] feat: pallet assets pop api integration --- Cargo.lock | 312 +++++------ .../examples/trust_backed_assets/.gitignore | 9 + .../examples/trust_backed_assets/Cargo.toml | 25 + pop-api/examples/trust_backed_assets/lib.rs | 69 +++ pop-api/src/lib.rs | 6 +- pop-api/src/v0/assets/mod.rs | 1 + pop-api/src/v0/assets/trust_backed.rs | 519 ++++++++++++++++++ pop-api/src/v0/mod.rs | 3 + pop-api/src/v0/nfts.rs | 2 +- primitives/src/lib.rs | 6 +- primitives/src/storage_keys.rs | 7 + runtime/devnet/src/config/assets.rs | 16 +- runtime/devnet/src/extensions.rs | 139 ++++- runtime/devnet/src/lib.rs | 103 ++-- runtime/testnet/src/config/assets.rs | 16 +- runtime/testnet/src/extensions.rs | 150 ++++- runtime/testnet/src/lib.rs | 103 ++-- 17 files changed, 1221 insertions(+), 265 deletions(-) create mode 100755 pop-api/examples/trust_backed_assets/.gitignore create mode 100755 pop-api/examples/trust_backed_assets/Cargo.toml create mode 100755 pop-api/examples/trust_backed_assets/lib.rs create mode 100644 pop-api/src/v0/assets/mod.rs create mode 100644 pop-api/src/v0/assets/trust_backed.rs diff --git a/Cargo.lock b/Cargo.lock index 4dc89da6..e43d2b18 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -214,7 +214,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.55", + "syn 2.0.58", ] [[package]] @@ -578,16 +578,16 @@ checksum = "f28243a43d821d11341ab73c80bed182dc015c514b951616cf79bd4af39af0c3" dependencies = [ "concurrent-queue", "event-listener 5.2.0", - "event-listener-strategy 0.5.0", + "event-listener-strategy 0.5.1", "futures-core", - "pin-project-lite 0.2.13", + "pin-project-lite 0.2.14", ] [[package]] name = "async-executor" -version = "1.8.0" +version = "1.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17ae5ebefcc48e7452b4987947920dac9450be1110cadf34d1b8c116bdbaf97c" +checksum = "10b3e585719c2358d2660232671ca8ca4ddb4be4ce8a1842d6c2dc8685303316" dependencies = [ "async-lock 3.3.0", "async-task", @@ -676,7 +676,7 @@ checksum = "d034b430882f8381900d3fe6f0aaa3ad94f2cb4ac519b429692a1bc2dda4ae7b" dependencies = [ "event-listener 4.0.3", "event-listener-strategy 0.4.0", - "pin-project-lite 0.2.13", + "pin-project-lite 0.2.14", ] [[package]] @@ -768,7 +768,7 @@ checksum = "a507401cad91ec6a857ed5513a2073c82a9b9048762b885bb98655b306964681" dependencies = [ "proc-macro2", "quote", - "syn 2.0.55", + "syn 2.0.58", ] [[package]] @@ -781,7 +781,7 @@ dependencies = [ "futures-sink", "futures-util", "memchr", - "pin-project-lite 0.2.13", + "pin-project-lite 0.2.14", ] [[package]] @@ -899,7 +899,7 @@ dependencies = [ "regex", "rustc-hash", "shlex", - "syn 2.0.55", + "syn 2.0.58", ] [[package]] @@ -1526,9 +1526,9 @@ dependencies = [ [[package]] name = "chrono" -version = "0.4.35" +version = "0.4.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8eaf5903dcbc0a39312feb77df2ff4c76387d591b9fc7b04a238dcf8bb62639a" +checksum = "8a0d04d43504c61aa6c7531f1871dd0d418d91130162063b789da00fd7057a5e" dependencies = [ "android-tzdata", "iana-time-zone", @@ -1610,7 +1610,7 @@ dependencies = [ "anstream", "anstyle", "clap_lex", - "strsim 0.11.0", + "strsim 0.11.1", "terminal_size", ] @@ -1623,7 +1623,7 @@ dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.55", + "syn 2.0.58", ] [[package]] @@ -2337,7 +2337,7 @@ dependencies = [ "proc-macro-crate 3.1.0", "proc-macro2", "quote", - "syn 2.0.55", + "syn 2.0.58", ] [[package]] @@ -2658,7 +2658,7 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.55", + "syn 2.0.58", ] [[package]] @@ -2698,7 +2698,7 @@ dependencies = [ "proc-macro2", "quote", "scratch", - "syn 2.0.55", + "syn 2.0.58", ] [[package]] @@ -2715,7 +2715,7 @@ checksum = "b404f596046b0bb2d903a9c786b875a126261b52b7c3a64bbb66382c41c771df" dependencies = [ "proc-macro2", "quote", - "syn 2.0.55", + "syn 2.0.58", ] [[package]] @@ -2763,7 +2763,7 @@ dependencies = [ "proc-macro2", "quote", "strsim 0.10.0", - "syn 2.0.55", + "syn 2.0.58", ] [[package]] @@ -2785,7 +2785,7 @@ checksum = "a668eda54683121533a393014d8692171709ff57a7d61f187b6e782719f8933f" dependencies = [ "darling_core 0.20.8", "quote", - "syn 2.0.55", + "syn 2.0.58", ] [[package]] @@ -2816,9 +2816,9 @@ dependencies = [ [[package]] name = "der" -version = "0.7.8" +version = "0.7.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fffa369a668c8af7dbf8b5e56c9f744fbd399949ed171606040001947de40b1c" +checksum = "f55bf8e7b65898637379c1b74eb1551107c8294ed26d855ceb9fd1a09cfc9bc0" dependencies = [ "const-oid", "zeroize", @@ -2869,6 +2869,17 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "derive-syn-parse" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d65d7ce8132b7c0e54497a4d9a55a1c2a0912a0d786cf894472ba818fba45762" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.58", +] + [[package]] name = "derive_more" version = "0.99.17" @@ -2968,31 +2979,31 @@ checksum = "487585f4d0c6655fe74905e2504d8ad6908e4db67f744eb140876906c2f3175d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.55", + "syn 2.0.58", ] [[package]] name = "docify" -version = "0.2.7" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cc4fd38aaa9fb98ac70794c82a00360d1e165a87fbf96a8a91f9dfc602aaee2" +checksum = "43a2f138ad521dc4a2ced1a4576148a6a610b4c5923933b062a263130a6802ce" dependencies = [ "docify_macros", ] [[package]] name = "docify_macros" -version = "0.2.7" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63fa215f3a0d40fb2a221b3aa90d8e1fbb8379785a990cb60d62ac71ebdc6460" +checksum = "1a081e51fb188742f5a7a1164ad752121abcb22874b21e2c3b0dd040c515fdad" dependencies = [ "common-path", - "derive-syn-parse", + "derive-syn-parse 0.2.0", "once_cell", "proc-macro2", "quote", "regex", - "syn 2.0.55", + "syn 2.0.58", "termcolor", "toml 0.8.12", "walkdir", @@ -3204,7 +3215,7 @@ checksum = "5c785274071b1b420972453b306eeca06acf4633829db4223b58a2a8c5953bc4" dependencies = [ "proc-macro2", "quote", - "syn 2.0.55", + "syn 2.0.58", ] [[package]] @@ -3215,7 +3226,7 @@ checksum = "6fd000fd6988e73bbe993ea3db9b1aa64906ab88766d654973924340c8cddb42" dependencies = [ "proc-macro2", "quote", - "syn 2.0.55", + "syn 2.0.58", ] [[package]] @@ -3331,7 +3342,7 @@ checksum = "d93877bcde0eb80ca09131a08d23f0a5c18a620b01db137dba666d18cd9b30c2" dependencies = [ "concurrent-queue", "parking", - "pin-project-lite 0.2.13", + "pin-project-lite 0.2.14", ] [[package]] @@ -3342,7 +3353,7 @@ checksum = "67b215c49b2b248c855fb73579eb1f4f26c38ffdc12973e20e07b91d78d5646e" dependencies = [ "concurrent-queue", "parking", - "pin-project-lite 0.2.13", + "pin-project-lite 0.2.14", ] [[package]] @@ -3353,7 +3364,7 @@ checksum = "2b5fb89194fa3cad959b833185b3063ba881dbfc7030680b314250779fb4cc91" dependencies = [ "concurrent-queue", "parking", - "pin-project-lite 0.2.13", + "pin-project-lite 0.2.14", ] [[package]] @@ -3363,17 +3374,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "958e4d70b6d5e81971bebec42271ec641e7ff4e170a6fa605f2b8a8b65cb97d3" dependencies = [ "event-listener 4.0.3", - "pin-project-lite 0.2.13", + "pin-project-lite 0.2.14", ] [[package]] name = "event-listener-strategy" -version = "0.5.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "feedafcaa9b749175d5ac357452a9d41ea2911da598fde46ce1fe02c37751291" +checksum = "332f51cb23d20b0de8458b86580878211da09bcd4503cb579c225b3d124cabb3" dependencies = [ "event-listener 5.2.0", - "pin-project-lite 0.2.13", + "pin-project-lite 0.2.14", ] [[package]] @@ -3408,7 +3419,7 @@ dependencies = [ "prettier-please", "proc-macro2", "quote", - "syn 2.0.55", + "syn 2.0.58", ] [[package]] @@ -3673,7 +3684,7 @@ dependencies = [ "proc-macro-crate 3.1.0", "proc-macro2", "quote", - "syn 2.0.55", + "syn 2.0.58", ] [[package]] @@ -3761,9 +3772,9 @@ dependencies = [ [[package]] name = "frame-support" -version = "29.0.0" +version = "29.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3b24824d29c43d0af94be3356bbf30338ededed649f6841d315a9ae067ce872" +checksum = "b8e52c84b611d2049d9253f83a62ab0f093e4be5c42a7ef42ea5bb16d6611e32" dependencies = [ "aquamarine", "array-bytes 6.2.2", @@ -3809,7 +3820,7 @@ checksum = "3bf1d648c4007d421b9677b3c893256913498fff159dc2d85022cdd9cc432f3c" dependencies = [ "Inflector", "cfg-expr", - "derive-syn-parse", + "derive-syn-parse 0.1.5", "expander 2.1.0", "frame-support-procedural-tools", "itertools 0.10.5", @@ -3818,7 +3829,7 @@ dependencies = [ "proc-macro2", "quote", "sp-crypto-hashing", - "syn 2.0.55", + "syn 2.0.58", ] [[package]] @@ -3831,7 +3842,7 @@ dependencies = [ "proc-macro-crate 3.1.0", "proc-macro2", "quote", - "syn 2.0.55", + "syn 2.0.58", ] [[package]] @@ -3842,7 +3853,7 @@ checksum = "68672b9ec6fe72d259d3879dc212c5e42e977588cdac830c76f54d9f492aeb58" dependencies = [ "proc-macro2", "quote", - "syn 2.0.55", + "syn 2.0.58", ] [[package]] @@ -4010,7 +4021,7 @@ dependencies = [ "futures-io", "memchr", "parking", - "pin-project-lite 0.2.13", + "pin-project-lite 0.2.14", "waker-fn", ] @@ -4024,7 +4035,7 @@ dependencies = [ "futures-core", "futures-io", "parking", - "pin-project-lite 0.2.13", + "pin-project-lite 0.2.14", ] [[package]] @@ -4035,7 +4046,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn 2.0.55", + "syn 2.0.58", ] [[package]] @@ -4080,7 +4091,7 @@ dependencies = [ "futures-sink", "futures-task", "memchr", - "pin-project-lite 0.2.13", + "pin-project-lite 0.2.14", "pin-utils", "slab", ] @@ -4404,7 +4415,7 @@ checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" dependencies = [ "bytes", "http", - "pin-project-lite 0.2.13", + "pin-project-lite 0.2.14", ] [[package]] @@ -4447,8 +4458,8 @@ dependencies = [ "httparse", "httpdate", "itoa", - "pin-project-lite 0.2.13", - "socket2 0.4.10", + "pin-project-lite 0.2.14", + "socket2 0.5.6", "tokio", "tower-service", "tracing", @@ -4806,9 +4817,9 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.10" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" +checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" [[package]] name = "jobserver" @@ -5125,9 +5136,9 @@ dependencies = [ [[package]] name = "landlock" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1530c5b973eeed4ac216af7e24baf5737645a6272e361f1fb95710678b67d9cc" +checksum = "9baa9eeb6e315942429397e617a190f4fdc696ef1ee0342939d641029cbb4ea7" dependencies = [ "enumflags2", "libc", @@ -5563,13 +5574,12 @@ dependencies = [ [[package]] name = "libredox" -version = "0.0.1" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85c833ca1e66078851dba29046874e38f08b2c883700aa29a03ddd3b23814ee8" +checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" dependencies = [ "bitflags 2.5.0", "libc", - "redox_syscall 0.4.1", ] [[package]] @@ -5805,7 +5815,7 @@ dependencies = [ "macro_magic_core", "macro_magic_macros", "quote", - "syn 2.0.55", + "syn 2.0.58", ] [[package]] @@ -5815,11 +5825,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "468155613a44cfd825f1fb0ffa532b018253920d404e6fca1e8d43155198a46d" dependencies = [ "const-random", - "derive-syn-parse", + "derive-syn-parse 0.1.5", "macro_magic_core_macros", "proc-macro2", "quote", - "syn 2.0.55", + "syn 2.0.58", ] [[package]] @@ -5830,7 +5840,7 @@ checksum = "9ea73aa640dc01d62a590d48c0c3521ed739d53b27f919b25c3551e233481654" dependencies = [ "proc-macro2", "quote", - "syn 2.0.55", + "syn 2.0.58", ] [[package]] @@ -5841,7 +5851,7 @@ checksum = "ef9d79ae96aaba821963320eb2b6e34d17df1e5a83d8a1985c29cc5be59577b3" dependencies = [ "macro_magic_core", "quote", - "syn 2.0.55", + "syn 2.0.58", ] [[package]] @@ -5892,9 +5902,9 @@ dependencies = [ [[package]] name = "memchr" -version = "2.7.1" +version = "2.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" +checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d" [[package]] name = "memfd" @@ -6229,9 +6239,9 @@ dependencies = [ [[package]] name = "nalgebra" -version = "0.32.4" +version = "0.32.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4541eb06dce09c0241ebbaab7102f0a01a0c8994afed2e5d0d66775016e25ac2" +checksum = "3ea4908d4f23254adda3daa60ffef0f1ac7b8c3e9a864cf3cc154b251908a2ef" dependencies = [ "approx", "matrixmultiply", @@ -6324,9 +6334,9 @@ dependencies = [ [[package]] name = "netlink-sys" -version = "0.8.5" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6471bf08e7ac0135876a9581bf3217ef0333c191c128d34878079f42ee150411" +checksum = "416060d346fbaf1f23f9512963e3e878f1a78e707cb699ba9215761754244307" dependencies = [ "bytes", "futures", @@ -6763,9 +6773,9 @@ dependencies = [ [[package]] name = "pallet-balances" -version = "29.0.0" +version = "29.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "942007f4f7aace74b77009db1675e7ca98683a42dde5e2d85bba2a9f404d2e5a" +checksum = "e27946a57494d7c6231ae8909275bbd3cb5460ee3d27b7a5774a8b8e64d3ab92" dependencies = [ "docify", "frame-benchmarking", @@ -7045,7 +7055,7 @@ checksum = "3163c6bc21b55a0ccb74c546ba784d9c9e69beb9240c059d28a3052f4cbce509" dependencies = [ "proc-macro2", "quote", - "syn 2.0.55", + "syn 2.0.58", ] [[package]] @@ -7682,9 +7692,9 @@ dependencies = [ [[package]] name = "pallet-staking" -version = "29.0.0" +version = "29.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a94127295cf027a26e933ea6788b0824e9fedd90740013673e2d36b5d707efe" +checksum = "668b7d28c499f0d9f295fad26cf6c342472e21842e3b13bcaaac8536358b2d6c" dependencies = [ "frame-benchmarking", "frame-election-provider-support", @@ -7713,7 +7723,7 @@ dependencies = [ "proc-macro-crate 3.1.0", "proc-macro2", "quote", - "syn 2.0.55", + "syn 2.0.58", ] [[package]] @@ -8274,9 +8284,9 @@ checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "pest" -version = "2.7.8" +version = "2.7.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56f8023d0fb78c8e03784ea1c7f3fa36e68a723138990b8d5a47d916b651e7a8" +checksum = "311fb059dee1a7b802f036316d790138c613a4e8b180c822e3925a662e9f0c95" dependencies = [ "memchr", "thiserror", @@ -8285,9 +8295,9 @@ dependencies = [ [[package]] name = "pest_derive" -version = "2.7.8" +version = "2.7.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0d24f72393fd16ab6ac5738bc33cdb6a9aa73f8b902e8fe29cf4e67d7dd1026" +checksum = "f73541b156d32197eecda1a4014d7f868fd2bcb3c550d5386087cfba442bf69c" dependencies = [ "pest", "pest_generator", @@ -8295,22 +8305,22 @@ dependencies = [ [[package]] name = "pest_generator" -version = "2.7.8" +version = "2.7.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdc17e2a6c7d0a492f0158d7a4bd66cc17280308bbaff78d5bef566dca35ab80" +checksum = "c35eeed0a3fab112f75165fdc026b3913f4183133f19b49be773ac9ea966e8bd" dependencies = [ "pest", "pest_meta", "proc-macro2", "quote", - "syn 2.0.55", + "syn 2.0.58", ] [[package]] name = "pest_meta" -version = "2.7.8" +version = "2.7.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "934cd7631c050f4674352a6e835d5f6711ffbfb9345c2fc0107155ac495ae293" +checksum = "2adbf29bb9776f28caece835398781ab24435585fe0d4dc1374a61db5accedca" dependencies = [ "once_cell", "pest", @@ -8344,7 +8354,7 @@ checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" dependencies = [ "proc-macro2", "quote", - "syn 2.0.55", + "syn 2.0.58", ] [[package]] @@ -8355,9 +8365,9 @@ checksum = "257b64915a082f7811703966789728173279bdebb956b143dbcd23f6f970a777" [[package]] name = "pin-project-lite" -version = "0.2.13" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" +checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" [[package]] name = "pin-utils" @@ -8394,9 +8404,9 @@ checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" [[package]] name = "platforms" -version = "3.3.0" +version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "626dec3cac7cc0e1577a2ec3fc496277ec2baa084bebad95bb6fdbfae235f84c" +checksum = "db23d408679286588f4d4644f965003d056e3dd5abcaaa938116871d7ce2fee7" [[package]] name = "polkadot-approval-distribution" @@ -9524,7 +9534,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6380dbe1fb03ecc74ad55d841cfc75480222d153ba69ddcb00977866cbdabdb8" dependencies = [ "polkavm-derive-impl", - "syn 2.0.55", + "syn 2.0.58", ] [[package]] @@ -9536,7 +9546,7 @@ dependencies = [ "polkavm-common", "proc-macro2", "quote", - "syn 2.0.55", + "syn 2.0.58", ] [[package]] @@ -9551,7 +9561,7 @@ dependencies = [ "concurrent-queue", "libc", "log", - "pin-project-lite 0.2.13", + "pin-project-lite 0.2.14", "windows-sys 0.48.0", ] @@ -9564,7 +9574,7 @@ dependencies = [ "cfg-if", "concurrent-queue", "hermit-abi", - "pin-project-lite 0.2.13", + "pin-project-lite 0.2.14", "rustix 0.38.32", "tracing", "windows-sys 0.52.0", @@ -9710,19 +9720,16 @@ dependencies = [ "pallet-collator-selection", "pallet-contracts", "pallet-message-queue", - "pallet-multisig", "pallet-nft-fractionalization", "pallet-nfts", "pallet-nfts-runtime-api", "pallet-preimage", - "pallet-proxy", "pallet-scheduler", "pallet-session", "pallet-sudo", "pallet-timestamp", "pallet-transaction-payment", "pallet-transaction-payment-rpc-runtime-api", - "pallet-utility", "pallet-xcm", "parachains-common", "parity-scale-codec", @@ -9783,19 +9790,16 @@ dependencies = [ "pallet-collator-selection", "pallet-contracts", "pallet-message-queue", - "pallet-multisig", "pallet-nft-fractionalization", "pallet-nfts", "pallet-nfts-runtime-api", "pallet-preimage", - "pallet-proxy", "pallet-scheduler", "pallet-session", "pallet-sudo", "pallet-timestamp", "pallet-transaction-payment", "pallet-transaction-payment-rpc-runtime-api", - "pallet-utility", "pallet-xcm", "parachains-common", "parity-scale-codec", @@ -9880,7 +9884,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "22020dfcf177fcc7bf5deaf7440af371400c67c0de14c399938d8ed4fb4645d3" dependencies = [ "proc-macro2", - "syn 2.0.55", + "syn 2.0.58", ] [[package]] @@ -9900,7 +9904,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8d3928fb5db768cb86f891ff014f0144589297e3c6a1aba6ed7cecfdace270c7" dependencies = [ "proc-macro2", - "syn 2.0.55", + "syn 2.0.58", ] [[package]] @@ -9994,7 +9998,7 @@ checksum = "834da187cfe638ae8abb0203f0b33e5ccdb02a28e7199f2f47b3e2754f50edca" dependencies = [ "proc-macro2", "quote", - "syn 2.0.55", + "syn 2.0.58", ] [[package]] @@ -10040,7 +10044,7 @@ checksum = "440f724eba9f6996b75d63681b0a92b06947f1457076d503a4d2e2c8f56442b8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.55", + "syn 2.0.58", ] [[package]] @@ -10108,7 +10112,7 @@ dependencies = [ "itertools 0.11.0", "proc-macro2", "quote", - "syn 2.0.55", + "syn 2.0.58", ] [[package]] @@ -10327,9 +10331,9 @@ dependencies = [ [[package]] name = "redox_users" -version = "0.4.4" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a18479200779601e498ada4e8c1e1f50e3ee19deb0259c25825a98b5603b2cb4" +checksum = "bd283d9651eeda4b2a83a43c1c91b266c40fd76ecd39a50a8c630ae69dc72891" dependencies = [ "getrandom 0.2.12", "libredox", @@ -10365,7 +10369,7 @@ checksum = "5fddb4f8d99b0a2ebafc65a87a69a7b9875e4b1ae1f00db265d300ef7f28bccc" dependencies = [ "proc-macro2", "quote", - "syn 2.0.55", + "syn 2.0.58", ] [[package]] @@ -10389,7 +10393,7 @@ dependencies = [ "aho-corasick", "memchr", "regex-automata 0.4.6", - "regex-syntax 0.8.2", + "regex-syntax 0.8.3", ] [[package]] @@ -10409,7 +10413,7 @@ checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea" dependencies = [ "aho-corasick", "memchr", - "regex-syntax 0.8.2", + "regex-syntax 0.8.3", ] [[package]] @@ -10420,9 +10424,9 @@ checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" [[package]] name = "regex-syntax" -version = "0.8.2" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" +checksum = "adad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56" [[package]] name = "resolv-conf" @@ -11025,7 +11029,7 @@ dependencies = [ "proc-macro-crate 3.1.0", "proc-macro2", "quote", - "syn 2.0.55", + "syn 2.0.58", ] [[package]] @@ -12039,7 +12043,7 @@ dependencies = [ "proc-macro-crate 3.1.0", "proc-macro2", "quote", - "syn 2.0.55", + "syn 2.0.58", ] [[package]] @@ -12205,7 +12209,7 @@ dependencies = [ "proc-macro2", "quote", "scale-info", - "syn 2.0.55", + "syn 2.0.58", "thiserror", ] @@ -12358,9 +12362,9 @@ dependencies = [ [[package]] name = "security-framework" -version = "2.9.2" +version = "2.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05b64fb303737d99b81884b2c63433e9ae28abebe5eb5045dcdd175dc2ecf4de" +checksum = "770452e37cad93e0a50d5abc3990d2bc351c36d0328f86cefec2f2fb206eaef6" dependencies = [ "bitflags 1.3.2", "core-foundation", @@ -12371,9 +12375,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.9.1" +version = "2.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e932934257d3b408ed8f30db49d85ea163bfe74961f017f405b025af298f0c7a" +checksum = "41f3cc463c0ef97e11c3461a9d3787412d30e8e7eb907c79180c4a57bf7c04ef" dependencies = [ "core-foundation-sys", "libc", @@ -12438,14 +12442,14 @@ checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.55", + "syn 2.0.58", ] [[package]] name = "serde_json" -version = "1.0.114" +version = "1.0.115" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5f09b1bd632ef549eaa9f60a1f8de742bdbc698e6cee2095fc84dde5f549ae0" +checksum = "12dc5c46daa8e9fdf4f5e71b6cf9a53f2487da0e86e55808e2d35539666497dd" dependencies = [ "itoa", "ryu", @@ -13057,7 +13061,7 @@ dependencies = [ "proc-macro-crate 3.1.0", "proc-macro2", "quote", - "syn 2.0.55", + "syn 2.0.58", ] [[package]] @@ -13323,7 +13327,7 @@ checksum = "b85d0f1f1e44bd8617eb2a48203ee854981229e3e79e6f468c7175d5fd37489b" dependencies = [ "quote", "sp-crypto-hashing", - "syn 2.0.55", + "syn 2.0.58", ] [[package]] @@ -13344,7 +13348,7 @@ checksum = "48d09fa0a5f7299fb81ee25ae3853d26200f7a348148aed6de76be905c007dbe" dependencies = [ "proc-macro2", "quote", - "syn 2.0.55", + "syn 2.0.58", ] [[package]] @@ -13593,7 +13597,7 @@ dependencies = [ "proc-macro-crate 3.1.0", "proc-macro2", "quote", - "syn 2.0.55", + "syn 2.0.58", ] [[package]] @@ -13800,7 +13804,7 @@ dependencies = [ "parity-scale-codec", "proc-macro2", "quote", - "syn 2.0.55", + "syn 2.0.58", ] [[package]] @@ -14044,9 +14048,9 @@ checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" [[package]] name = "strsim" -version = "0.11.0" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ee073c9e4cd00e28217186dbe12796d692868f432bf2e97ee73bed0c56dfa01" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "strum" @@ -14086,7 +14090,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.55", + "syn 2.0.58", ] [[package]] @@ -14262,7 +14266,7 @@ dependencies = [ "scale-info", "scale-typegen", "subxt-metadata", - "syn 2.0.55", + "syn 2.0.58", "thiserror", "tokio", ] @@ -14296,7 +14300,7 @@ dependencies = [ "quote", "scale-typegen", "subxt-codegen", - "syn 2.0.55", + "syn 2.0.58", ] [[package]] @@ -14347,9 +14351,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.55" +version = "2.0.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "002a1b3dbf967edfafc32655d0f377ab0bb7b994aa1d32c8cc7e9b8bf3ebb8f0" +checksum = "44cfb93f38070beee36b3fef7d4f5a16f27751d94b187b666a5cc5e9b0d30687" dependencies = [ "proc-macro2", "quote", @@ -14479,7 +14483,7 @@ checksum = "e4c60d69f36615a077cc7663b9cb8e42275722d23e58a7fa3d2c7f2915d09d04" dependencies = [ "proc-macro2", "quote", - "syn 2.0.55", + "syn 2.0.58", ] [[package]] @@ -14490,7 +14494,7 @@ checksum = "c61f3ba182994efc43764a46c018c347bc492c79f024e705f46567b418f6d4f7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.55", + "syn 2.0.58", ] [[package]] @@ -14619,7 +14623,7 @@ dependencies = [ "mio", "num_cpus", "parking_lot 0.12.1", - "pin-project-lite 0.2.13", + "pin-project-lite 0.2.14", "signal-hook-registry", "socket2 0.5.6", "tokio-macros", @@ -14634,7 +14638,7 @@ checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.55", + "syn 2.0.58", ] [[package]] @@ -14676,7 +14680,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "267ac89e0bec6e691e5813911606935d77c476ff49024f98abcea3e7b15e37af" dependencies = [ "futures-core", - "pin-project-lite 0.2.13", + "pin-project-lite 0.2.14", "tokio", "tokio-util", ] @@ -14691,7 +14695,7 @@ dependencies = [ "futures-core", "futures-io", "futures-sink", - "pin-project-lite 0.2.13", + "pin-project-lite 0.2.14", "tokio", "tracing", ] @@ -14781,7 +14785,7 @@ dependencies = [ "futures-core", "futures-util", "pin-project", - "pin-project-lite 0.2.13", + "pin-project-lite 0.2.14", "tower-layer", "tower-service", "tracing", @@ -14800,7 +14804,7 @@ dependencies = [ "http", "http-body", "http-range-header", - "pin-project-lite 0.2.13", + "pin-project-lite 0.2.14", "tower-layer", "tower-service", ] @@ -14824,7 +14828,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" dependencies = [ "log", - "pin-project-lite 0.2.13", + "pin-project-lite 0.2.14", "tracing-attributes", "tracing-core", ] @@ -14837,7 +14841,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.55", + "syn 2.0.58", ] [[package]] @@ -14882,7 +14886,7 @@ dependencies = [ "proc-macro-crate 3.1.0", "proc-macro2", "quote", - "syn 2.0.55", + "syn 2.0.58", ] [[package]] @@ -15308,7 +15312,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.55", + "syn 2.0.58", "wasm-bindgen-shared", ] @@ -15342,7 +15346,7 @@ checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.55", + "syn 2.0.58", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -15364,9 +15368,9 @@ dependencies = [ [[package]] name = "wasm-opt" -version = "0.116.0" +version = "0.116.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc942673e7684671f0c5708fc18993569d184265fd5223bb51fc8e5b9b6cfd52" +checksum = "2fd87a4c135535ffed86123b6fb0f0a5a0bc89e50416c942c5f0662c645f679c" dependencies = [ "anyhow", "libc", @@ -16222,7 +16226,7 @@ dependencies = [ "Inflector", "proc-macro2", "quote", - "syn 2.0.55", + "syn 2.0.58", ] [[package]] @@ -16271,7 +16275,7 @@ checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.55", + "syn 2.0.58", ] [[package]] @@ -16291,7 +16295,7 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.55", + "syn 2.0.58", ] [[package]] @@ -16334,9 +16338,9 @@ dependencies = [ [[package]] name = "zstd-sys" -version = "2.0.9+zstd.1.5.5" +version = "2.0.10+zstd.1.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e16efa8a874a0481a574084d34cc26fdb3b99627480f785888deb6386506656" +checksum = "c253a4914af5bafc8fa8c86ee400827e83cf6ec01195ec1f1ed8441bf00d65aa" dependencies = [ "cc", "pkg-config", diff --git a/pop-api/examples/trust_backed_assets/.gitignore b/pop-api/examples/trust_backed_assets/.gitignore new file mode 100755 index 00000000..8de8f877 --- /dev/null +++ b/pop-api/examples/trust_backed_assets/.gitignore @@ -0,0 +1,9 @@ +# Ignore build artifacts from the local tests sub-crate. +/target/ + +# Ignore backup files creates by cargo fmt. +**/*.rs.bk + +# Remove Cargo.lock when creating an executable, leave it for libraries +# More information here http://doc.crates.io/guide.html#cargotoml-vs-cargolock +Cargo.lock diff --git a/pop-api/examples/trust_backed_assets/Cargo.toml b/pop-api/examples/trust_backed_assets/Cargo.toml new file mode 100755 index 00000000..3c3716fc --- /dev/null +++ b/pop-api/examples/trust_backed_assets/Cargo.toml @@ -0,0 +1,25 @@ +[package] +name = "pop_api_trust_backed_assets_example" +version = "0.1.0" +authors = ["[your_name] <[your_email]>"] +edition = "2021" + +[dependencies] +ink = { version = "5.0.0", default-features = false } +pop-api = { path = "../../../pop-api", default-features = false } +scale = { package = "parity-scale-codec", version = "3", default-features = false, features = ["derive"] } +scale-info = { version = "2.6", default-features = false, features = ["derive"], optional = true } + +[lib] +path = "lib.rs" + +[features] +default = ["std"] +std = [ + "ink/std", + "pop-api/std", + "scale/std", + "scale-info/std", +] +ink-as-dependency = [] +e2e-tests = [] diff --git a/pop-api/examples/trust_backed_assets/lib.rs b/pop-api/examples/trust_backed_assets/lib.rs new file mode 100755 index 00000000..8b2fbda6 --- /dev/null +++ b/pop-api/examples/trust_backed_assets/lib.rs @@ -0,0 +1,69 @@ +#![cfg_attr(not(feature = "std"), no_std, no_main)] + +use pop_api::assets::trust_backed as trust_backed_assets; + +#[derive(Debug, Copy, Clone, PartialEq, Eq, scale::Encode, scale::Decode)] +#[cfg_attr(feature = "std", derive(scale_info::TypeInfo))] +pub enum ContractError { + TrustBackedAssetsError(trust_backed_assets::Error), + UnknownAsset, +} + +impl From for ContractError { + fn from(value: trust_backed_assets::Error) -> Self { + ContractError::TrustBackedAssetsError(value) + } +} + +#[ink::contract(env = pop_api::Environment)] +mod pop_api_extension_demo { + use super::*; + + #[ink(storage)] + #[derive(Default)] + pub struct PopApiExtensionDemo; + + impl PopApiExtensionDemo { + #[ink(constructor, payable)] + pub fn new() -> Self { + ink::env::debug_println!("Contract::new"); + Default::default() + } + + #[ink(message)] + pub fn mint_asset_through_runtime( + &mut self, + id: u32, + beneficiary: AccountId, + amount: Balance, + ) -> Result<(), ContractError> { + ink::env::debug_println!( + "Contract::mint_asset_through_runtime: id: {:?} beneficiary: {:?} amount: {:?}", + id, + beneficiary, + amount + ); + + // Check if asset doesn't exist. + if !trust_backed_assets::asset_exists(id)? { + return Err(ContractError::UnknownAsset); + } + + // Mint asset via pop api. + trust_backed_assets::mint(id, beneficiary, amount)?; + ink::env::debug_println!("Contract::mint_asset_through_runtime: asset(s) minted successfully"); + Ok(()) + } + } + + #[cfg(test)] + mod tests { + use super::*; + + #[ink::test] + fn default_works() { + PopApiExtensionDemo::new(); + } + } +} + diff --git a/pop-api/src/lib.rs b/pop-api/src/lib.rs index e4590c89..68ce6906 100644 --- a/pop-api/src/lib.rs +++ b/pop-api/src/lib.rs @@ -3,12 +3,12 @@ pub mod primitives; pub mod v0; -use crate::PopApiError::{Balances, Nfts, UnknownStatusCode}; +use crate::PopApiError::{Balances, Nfts, TrustBackedAssets, UnknownStatusCode}; use ink::{prelude::vec::Vec, ChainExtensionInstance}; use primitives::{cross_chain::*, storage_keys::*}; pub use sp_runtime::{BoundedVec, MultiAddress, MultiSignature}; use v0::RuntimeCall; -pub use v0::{balances, cross_chain, nfts, relay_chain_block_number, state}; +pub use v0::{balances, cross_chain, nfts, relay_chain_block_number, state, assets}; type AccountId = ::AccountId; type Balance = ::Balance; @@ -26,6 +26,7 @@ pub enum PopApiError { SystemCallFiltered, Balances(balances::Error), Nfts(nfts::Error), + TrustBackedAssets(assets::trust_backed::Error), Xcm(cross_chain::Error), } @@ -37,6 +38,7 @@ impl ink::env::chain_extension::FromStatusCode for PopApiError { 5 => Err(PopApiError::SystemCallFiltered), 10_000..=10_999 => Err(Balances((status_code - 10_000).try_into()?)), 50_000..=50_999 => Err(Nfts((status_code - 50_000).try_into()?)), + 52_000..=52_999 => Err(TrustBackedAssets((status_code - 52_000).try_into()?)), _ => Err(UnknownStatusCode(status_code)), } } diff --git a/pop-api/src/v0/assets/mod.rs b/pop-api/src/v0/assets/mod.rs new file mode 100644 index 00000000..7ad40f15 --- /dev/null +++ b/pop-api/src/v0/assets/mod.rs @@ -0,0 +1 @@ +pub mod trust_backed; \ No newline at end of file diff --git a/pop-api/src/v0/assets/trust_backed.rs b/pop-api/src/v0/assets/trust_backed.rs new file mode 100644 index 00000000..fb413413 --- /dev/null +++ b/pop-api/src/v0/assets/trust_backed.rs @@ -0,0 +1,519 @@ +use crate::{Balance, PopApiError::UnknownStatusCode, RuntimeCall, *}; +use ink::prelude::vec::Vec; +use primitives::{AssetId, MultiAddress}; +use scale::{Compact, Encode}; + +type Result = core::result::Result; + +/// https://github.com/paritytech/polkadot-sdk/blob/master/substrate/frame/assets/src/lib.rs +/// +/// Extrinsics within pallet assets (TrustBackedAssets Instance) that can be used via the pop api on Pop Network: +/// 1. create +/// 2. start_destroy +/// 3. destroy_accounts +/// 4. destroy_approvals +/// 5. finish_destroy +/// 6. mint +/// 7. burn +/// 8. transfer +/// 9. transfer_keep_alive +/// 10. force_transfer +/// 11. freeze +/// 12. thaw +/// 13. freeze_asset +/// 14. thaw_asset +/// 15. transfer_ownership +/// 16. set_team +/// 17. set_metadata +/// 18. clear_metadata +/// 19. approve_transfer +/// 20. cancel_approval +/// 21. force_cancel_approval +/// 22. transfer_approved +/// 23. touch +/// 24. refund +/// 25. set_min_balance +/// 26. touch_other +/// 27. refund_other +/// 28. block + + +/// Issue a new class of fungible assets from a public origin. +pub fn create( + id: AssetId, + admin: impl Into>, + min_balance: Balance, +) -> Result<()> { + Ok(dispatch(RuntimeCall::TrustBackedAssets(TrustBackedAssetsCalls::Create { + id: id.into(), + admin: admin.into(), + min_balance: Compact(min_balance), + }))?) +} + +/// Start the process of destroying a fungible asset class. +pub fn start_destroy(id: AssetId) -> Result<()> { + Ok(dispatch(RuntimeCall::TrustBackedAssets(TrustBackedAssetsCalls::StartDestroy { + id: id.into(), + }))?) +} + +/// Destroy all accounts associated with a given asset. +pub fn destroy_accounts(id: AssetId) -> Result<()> { + Ok(dispatch(RuntimeCall::TrustBackedAssets(TrustBackedAssetsCalls::DestroyAccounts { + id: id.into(), + }))?) +} + +/// Destroy all approvals associated with a given asset up to the max (see runtime configuration TrustBackedAssets `RemoveItemsLimit`). +pub fn destroy_approvals(id: AssetId) -> Result<()> { + Ok(dispatch(RuntimeCall::TrustBackedAssets(TrustBackedAssetsCalls::DestroyApprovals { + id: id.into(), + }))?) +} + +/// Complete destroying asset and unreserve currency. +pub fn finish_destroy(id: AssetId) -> Result<()> { + Ok(dispatch(RuntimeCall::TrustBackedAssets(TrustBackedAssetsCalls::FinishDestroy { + id: id.into(), + }))?) +} + +/// Mint assets of a particular class. +pub fn mint( + id: AssetId, + beneficiary: impl Into>, + amount: Balance, +) -> Result<()> { + Ok(dispatch(RuntimeCall::TrustBackedAssets(TrustBackedAssetsCalls::Mint { + id: id.into(), + beneficiary: beneficiary.into(), + amount: Compact(amount), + }))?) +} + +/// Reduce the balance of `who` by as much as possible up to `amount` assets of `id`. +pub fn burn( + id: AssetId, + who: impl Into>, + amount: Balance, +) -> Result<()> { + Ok(dispatch(RuntimeCall::TrustBackedAssets(TrustBackedAssetsCalls::Burn { + id: id.into(), + who: who.into(), + amount: Compact(amount), + }))?) +} + +/// Move some assets from the sender account to another. +pub fn transfer( + id: AssetId, + target: impl Into>, + amount: Balance, +) -> Result<()> { + Ok(dispatch(RuntimeCall::TrustBackedAssets(TrustBackedAssetsCalls::Transfer { + id: id.into(), + target: target.into(), + amount: Compact(amount), + }))?) +} + +/// Move some assets from the sender account to another, keeping the sender account alive. +pub fn transfer_keep_alive( + id: AssetId, + target: impl Into>, + amount: Balance, +) -> Result<()> { + Ok(dispatch(RuntimeCall::TrustBackedAssets(TrustBackedAssetsCalls::TransferKeepAlive { + id: id.into(), + target: target.into(), + amount: Compact(amount), + }))?) +} + +/// Move some assets from one account to another. Sender should be the Admin of the asset `id`. +pub fn force_transfer( + id: AssetId, + source: impl Into>, + dest: impl Into>, + amount: Balance, +) -> Result<()> { + Ok(dispatch(RuntimeCall::TrustBackedAssets(TrustBackedAssetsCalls::ForceTransfer { + id: id.into(), + source: source.into(), + dest: dest.into(), + amount: Compact(amount), + }))?) +} + +/// Disallow further unprivileged transfers of an asset `id` from an account `who`. `who` +/// must already exist as an entry in `Account`s of the asset. If you want to freeze an +/// account that does not have an entry, use `touch_other` first. +pub fn freeze(id: AssetId, who: impl Into>) -> Result<()> { + Ok(dispatch(RuntimeCall::TrustBackedAssets(TrustBackedAssetsCalls::Freeze { + id: id.into(), + who: who.into(), + }))?) +} + +/// Allow unprivileged transfers to and from an account again. +pub fn thaw(id: AssetId, who: impl Into>) -> Result<()> { + Ok(dispatch(RuntimeCall::TrustBackedAssets(TrustBackedAssetsCalls::Thaw { + id: id.into(), + who: who.into(), + }))?) +} + +/// Disallow further unprivileged transfers for the asset class. +pub fn freeze_asset(id: AssetId) -> Result<()> { + Ok(dispatch(RuntimeCall::TrustBackedAssets(TrustBackedAssetsCalls::FreezeAsset { + id: id.into(), + }))?) +} + +/// Allow unprivileged transfers for the asset again. +pub fn thaw_asset(id: AssetId) -> Result<()> { + Ok(dispatch(RuntimeCall::TrustBackedAssets(TrustBackedAssetsCalls::ThawAsset { + id: id.into(), + }))?) +} + +/// Change the Owner of an asset. +pub fn transfer_ownership( + id: AssetId, + owner: impl Into>, +) -> Result<()> { + Ok(dispatch(RuntimeCall::TrustBackedAssets(TrustBackedAssetsCalls::TransferOwnership { + id: id.into(), + owner: owner.into(), + }))?) +} + +/// Change the Issuer, Admin and Freezer of an asset. +pub fn set_team( + id: AssetId, + issuer: impl Into>, + admin: impl Into>, + freezer: impl Into>, +) -> Result<()> { + Ok(dispatch(RuntimeCall::TrustBackedAssets(TrustBackedAssetsCalls::SetTeam { + id: id.into(), + issuer: issuer.into(), + admin: admin.into(), + freezer: freezer.into(), + }))?) +} + +/// Set the metadata for an asset. +pub fn set_metadata(id: AssetId, name: Vec, symbol: Vec, decimals: u8) -> Result<()> { + Ok(dispatch(RuntimeCall::TrustBackedAssets(TrustBackedAssetsCalls::SetMetadata { + id: id.into(), + name, + symbol, + decimals, + }))?) +} + +/// Clear the metadata for an asset. +pub fn clear_metadata(id: AssetId) -> Result<()> { + Ok(dispatch(RuntimeCall::TrustBackedAssets(TrustBackedAssetsCalls::ClearMetadata { + id: id.into(), + }))?) +} + +/// Approve an amount of asset for transfer by a delegated third-party account. +pub fn approve_transfer( + id: AssetId, + delegate: impl Into>, + amount: Balance, +) -> Result<()> { + Ok(dispatch(RuntimeCall::TrustBackedAssets(TrustBackedAssetsCalls::ApproveTransfer { + id: id.into(), + delegate: delegate.into(), + amount: Compact(amount), + }))?) +} + +/// Cancel all of some asset approved for delegated transfer by a third-party account. +pub fn cancel_approval( + id: AssetId, + delegate: impl Into>, +) -> Result<()> { + Ok(dispatch(RuntimeCall::TrustBackedAssets(TrustBackedAssetsCalls::CancelApproval { + id: id.into(), + delegate: delegate.into(), + }))?) +} + +/// Cancel all of some asset approved for delegated transfer by a third-party account. +pub fn force_cancel_approval( + id: AssetId, + owner: impl Into>, + delegate: impl Into>, +) -> Result<()> { + Ok(dispatch(RuntimeCall::TrustBackedAssets(TrustBackedAssetsCalls::ForceCancelApproval { + id: id.into(), + owner: owner.into(), + delegate: delegate.into(), + }))?) +} + +/// Transfer some asset balance from a previously delegated account to some third-party +/// account. +pub fn transfer_approved( + id: AssetId, + owner: impl Into>, + destination: impl Into>, + amount: Balance, +) -> Result<()> { + Ok(dispatch(RuntimeCall::TrustBackedAssets(TrustBackedAssetsCalls::TransferApproved { + id: id.into(), + owner: owner.into(), + destination: destination.into(), + amount: Compact(amount), + }))?) +} + +/// Create an asset account for non-provider assets. +pub fn touch(id: AssetId) -> Result<()> { + Ok(dispatch(RuntimeCall::TrustBackedAssets(TrustBackedAssetsCalls::Touch { + id: id.into(), + }))?) +} + +/// Return the deposit (if any) of an asset account or a consumer reference (if any) of an +/// account. +pub fn refund(id: AssetId, allow_burn: bool) -> Result<()> { + Ok(dispatch(RuntimeCall::TrustBackedAssets(TrustBackedAssetsCalls::Refund { + id: id.into(), + allow_burn, + }))?) +} + +/// Sets the minimum balance of an asset. +pub fn set_min_balance(id: AssetId, min_balance: Balance) -> Result<()> { + Ok(dispatch(RuntimeCall::TrustBackedAssets(TrustBackedAssetsCalls::SetMinBalance { + id: id.into(), + min_balance: Compact(min_balance), + }))?) +} + +/// Create an asset account for `who`. +pub fn touch_other(id: AssetId, who: impl Into>) -> Result<()> { + Ok(dispatch(RuntimeCall::TrustBackedAssets(TrustBackedAssetsCalls::TouchOther { + id: id.into(), + who: who.into(), + }))?) +} + +/// Return the deposit (if any) of a target asset account. Useful if you are the depositor. +pub fn refund_other(id: AssetId, who: impl Into>) -> Result<()> { + Ok(dispatch(RuntimeCall::TrustBackedAssets(TrustBackedAssetsCalls::RefundOther { + id: id.into(), + who: who.into(), + }))?) +} + +/// Disallow further unprivileged transfers of an asset `id` to and from an account `who`. +pub fn block(id: AssetId, who: impl Into>) -> Result<()> { + Ok(dispatch(RuntimeCall::TrustBackedAssets(TrustBackedAssetsCalls::Block { + id: id.into(), + who: who.into(), + }))?) +} + +pub fn asset_exists(id: AssetId) -> Result { + Ok(state::read(RuntimeStateKeys::TrustBackedAssets(TrustBackedAssetsKeys::AssetExists(id)))?) +} + +// Parameters to extrinsics representing an asset id (`AssetIdParameter`) and a balance amount (`Balance`) are expected +// to be compact encoded. The pop api handles that for the developer. +// +// reference: https://substrate.stackexchange.com/questions/1873/what-is-the-meaning-of-palletcompact-in-pallet-development +// +// Asset id that is compact encoded. +type AssetIdParameter = Compact; +// Balance amount that is compact encoded. +type BalanceParameter = Compact; + +#[derive(Encode)] +pub(crate) enum TrustBackedAssetsCalls { + #[codec(index = 0)] + Create { + id: AssetIdParameter, + admin: MultiAddress, + min_balance: BalanceParameter, + }, + #[codec(index = 2)] + StartDestroy { id: AssetIdParameter }, + #[codec(index = 3)] + DestroyAccounts { id: AssetIdParameter }, + #[codec(index = 4)] + DestroyApprovals { id: AssetIdParameter }, + #[codec(index = 5)] + FinishDestroy { id: AssetIdParameter }, + #[codec(index = 6)] + Mint { + id: AssetIdParameter, + beneficiary: MultiAddress, + amount: BalanceParameter, + }, + #[codec(index = 7)] + Burn { id: AssetIdParameter, who: MultiAddress, amount: BalanceParameter }, + #[codec(index = 8)] + Transfer { id: AssetIdParameter, target: MultiAddress, amount: BalanceParameter }, + #[codec(index = 9)] + TransferKeepAlive { + id: AssetIdParameter, + target: MultiAddress, + amount: BalanceParameter, + }, + #[codec(index = 10)] + ForceTransfer { + id: AssetIdParameter, + source: MultiAddress, + dest: MultiAddress, + amount: BalanceParameter, + }, + #[codec(index = 11)] + Freeze { id: AssetIdParameter, who: MultiAddress }, + #[codec(index = 12)] + Thaw { id: AssetIdParameter, who: MultiAddress }, + #[codec(index = 13)] + FreezeAsset { id: AssetIdParameter }, + #[codec(index = 14)] + ThawAsset { id: AssetIdParameter }, + #[codec(index = 15)] + TransferOwnership { id: AssetIdParameter, owner: MultiAddress }, + #[codec(index = 16)] + SetTeam { + id: AssetIdParameter, + issuer: MultiAddress, + admin: MultiAddress, + freezer: MultiAddress, + }, + #[codec(index = 17)] + SetMetadata { id: AssetIdParameter, name: Vec, symbol: Vec, decimals: u8 }, + #[codec(index = 18)] + ClearMetadata { id: AssetIdParameter }, + #[codec(index = 22)] + ApproveTransfer { + id: AssetIdParameter, + delegate: MultiAddress, + amount: BalanceParameter, + }, + #[codec(index = 23)] + CancelApproval { id: AssetIdParameter, delegate: MultiAddress }, + #[codec(index = 24)] + ForceCancelApproval { + id: AssetIdParameter, + owner: MultiAddress, + delegate: MultiAddress, + }, + #[codec(index = 25)] + TransferApproved { + id: AssetIdParameter, + owner: MultiAddress, + destination: MultiAddress, + amount: BalanceParameter, + }, + #[codec(index = 26)] + Touch { id: AssetIdParameter }, + #[codec(index = 27)] + Refund { id: AssetIdParameter, allow_burn: bool }, + #[codec(index = 28)] + SetMinBalance { id: AssetIdParameter, min_balance: BalanceParameter }, + #[codec(index = 29)] + TouchOther { id: AssetIdParameter, who: MultiAddress }, + #[codec(index = 30)] + RefundOther { id: AssetIdParameter, who: MultiAddress }, + #[codec(index = 31)] + Block { id: AssetIdParameter, who: MultiAddress }, +} + +#[derive(Debug, Copy, Clone, PartialEq, Eq, Encode, scale::Decode)] +#[cfg_attr(feature = "std", derive(scale_info::TypeInfo))] +pub enum Error { + /// Account balance must be greater than or equal to the transfer amount. + BalanceLow, + /// The account to alter does not exist. + NoAccount, + /// The signing account has no permission to do the operation. + NoPermission, + /// The given asset ID is unknown. + Unknown, + /// The origin account is frozen. + Frozen, + /// The asset ID is already taken. + InUse, + /// Invalid witness data given. + BadWitness, + /// Minimum balance should be non-zero. + MinBalanceZero, + /// Unable to increment the consumer reference counters on the account. Either no provider + /// reference exists to allow a non-zero balance of a non-self-sufficient asset, or one + /// fewer then the maximum number of consumers has been reached. + UnavailableConsumer, + /// Invalid metadata given. + BadMetadata, + /// No approval exists that would allow the transfer. + Unapproved, + /// The source account would not survive the transfer and it needs to stay alive. + WouldDie, + /// The asset-account already exists. + AlreadyExists, + /// The asset-account doesn't have an associated deposit. + NoDeposit, + /// The operation would result in funds being burned. + WouldBurn, + /// The asset is a live asset and is actively being used. Usually emit for operations such + /// as `start_destroy` which require the asset to be in a destroying state. + LiveAsset, + /// The asset is not live, and likely being destroyed. + AssetNotLive, + /// The asset status is not the expected status. + IncorrectStatus, + /// The asset should be frozen before the given operation. + NotFrozen, + /// Callback action resulted in error + CallbackFailed, +} + +impl TryFrom for Error { + type Error = PopApiError; + + fn try_from(status_code: u32) -> core::result::Result { + use Error::*; + match status_code { + 0 => Ok(BalanceLow), + 1 => Ok(NoAccount), + 2 => Ok(NoPermission), + 3 => Ok(Unknown), + 4 => Ok(Frozen), + 5 => Ok(InUse), + 6 => Ok(BadWitness), + 7 => Ok(MinBalanceZero), + 8 => Ok(UnavailableConsumer), + 9 => Ok(BadMetadata), + 10 => Ok(Unapproved), + 11 => Ok(WouldDie), + 12 => Ok(AlreadyExists), + 13 => Ok(NoDeposit), + 14 => Ok(WouldBurn), + 15 => Ok(LiveAsset), + 16 => Ok(AssetNotLive), + 17 => Ok(IncorrectStatus), + 18 => Ok(NotFrozen), + _ => Err(UnknownStatusCode(status_code)), + } + } +} + +impl From for Error { + fn from(error: PopApiError) -> Self { + match error { + PopApiError::TrustBackedAssets(e) => e, + _ => panic!("Unexpected pallet assets error. This error is unknown to pallet assets"), + } + } +} diff --git a/pop-api/src/v0/mod.rs b/pop-api/src/v0/mod.rs index 2ae0b821..d914db24 100644 --- a/pop-api/src/v0/mod.rs +++ b/pop-api/src/v0/mod.rs @@ -7,6 +7,7 @@ pub mod balances; pub mod cross_chain; pub mod nfts; pub mod state; +pub mod assets; pub fn relay_chain_block_number() -> Result { state::read(RuntimeStateKeys::ParachainSystem(ParachainSystemKeys::LastRelayChainBlockNumber)) @@ -18,4 +19,6 @@ pub(crate) enum RuntimeCall { Balances(balances::BalancesCall), #[codec(index = 50)] Nfts(nfts::NftCalls), + #[codec(index = 52)] + TrustBackedAssets(assets::trust_backed::TrustBackedAssetsCalls), } diff --git a/pop-api/src/v0/nfts.rs b/pop-api/src/v0/nfts.rs index 3db08cd1..5a55154f 100644 --- a/pop-api/src/v0/nfts.rs +++ b/pop-api/src/v0/nfts.rs @@ -669,7 +669,7 @@ impl From for Error { fn from(error: PopApiError) -> Self { match error { PopApiError::Nfts(e) => e, - _ => panic!("expected nfts error"), + _ => panic!("unexpected pallet nfts error. This error is unknown to pallet nfts"), } } } diff --git a/primitives/src/lib.rs b/primitives/src/lib.rs index 8ad74ade..ebad36d3 100644 --- a/primitives/src/lib.rs +++ b/primitives/src/lib.rs @@ -1,14 +1,12 @@ #![cfg_attr(not(feature = "std"), no_std, no_main)] pub use bounded_collections::{BoundedBTreeMap, BoundedBTreeSet, BoundedVec, ConstU32}; -//use scale::{Decode, Encode, MaxEncodedLen}; pub mod cross_chain; pub mod storage_keys; -// /// Some way of identifying an account on the chain. -// #[derive(Encode, Decode, Debug, MaxEncodedLen)] -// pub struct AccountId([u8; 32]); +// Identifier for the class of asset. +pub type AssetId = u32; // Id used for identifying non-fungible collections. pub type CollectionId = u32; // Id used for identifying non-fungible items. diff --git a/primitives/src/storage_keys.rs b/primitives/src/storage_keys.rs index 2bcb41ec..a03b3a09 100644 --- a/primitives/src/storage_keys.rs +++ b/primitives/src/storage_keys.rs @@ -5,6 +5,7 @@ use scale::{Decode, Encode, MaxEncodedLen}; pub enum RuntimeStateKeys { Nfts(NftsKeys), ParachainSystem(ParachainSystemKeys), + TrustBackedAssets(TrustBackedAssetsKeys), } #[derive(Encode, Decode, Debug, MaxEncodedLen)] @@ -33,3 +34,9 @@ pub enum NftsKeys { /// Get the attribute value of `item` of `collection` corresponding to `key`. CollectionAttribute(CollectionId, BoundedVec), } + +#[derive(Encode, Decode, Debug, MaxEncodedLen)] +pub enum TrustBackedAssetsKeys { + /// Check if the asset exists. + AssetExists(AssetId), +} diff --git a/runtime/devnet/src/config/assets.rs b/runtime/devnet/src/config/assets.rs index 34035c1f..f51f8875 100644 --- a/runtime/devnet/src/config/assets.rs +++ b/runtime/devnet/src/config/assets.rs @@ -1,6 +1,6 @@ use crate::{ - deposit, AccountId, Assets, Balance, Balances, BlockNumber, Nfts, Runtime, RuntimeEvent, - RuntimeHoldReason, DAYS, EXISTENTIAL_DEPOSIT, UNIT, + deposit, AccountId, Balance, Balances, BlockNumber, Nfts, Runtime, RuntimeEvent, + RuntimeHoldReason, TrustBackedAssets, DAYS, EXISTENTIAL_DEPOSIT, UNIT, }; use frame_support::{ parameter_types, @@ -84,9 +84,9 @@ impl pallet_nft_fractionalization::Config for Runtime { type StringLimit = AssetsStringLimit; type NftCollectionId = ::CollectionId; type NftId = ::ItemId; - type AssetBalance = >::Balance; - type AssetId = >::AssetId; - type Assets = Assets; + type AssetBalance = >::Balance; + type AssetId = >::AssetId; + type Assets = TrustBackedAssets; type Nfts = Nfts; type PalletId = NftFractionalizationPalletId; type WeightInfo = pallet_nft_fractionalization::weights::SubstrateWeight; @@ -95,9 +95,9 @@ impl pallet_nft_fractionalization::Config for Runtime { type BenchmarkHelper = (); } -pub type TrustBackedAssets = pallet_assets::Instance1; -pub type TrustBackedAssetsCall = pallet_assets::Call; -impl pallet_assets::Config for Runtime { +pub type TrustBackedAssetsInstance = pallet_assets::Instance1; +pub(crate) type TrustBackedAssetsCall = pallet_assets::Call; +impl pallet_assets::Config for Runtime { type RuntimeEvent = RuntimeEvent; type Balance = Balance; type AssetId = AssetIdForTrustBackedAssets; diff --git a/runtime/devnet/src/extensions.rs b/runtime/devnet/src/extensions.rs index 7e2a53c0..c8e88eb2 100644 --- a/runtime/devnet/src/extensions.rs +++ b/runtime/devnet/src/extensions.rs @@ -3,15 +3,15 @@ use frame_support::traits::{Contains, OriginTrait}; use frame_support::{ dispatch::{GetDispatchInfo, RawOrigin}, pallet_prelude::*, - traits::nonfungibles_v2::Inspect, + traits::{fungibles::Inspect, nonfungibles_v2::Inspect as NonFungiblesInspect}, }; use pallet_contracts::chain_extension::{ BufInBufOutState, ChainExtension, ChargedAmount, Environment, Ext, InitState, RetVal, }; use pop_primitives::{ cross_chain::CrossChainMessage, - storage_keys::{NftsKeys, ParachainSystemKeys, RuntimeStateKeys}, - CollectionId, ItemId, + storage_keys::{NftsKeys, ParachainSystemKeys, RuntimeStateKeys, TrustBackedAssetsKeys}, + AssetId, CollectionId, ItemId, }; use sp_core::crypto::UncheckedFrom; use sp_runtime::{ @@ -24,7 +24,10 @@ use xcm::{ VersionedXcm, }; -use crate::{AccountId, AllowedApiCalls, RuntimeCall, RuntimeOrigin, UNIT}; +use crate::{ + assets_config::TrustBackedAssetsInstance, AccountId, AllowedPopApiCalls, RuntimeCall, + RuntimeOrigin, UNIT, +}; const LOG_TARGET: &str = "pop-api::extension"; @@ -37,6 +40,7 @@ impl ChainExtension for PopApiExtension where T: pallet_contracts::Config + pallet_xcm::Config + + pallet_assets::Config + pallet_nfts::Config + cumulus_pallet_parachain_system::Config + frame_system::Config< @@ -120,7 +124,7 @@ where log::debug!(target:LOG_TARGET, "{} inputted RuntimeCall: {:?}", log_prefix, call); - origin.add_filter(AllowedApiCalls::contains); + origin.add_filter(AllowedPopApiCalls::contains); match call.dispatch(origin) { Ok(info) => { @@ -192,6 +196,7 @@ where fn read_state(env: Environment) -> Result<(), DispatchError> where T: pallet_contracts::Config + + pallet_assets::Config + pallet_nfts::Config + cumulus_pallet_parachain_system::Config + frame_system::Config, @@ -217,6 +222,9 @@ where RuntimeStateKeys::ParachainSystem(key) => { read_parachain_system_state::(key, &mut env) }, + RuntimeStateKeys::TrustBackedAssets(key) => { + read_trust_backed_assets_state::(key, &mut env) + }, }? .encode(); @@ -292,6 +300,23 @@ where } } +fn read_trust_backed_assets_state( + key: TrustBackedAssetsKeys, + env: &mut Environment, +) -> Result, DispatchError> +where + T: pallet_contracts::Config + + pallet_assets::Config, + E: Ext, +{ + match key { + TrustBackedAssetsKeys::AssetExists(id) => { + env.charge_weight(T::DbWeight::get().reads(1_u64))?; + Ok(pallet_assets::Pallet::::asset_exists(id).encode()) + }, + } +} + fn send_xcm(env: Environment) -> Result<(), DispatchError> where T: pallet_contracts::Config @@ -828,6 +853,110 @@ mod tests { }); } + #[test] + #[ignore] + fn dispatch_trust_backed_assets_mint_from_contract_works() { + new_test_ext().execute_with(|| { + let _ = env_logger::try_init(); + + let (wasm_binary, _) = load_wasm_module::( + "../../pop-api/examples/trust_backed_assets/target/ink/pop_api_trust_backed_assets_example.wasm", + ) + .unwrap(); + + let init_value = 100; + + let result = Contracts::bare_instantiate( + ALICE, + init_value, + GAS_LIMIT, + None, + Code::Upload(wasm_binary), + function_selector("new"), + vec![], + DEBUG_OUTPUT, + pallet_contracts::CollectEvents::Skip, + ) + .result + .unwrap(); + + assert!(!result.result.did_revert(), "deploying contract reverted {:?}", result); + let addr = result.account_id; + + let asset_id: u32 = 1; + let min_balance = 1; + let amount: u128 = 100 * UNIT; + let function = function_selector("mint_asset_through_runtime"); + let params = [function, asset_id.encode(), BOB.encode(), amount.encode()].concat(); + + // Mint asset which does not exist. + let result = Contracts::bare_call( + ALICE, + addr.clone(), + 0, + GAS_LIMIT, + None, + params.clone(), + DEBUG_OUTPUT, + pallet_contracts::CollectEvents::Skip, + pallet_contracts::Determinism::Enforced, + ); + + if DEBUG_OUTPUT == pallet_contracts::DebugInfo::UnsafeDebug { + log::debug!( + "Contract debug buffer - {:?}", + String::from_utf8(result.debug_message.clone()) + ); + log::debug!("result: {:?}", result); + } + + // Check for revert. + assert!(result.result.unwrap().did_revert(), "Contract should have been reverted!"); + + // Create asset with contract as owner. + assert_eq!( + TrustBackedAssets::force_create( + RuntimeOrigin::root(), + asset_id.into(), + addr.clone().into(), + true, + min_balance, + ), + Ok(()) + ); + + // Check Bob's asset balance before minting through contract. + let bob_balance_before = TrustBackedAssets::balance(asset_id, &BOB); + assert_eq!(bob_balance_before, 0); + + let result = Contracts::bare_call( + ALICE, + addr.clone(), + 0, + GAS_LIMIT, + None, + params, + DEBUG_OUTPUT, + pallet_contracts::CollectEvents::Skip, + pallet_contracts::Determinism::Enforced, + ); + + if DEBUG_OUTPUT == pallet_contracts::DebugInfo::UnsafeDebug { + log::debug!( + "Contract debug buffer - {:?}", + String::from_utf8(result.debug_message.clone()) + ); + log::debug!("result: {:?}", result); + } + + // Check for revert + assert!(!result.result.unwrap().did_revert(), "Contract reverted!"); + + let bob_balance_after = TrustBackedAssets::balance(asset_id, &BOB); + assert_eq!(bob_balance_after, bob_balance_before + amount); + }); + } + #[test] #[ignore] fn allow_call_filter_blocks_call() { diff --git a/runtime/devnet/src/lib.rs b/runtime/devnet/src/lib.rs index ffca8a12..52a0938f 100644 --- a/runtime/devnet/src/lib.rs +++ b/runtime/devnet/src/lib.rs @@ -251,46 +251,77 @@ impl Contains for FilteredCalls { } /// A type to identify allowed calls to the Runtime from contracts. Used by Pop API -pub struct AllowedApiCalls; -impl Contains for crate::AllowedApiCalls { +pub struct AllowedPopApiCalls; +impl Contains for crate::AllowedPopApiCalls { fn contains(c: &RuntimeCall) -> bool { + use assets_config::TrustBackedAssetsCall; use pallet_nfts::Call as NftsCall; matches!( c, RuntimeCall::Balances(BalancesCall::transfer_keep_alive { .. }) - | RuntimeCall::Nfts( - NftsCall::create { .. } - | NftsCall::destroy { .. } - | NftsCall::mint { .. } | NftsCall::burn { .. } - | NftsCall::transfer { .. } - | NftsCall::redeposit { .. } - | NftsCall::lock_item_transfer { .. } - | NftsCall::unlock_item_transfer { .. } - | NftsCall::lock_collection { .. } - | NftsCall::transfer_ownership { .. } - | NftsCall::set_team { .. } - | NftsCall::approve_transfer { .. } - | NftsCall::cancel_approval { .. } - | NftsCall::clear_all_transfer_approvals { .. } - | NftsCall::lock_item_properties { .. } - | NftsCall::set_attribute { .. } - | NftsCall::clear_attribute { .. } - | NftsCall::approve_item_attributes { .. } - | NftsCall::cancel_item_attributes_approval { .. } - | NftsCall::set_metadata { .. } - | NftsCall::clear_metadata { .. } - | NftsCall::set_collection_metadata { .. } - | NftsCall::clear_collection_metadata { .. } - | NftsCall::set_accept_ownership { .. } - | NftsCall::set_collection_max_supply { .. } - | NftsCall::update_mint_settings { .. } - | NftsCall::set_price { .. } - | NftsCall::buy_item { .. } - | NftsCall::pay_tips { .. } - | NftsCall::create_swap { .. } - | NftsCall::cancel_swap { .. } - | NftsCall::claim_swap { .. } - ) + | RuntimeCall::TrustBackedAssets( + TrustBackedAssetsCall::create { .. } + | TrustBackedAssetsCall::start_destroy { .. } + | TrustBackedAssetsCall::destroy_accounts { .. } + | TrustBackedAssetsCall::destroy_approvals { .. } + | TrustBackedAssetsCall::finish_destroy { .. } + | TrustBackedAssetsCall::mint { .. } + | TrustBackedAssetsCall::burn { .. } + | TrustBackedAssetsCall::transfer { .. } + | TrustBackedAssetsCall::transfer_keep_alive { .. } + | TrustBackedAssetsCall::force_transfer { .. } + | TrustBackedAssetsCall::freeze { .. } + | TrustBackedAssetsCall::thaw { .. } + | TrustBackedAssetsCall::freeze_asset { .. } + | TrustBackedAssetsCall::thaw_asset { .. } + | TrustBackedAssetsCall::transfer_ownership { .. } + | TrustBackedAssetsCall::set_team { .. } + | TrustBackedAssetsCall::set_metadata { .. } + | TrustBackedAssetsCall::clear_metadata { .. } + | TrustBackedAssetsCall::approve_transfer { .. } + | TrustBackedAssetsCall::cancel_approval { .. } + | TrustBackedAssetsCall::force_cancel_approval { .. } + | TrustBackedAssetsCall::transfer_approved { .. } + | TrustBackedAssetsCall::touch { .. } + | TrustBackedAssetsCall::refund { .. } + | TrustBackedAssetsCall::set_min_balance { .. } + | TrustBackedAssetsCall::touch_other { .. } + | TrustBackedAssetsCall::refund_other { .. } + | TrustBackedAssetsCall::block { .. } + ) | RuntimeCall::Nfts( + NftsCall::create { .. } + | NftsCall::destroy { .. } + | NftsCall::mint { .. } + | NftsCall::burn { .. } + | NftsCall::transfer { .. } + | NftsCall::redeposit { .. } + | NftsCall::lock_item_transfer { .. } + | NftsCall::unlock_item_transfer { .. } + | NftsCall::lock_collection { .. } + | NftsCall::transfer_ownership { .. } + | NftsCall::set_team { .. } + | NftsCall::approve_transfer { .. } + | NftsCall::cancel_approval { .. } + | NftsCall::clear_all_transfer_approvals { .. } + | NftsCall::lock_item_properties { .. } + | NftsCall::set_attribute { .. } + | NftsCall::clear_attribute { .. } + | NftsCall::approve_item_attributes { .. } + | NftsCall::cancel_item_attributes_approval { .. } + | NftsCall::set_metadata { .. } + | NftsCall::clear_metadata { .. } + | NftsCall::set_collection_metadata { .. } + | NftsCall::clear_collection_metadata { .. } + | NftsCall::set_accept_ownership { .. } + | NftsCall::set_collection_max_supply { .. } + | NftsCall::update_mint_settings { .. } + | NftsCall::set_price { .. } + | NftsCall::buy_item { .. } + | NftsCall::pay_tips { .. } + | NftsCall::create_swap { .. } + | NftsCall::cancel_swap { .. } + | NftsCall::claim_swap { .. } + ) ) } } @@ -631,7 +662,7 @@ construct_runtime!( // Assets Nfts: pallet_nfts = 50, NftFractionalization: pallet_nft_fractionalization = 51, - Assets: pallet_assets:: = 52, + TrustBackedAssets: pallet_assets:: = 52, } ); diff --git a/runtime/testnet/src/config/assets.rs b/runtime/testnet/src/config/assets.rs index 34035c1f..f51f8875 100644 --- a/runtime/testnet/src/config/assets.rs +++ b/runtime/testnet/src/config/assets.rs @@ -1,6 +1,6 @@ use crate::{ - deposit, AccountId, Assets, Balance, Balances, BlockNumber, Nfts, Runtime, RuntimeEvent, - RuntimeHoldReason, DAYS, EXISTENTIAL_DEPOSIT, UNIT, + deposit, AccountId, Balance, Balances, BlockNumber, Nfts, Runtime, RuntimeEvent, + RuntimeHoldReason, TrustBackedAssets, DAYS, EXISTENTIAL_DEPOSIT, UNIT, }; use frame_support::{ parameter_types, @@ -84,9 +84,9 @@ impl pallet_nft_fractionalization::Config for Runtime { type StringLimit = AssetsStringLimit; type NftCollectionId = ::CollectionId; type NftId = ::ItemId; - type AssetBalance = >::Balance; - type AssetId = >::AssetId; - type Assets = Assets; + type AssetBalance = >::Balance; + type AssetId = >::AssetId; + type Assets = TrustBackedAssets; type Nfts = Nfts; type PalletId = NftFractionalizationPalletId; type WeightInfo = pallet_nft_fractionalization::weights::SubstrateWeight; @@ -95,9 +95,9 @@ impl pallet_nft_fractionalization::Config for Runtime { type BenchmarkHelper = (); } -pub type TrustBackedAssets = pallet_assets::Instance1; -pub type TrustBackedAssetsCall = pallet_assets::Call; -impl pallet_assets::Config for Runtime { +pub type TrustBackedAssetsInstance = pallet_assets::Instance1; +pub(crate) type TrustBackedAssetsCall = pallet_assets::Call; +impl pallet_assets::Config for Runtime { type RuntimeEvent = RuntimeEvent; type Balance = Balance; type AssetId = AssetIdForTrustBackedAssets; diff --git a/runtime/testnet/src/extensions.rs b/runtime/testnet/src/extensions.rs index d6f2d656..0d552090 100644 --- a/runtime/testnet/src/extensions.rs +++ b/runtime/testnet/src/extensions.rs @@ -3,23 +3,25 @@ use frame_support::traits::{Contains, OriginTrait}; use frame_support::{ dispatch::{GetDispatchInfo, RawOrigin}, pallet_prelude::*, - traits::nonfungibles_v2::Inspect, + traits::{fungibles::Inspect, nonfungibles_v2::Inspect as NonFungiblesInspect}, }; use pallet_contracts::chain_extension::{ BufInBufOutState, ChainExtension, ChargedAmount, Environment, Ext, InitState, RetVal, }; use pop_primitives::{ - storage_keys::{NftsKeys, ParachainSystemKeys, RuntimeStateKeys}, - CollectionId, ItemId, + storage_keys::{NftsKeys, ParachainSystemKeys, RuntimeStateKeys, TrustBackedAssetsKeys}, + AssetId, CollectionId, ItemId, }; use sp_core::crypto::UncheckedFrom; use sp_runtime::{ traits::{BlockNumberProvider, Dispatchable}, DispatchError, }; -use sp_std::vec::Vec; -use crate::{AccountId, AllowedApiCalls, RuntimeCall, RuntimeOrigin}; +use crate::{ + assets_config::TrustBackedAssetsInstance, AccountId, AllowedPopApiCalls, RuntimeCall, + RuntimeOrigin, +}; const LOG_TARGET: &str = "pop-api::extension"; @@ -32,6 +34,7 @@ impl ChainExtension for PopApiExtension where T: pallet_contracts::Config + pallet_xcm::Config + + pallet_assets::Config + pallet_nfts::Config + cumulus_pallet_parachain_system::Config + frame_system::Config< @@ -109,7 +112,7 @@ where log::debug!(target:LOG_TARGET, "{} inputted RuntimeCall: {:?}", log_prefix, call); - origin.add_filter(AllowedApiCalls::contains); + origin.add_filter(AllowedPopApiCalls::contains); match call.dispatch(origin) { Ok(info) => { @@ -181,6 +184,7 @@ where fn read_state(env: Environment) -> Result<(), DispatchError> where T: pallet_contracts::Config + + pallet_assets::Config + pallet_nfts::Config + cumulus_pallet_parachain_system::Config + frame_system::Config, @@ -206,6 +210,9 @@ where RuntimeStateKeys::ParachainSystem(key) => { read_parachain_system_state::(key, &mut env) }, + RuntimeStateKeys::TrustBackedAssets(key) => { + read_trust_backed_assets_state::(key, &mut env) + }, }? .encode(); @@ -281,6 +288,23 @@ where } } +fn read_trust_backed_assets_state( + key: TrustBackedAssetsKeys, + env: &mut Environment, +) -> Result, DispatchError> +where + T: pallet_contracts::Config + + pallet_assets::Config, + E: Ext, +{ + match key { + TrustBackedAssetsKeys::AssetExists(id) => { + env.charge_weight(T::DbWeight::get().reads(1_u64))?; + Ok(pallet_assets::Pallet::::asset_exists(id).encode()) + }, + } +} + #[cfg(test)] mod tests { pub use super::*; @@ -481,7 +505,7 @@ mod tests { log::debug!("result: {:?}", result); } - // check for revert + // Check for revert. assert!(!result.result.unwrap().did_revert(), "Contract reverted!"); assert_eq!(Nfts::owner(collection_id, item_id), Some(BOB.into())); @@ -546,7 +570,7 @@ mod tests { log::debug!("result: {:?}", result); } - // check for revert with expected error + // Check for revert with expected error. let result = result.result.unwrap(); assert!(result.did_revert()); }); @@ -606,7 +630,7 @@ mod tests { log::debug!("result: {:?}", result); } - // check for revert + // Check for revert. assert!(!result.result.unwrap().did_revert(), "Contract reverted!"); }); } @@ -669,7 +693,7 @@ mod tests { log::debug!("result: {:?}", result); } - // check for revert + // Check for revert. assert!( result.result.is_err(), "Contract execution should have failed - unimplemented runtime call!" @@ -677,6 +701,110 @@ mod tests { }); } + #[test] + #[ignore] + fn dispatch_trust_backed_assets_mint_from_contract_works() { + new_test_ext().execute_with(|| { + let _ = env_logger::try_init(); + + let (wasm_binary, _) = load_wasm_module::( + "../../pop-api/examples/trust_backed_assets/target/ink/pop_api_trust_backed_assets_example.wasm", + ) + .unwrap(); + + let init_value = 100; + + let result = Contracts::bare_instantiate( + ALICE, + init_value, + GAS_LIMIT, + None, + Code::Upload(wasm_binary), + function_selector("new"), + vec![], + DEBUG_OUTPUT, + pallet_contracts::CollectEvents::Skip, + ) + .result + .unwrap(); + + assert!(!result.result.did_revert(), "deploying contract reverted {:?}", result); + let addr = result.account_id; + + let asset_id: u32 = 1; + let min_balance = 1; + let amount: u128 = 100 * UNIT; + let function = function_selector("mint_asset_through_runtime"); + let params = [function, asset_id.encode(), BOB.encode(), amount.encode()].concat(); + + // Mint asset which does not exist. + let result = Contracts::bare_call( + ALICE, + addr.clone(), + 0, + GAS_LIMIT, + None, + params.clone(), + DEBUG_OUTPUT, + pallet_contracts::CollectEvents::Skip, + pallet_contracts::Determinism::Enforced, + ); + + if DEBUG_OUTPUT == pallet_contracts::DebugInfo::UnsafeDebug { + log::debug!( + "Contract debug buffer - {:?}", + String::from_utf8(result.debug_message.clone()) + ); + log::debug!("result: {:?}", result); + } + + // Check for revert. + assert!(result.result.unwrap().did_revert(), "Contract should have been reverted!"); + + // Create asset with contract as owner. + assert_eq!( + TrustBackedAssets::force_create( + RuntimeOrigin::root(), + asset_id.into(), + addr.clone().into(), + true, + min_balance, + ), + Ok(()) + ); + + // Check Bob's asset balance before minting through contract. + let bob_balance_before = TrustBackedAssets::balance(asset_id, &BOB); + assert_eq!(bob_balance_before, 0); + + let result = Contracts::bare_call( + ALICE, + addr.clone(), + 0, + GAS_LIMIT, + None, + params, + DEBUG_OUTPUT, + pallet_contracts::CollectEvents::Skip, + pallet_contracts::Determinism::Enforced, + ); + + if DEBUG_OUTPUT == pallet_contracts::DebugInfo::UnsafeDebug { + log::debug!( + "Contract debug buffer - {:?}", + String::from_utf8(result.debug_message.clone()) + ); + log::debug!("result: {:?}", result); + } + + // Check for revert + assert!(!result.result.unwrap().did_revert(), "Contract reverted!"); + + let bob_balance_after = TrustBackedAssets::balance(asset_id, &BOB); + assert_eq!(bob_balance_after, bob_balance_before + amount); + }); + } + #[test] #[ignore] fn allow_call_filter_blocks_call() { @@ -731,7 +859,7 @@ mod tests { log::debug!("filtered result: {:?}", result); } - // check for revert + // Check for revert. assert!(!result.result.unwrap().did_revert(), "Contract reverted!"); }); } diff --git a/runtime/testnet/src/lib.rs b/runtime/testnet/src/lib.rs index 37f378f7..312d9b50 100644 --- a/runtime/testnet/src/lib.rs +++ b/runtime/testnet/src/lib.rs @@ -250,46 +250,77 @@ impl Contains for FilteredCalls { } /// A type to identify allowed calls to the Runtime from contracts. Used by Pop API -pub struct AllowedApiCalls; -impl Contains for crate::AllowedApiCalls { +pub struct AllowedPopApiCalls; +impl Contains for crate::AllowedPopApiCalls { fn contains(c: &RuntimeCall) -> bool { + use assets_config::TrustBackedAssetsCall; use pallet_nfts::Call as NftsCall; matches!( c, RuntimeCall::Balances(BalancesCall::transfer_keep_alive { .. }) - | RuntimeCall::Nfts( - NftsCall::create { .. } - | NftsCall::destroy { .. } - | NftsCall::mint { .. } | NftsCall::burn { .. } - | NftsCall::transfer { .. } - | NftsCall::redeposit { .. } - | NftsCall::lock_item_transfer { .. } - | NftsCall::unlock_item_transfer { .. } - | NftsCall::lock_collection { .. } - | NftsCall::transfer_ownership { .. } - | NftsCall::set_team { .. } - | NftsCall::approve_transfer { .. } - | NftsCall::cancel_approval { .. } - | NftsCall::clear_all_transfer_approvals { .. } - | NftsCall::lock_item_properties { .. } - | NftsCall::set_attribute { .. } - | NftsCall::clear_attribute { .. } - | NftsCall::approve_item_attributes { .. } - | NftsCall::cancel_item_attributes_approval { .. } - | NftsCall::set_metadata { .. } - | NftsCall::clear_metadata { .. } - | NftsCall::set_collection_metadata { .. } - | NftsCall::clear_collection_metadata { .. } - | NftsCall::set_accept_ownership { .. } - | NftsCall::set_collection_max_supply { .. } - | NftsCall::update_mint_settings { .. } - | NftsCall::set_price { .. } - | NftsCall::buy_item { .. } - | NftsCall::pay_tips { .. } - | NftsCall::create_swap { .. } - | NftsCall::cancel_swap { .. } - | NftsCall::claim_swap { .. } - ) + | RuntimeCall::TrustBackedAssets( + TrustBackedAssetsCall::create { .. } + | TrustBackedAssetsCall::start_destroy { .. } + | TrustBackedAssetsCall::destroy_accounts { .. } + | TrustBackedAssetsCall::destroy_approvals { .. } + | TrustBackedAssetsCall::finish_destroy { .. } + | TrustBackedAssetsCall::mint { .. } + | TrustBackedAssetsCall::burn { .. } + | TrustBackedAssetsCall::transfer { .. } + | TrustBackedAssetsCall::transfer_keep_alive { .. } + | TrustBackedAssetsCall::force_transfer { .. } + | TrustBackedAssetsCall::freeze { .. } + | TrustBackedAssetsCall::thaw { .. } + | TrustBackedAssetsCall::freeze_asset { .. } + | TrustBackedAssetsCall::thaw_asset { .. } + | TrustBackedAssetsCall::transfer_ownership { .. } + | TrustBackedAssetsCall::set_team { .. } + | TrustBackedAssetsCall::set_metadata { .. } + | TrustBackedAssetsCall::clear_metadata { .. } + | TrustBackedAssetsCall::approve_transfer { .. } + | TrustBackedAssetsCall::cancel_approval { .. } + | TrustBackedAssetsCall::force_cancel_approval { .. } + | TrustBackedAssetsCall::transfer_approved { .. } + | TrustBackedAssetsCall::touch { .. } + | TrustBackedAssetsCall::refund { .. } + | TrustBackedAssetsCall::set_min_balance { .. } + | TrustBackedAssetsCall::touch_other { .. } + | TrustBackedAssetsCall::refund_other { .. } + | TrustBackedAssetsCall::block { .. } + ) | RuntimeCall::Nfts( + NftsCall::create { .. } + | NftsCall::destroy { .. } + | NftsCall::mint { .. } + | NftsCall::burn { .. } + | NftsCall::transfer { .. } + | NftsCall::redeposit { .. } + | NftsCall::lock_item_transfer { .. } + | NftsCall::unlock_item_transfer { .. } + | NftsCall::lock_collection { .. } + | NftsCall::transfer_ownership { .. } + | NftsCall::set_team { .. } + | NftsCall::approve_transfer { .. } + | NftsCall::cancel_approval { .. } + | NftsCall::clear_all_transfer_approvals { .. } + | NftsCall::lock_item_properties { .. } + | NftsCall::set_attribute { .. } + | NftsCall::clear_attribute { .. } + | NftsCall::approve_item_attributes { .. } + | NftsCall::cancel_item_attributes_approval { .. } + | NftsCall::set_metadata { .. } + | NftsCall::clear_metadata { .. } + | NftsCall::set_collection_metadata { .. } + | NftsCall::clear_collection_metadata { .. } + | NftsCall::set_accept_ownership { .. } + | NftsCall::set_collection_max_supply { .. } + | NftsCall::update_mint_settings { .. } + | NftsCall::set_price { .. } + | NftsCall::buy_item { .. } + | NftsCall::pay_tips { .. } + | NftsCall::create_swap { .. } + | NftsCall::cancel_swap { .. } + | NftsCall::claim_swap { .. } + ) ) } } @@ -630,7 +661,7 @@ construct_runtime!( // Assets Nfts: pallet_nfts = 50, NftFractionalization: pallet_nft_fractionalization = 51, - Assets: pallet_assets:: = 52, + TrustBackedAssets: pallet_assets:: = 52, } ); From 418aa6311498112ec43a23ea72962a43464826b3 Mon Sep 17 00:00:00 2001 From: R0GUE Date: Fri, 12 Apr 2024 15:33:32 +0200 Subject: [PATCH 002/112] style: renaming assets example --- pop-api/examples/trust_backed_assets/lib.rs | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/pop-api/examples/trust_backed_assets/lib.rs b/pop-api/examples/trust_backed_assets/lib.rs index 8b2fbda6..3606f852 100755 --- a/pop-api/examples/trust_backed_assets/lib.rs +++ b/pop-api/examples/trust_backed_assets/lib.rs @@ -1,5 +1,9 @@ #![cfg_attr(not(feature = "std"), no_std, no_main)] +// Utilizing Trust Backed Assets with the Pop API. +// +// This example demonstrates interaction with trust backed assets via the assets pallet. Trust backed assets are originated +// and managed within Pop Network, harnessing the platform's inherent trust, security, and governance models. use pop_api::assets::trust_backed as trust_backed_assets; #[derive(Debug, Copy, Clone, PartialEq, Eq, scale::Encode, scale::Decode)] @@ -16,14 +20,14 @@ impl From for ContractError { } #[ink::contract(env = pop_api::Environment)] -mod pop_api_extension_demo { +mod pop_api_tb_assets_example { use super::*; #[ink(storage)] #[derive(Default)] - pub struct PopApiExtensionDemo; + pub struct PopApiTBAssetsExample; - impl PopApiExtensionDemo { + impl PopApiTBAssetsExample { #[ink(constructor, payable)] pub fn new() -> Self { ink::env::debug_println!("Contract::new"); @@ -45,13 +49,15 @@ mod pop_api_extension_demo { ); // Check if asset doesn't exist. - if !trust_backed_assets::asset_exists(id)? { + if !trust_backed_assets::asset_exists(id)? { return Err(ContractError::UnknownAsset); } // Mint asset via pop api. trust_backed_assets::mint(id, beneficiary, amount)?; - ink::env::debug_println!("Contract::mint_asset_through_runtime: asset(s) minted successfully"); + ink::env::debug_println!( + "Contract::mint_asset_through_runtime: asset(s) minted successfully" + ); Ok(()) } } @@ -62,8 +68,7 @@ mod pop_api_extension_demo { #[ink::test] fn default_works() { - PopApiExtensionDemo::new(); + PopApiTBAssetsExample::new(); } } } - From 3d385df789e84a678badd94a70a6833d61329437 Mon Sep 17 00:00:00 2001 From: R0GUE Date: Mon, 22 Apr 2024 15:05:31 +0200 Subject: [PATCH 003/112] refactor: chain extension tests --- Cargo.lock | 8 + pop-api/Cargo.toml | 2 +- .../.gitignore | 0 .../Cargo.toml | 2 +- pop-api/examples/fungibles/expanded.rs | 2766 +++++++++++++++++ pop-api/examples/fungibles/lib.rs | 176 ++ pop-api/examples/trust_backed_assets/lib.rs | 74 - pop-api/src/lib.rs | 15 +- pop-api/src/v0/assets/fungibles.rs | 554 ++++ pop-api/src/v0/assets/mod.rs | 2 +- pop-api/src/v0/assets/trust_backed.rs | 519 ---- pop-api/src/v0/balances.rs | 2 +- pop-api/src/v0/contracts.rs | 156 + pop-api/src/v0/mod.rs | 3 +- primitives/Cargo.toml | 14 +- primitives/src/lib.rs | 12 + primitives/src/storage_keys.rs | 14 +- runtime/devnet/Cargo.toml | 2 +- runtime/devnet/src/config/assets.rs | 8 +- runtime/devnet/src/config/mod.rs | 2 +- runtime/devnet/src/config/proxy.rs | 40 +- runtime/devnet/src/extensions.rs | 1018 ------ runtime/devnet/src/extensions/mod.rs | 896 ++++++ .../src/extensions/tests/local_fungibles.rs | 302 ++ runtime/devnet/src/extensions/tests/mod.rs | 86 + runtime/devnet/src/lib.rs | 62 +- runtime/testnet/Cargo.toml | 2 +- runtime/testnet/src/config/assets.rs | 8 +- runtime/testnet/src/config/proxy.rs | 40 +- runtime/testnet/src/extensions.rs | 138 +- runtime/testnet/src/lib.rs | 99 +- 31 files changed, 5116 insertions(+), 1906 deletions(-) rename pop-api/examples/{trust_backed_assets => fungibles}/.gitignore (100%) rename pop-api/examples/{trust_backed_assets => fungibles}/Cargo.toml (93%) create mode 100644 pop-api/examples/fungibles/expanded.rs create mode 100755 pop-api/examples/fungibles/lib.rs delete mode 100755 pop-api/examples/trust_backed_assets/lib.rs create mode 100644 pop-api/src/v0/assets/fungibles.rs delete mode 100644 pop-api/src/v0/assets/trust_backed.rs create mode 100644 pop-api/src/v0/contracts.rs delete mode 100644 runtime/devnet/src/extensions.rs create mode 100644 runtime/devnet/src/extensions/mod.rs create mode 100644 runtime/devnet/src/extensions/tests/local_fungibles.rs create mode 100644 runtime/devnet/src/extensions/tests/mod.rs diff --git a/Cargo.lock b/Cargo.lock index e43d2b18..17cc70e5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -9673,6 +9673,8 @@ version = "0.0.0" dependencies = [ "bounded-collections 0.1.9", "parity-scale-codec", + "scale-decode", + "scale-encode", "scale-info", ] @@ -9720,16 +9722,19 @@ dependencies = [ "pallet-collator-selection", "pallet-contracts", "pallet-message-queue", + "pallet-multisig", "pallet-nft-fractionalization", "pallet-nfts", "pallet-nfts-runtime-api", "pallet-preimage", + "pallet-proxy", "pallet-scheduler", "pallet-session", "pallet-sudo", "pallet-timestamp", "pallet-transaction-payment", "pallet-transaction-payment-rpc-runtime-api", + "pallet-utility", "pallet-xcm", "parachains-common", "parity-scale-codec", @@ -9790,16 +9795,19 @@ dependencies = [ "pallet-collator-selection", "pallet-contracts", "pallet-message-queue", + "pallet-multisig", "pallet-nft-fractionalization", "pallet-nfts", "pallet-nfts-runtime-api", "pallet-preimage", + "pallet-proxy", "pallet-scheduler", "pallet-session", "pallet-sudo", "pallet-timestamp", "pallet-transaction-payment", "pallet-transaction-payment-rpc-runtime-api", + "pallet-utility", "pallet-xcm", "parachains-common", "parity-scale-codec", diff --git a/pop-api/Cargo.toml b/pop-api/Cargo.toml index 0fa1119c..80818235 100644 --- a/pop-api/Cargo.toml +++ b/pop-api/Cargo.toml @@ -13,7 +13,7 @@ scale-info = { version = "2.6", default-features = false, features = ["derive"] sp-io = { version = "23.0.0", default-features = false, features = ["disable_panic_handler", "disable_oom", "disable_allocator"] } sp-runtime = { version = "24.0", default-features = false } -pop-primitives = { path = "../primitives", default-features = false } +pop-primitives = { path = "../primitives", features = ["devnet"], default-features = false } [lib] name = "pop_api" diff --git a/pop-api/examples/trust_backed_assets/.gitignore b/pop-api/examples/fungibles/.gitignore similarity index 100% rename from pop-api/examples/trust_backed_assets/.gitignore rename to pop-api/examples/fungibles/.gitignore diff --git a/pop-api/examples/trust_backed_assets/Cargo.toml b/pop-api/examples/fungibles/Cargo.toml similarity index 93% rename from pop-api/examples/trust_backed_assets/Cargo.toml rename to pop-api/examples/fungibles/Cargo.toml index 3c3716fc..1fe32d6d 100755 --- a/pop-api/examples/trust_backed_assets/Cargo.toml +++ b/pop-api/examples/fungibles/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "pop_api_trust_backed_assets_example" +name = "fungibles" version = "0.1.0" authors = ["[your_name] <[your_email]>"] edition = "2021" diff --git a/pop-api/examples/fungibles/expanded.rs b/pop-api/examples/fungibles/expanded.rs new file mode 100644 index 00000000..c73cdeb7 --- /dev/null +++ b/pop-api/examples/fungibles/expanded.rs @@ -0,0 +1,2766 @@ +#![feature(prelude_import)] +#[prelude_import] +use std::prelude::rust_2021::*; +#[macro_use] +extern crate std; +use pop_api::{ + primitives::{AccountId as AccountId32, AssetId}, + assets::fungibles::*, +}; +pub enum FungiblesError { + /// Not enough balance to fulfill a request is available. + InsufficientBalance, + /// Not enough allowance to fulfill a request is available. + InsufficientAllowance, + /// The asset status is not the expected status. + IncorrectStatus, + /// The asset ID is already taken. + InUse, + /// Minimum balance should be non-zero. + MinBalanceZero, + /// The signing account has no permission to do the operation. + NoPermission, + /// The given asset ID is unknown. + Unknown, + /// Recipient's address is zero. + ZeroRecipientAddress, + /// Sender's address is zero. + ZeroSenderAddress, +} +#[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] +const _: () = { + impl ::scale_info::TypeInfo for FungiblesError { + type Identity = Self; + fn type_info() -> ::scale_info::Type { + ::scale_info::Type::builder() + .path( + ::scale_info::Path::new_with_replace( + "FungiblesError", + "fungibles", + &[], + ), + ) + .type_params(::alloc::vec::Vec::new()) + .variant( + ::scale_info::build::Variants::new() + .variant( + "InsufficientBalance", + |v| { + v + .index(0usize as ::core::primitive::u8) + .docs( + &["Not enough balance to fulfill a request is available."], + ) + }, + ) + .variant( + "InsufficientAllowance", + |v| { + v + .index(1usize as ::core::primitive::u8) + .docs( + &["Not enough allowance to fulfill a request is available."], + ) + }, + ) + .variant( + "IncorrectStatus", + |v| { + v + .index(2usize as ::core::primitive::u8) + .docs(&["The asset status is not the expected status."]) + }, + ) + .variant( + "InUse", + |v| { + v + .index(3usize as ::core::primitive::u8) + .docs(&["The asset ID is already taken."]) + }, + ) + .variant( + "MinBalanceZero", + |v| { + v + .index(4usize as ::core::primitive::u8) + .docs(&["Minimum balance should be non-zero."]) + }, + ) + .variant( + "NoPermission", + |v| { + v + .index(5usize as ::core::primitive::u8) + .docs( + &[ + "The signing account has no permission to do the operation.", + ], + ) + }, + ) + .variant( + "Unknown", + |v| { + v + .index(6usize as ::core::primitive::u8) + .docs(&["The given asset ID is unknown."]) + }, + ) + .variant( + "ZeroRecipientAddress", + |v| { + v + .index(7usize as ::core::primitive::u8) + .docs(&["Recipient's address is zero."]) + }, + ) + .variant( + "ZeroSenderAddress", + |v| { + v + .index(8usize as ::core::primitive::u8) + .docs(&["Sender's address is zero."]) + }, + ), + ) + } + } +}; +#[automatically_derived] +impl ::core::fmt::Debug for FungiblesError { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::write_str( + f, + match self { + FungiblesError::InsufficientBalance => "InsufficientBalance", + FungiblesError::InsufficientAllowance => "InsufficientAllowance", + FungiblesError::IncorrectStatus => "IncorrectStatus", + FungiblesError::InUse => "InUse", + FungiblesError::MinBalanceZero => "MinBalanceZero", + FungiblesError::NoPermission => "NoPermission", + FungiblesError::Unknown => "Unknown", + FungiblesError::ZeroRecipientAddress => "ZeroRecipientAddress", + FungiblesError::ZeroSenderAddress => "ZeroSenderAddress", + }, + ) + } +} +#[automatically_derived] +impl ::core::marker::Copy for FungiblesError {} +#[automatically_derived] +impl ::core::clone::Clone for FungiblesError { + #[inline] + fn clone(&self) -> FungiblesError { + *self + } +} +#[automatically_derived] +impl ::core::marker::StructuralPartialEq for FungiblesError {} +#[automatically_derived] +impl ::core::cmp::PartialEq for FungiblesError { + #[inline] + fn eq(&self, other: &FungiblesError) -> bool { + let __self_tag = ::core::intrinsics::discriminant_value(self); + let __arg1_tag = ::core::intrinsics::discriminant_value(other); + __self_tag == __arg1_tag + } +} +#[automatically_derived] +impl ::core::cmp::Eq for FungiblesError { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () {} +} +#[allow(deprecated)] +const _: () = { + #[automatically_derived] + impl ::scale::Encode for FungiblesError { + fn size_hint(&self) -> usize { + 1_usize + + match *self { + FungiblesError::InsufficientBalance => 0_usize, + FungiblesError::InsufficientAllowance => 0_usize, + FungiblesError::IncorrectStatus => 0_usize, + FungiblesError::InUse => 0_usize, + FungiblesError::MinBalanceZero => 0_usize, + FungiblesError::NoPermission => 0_usize, + FungiblesError::Unknown => 0_usize, + FungiblesError::ZeroRecipientAddress => 0_usize, + FungiblesError::ZeroSenderAddress => 0_usize, + _ => 0_usize, + } + } + fn encode_to<__CodecOutputEdqy: ::scale::Output + ?::core::marker::Sized>( + &self, + __codec_dest_edqy: &mut __CodecOutputEdqy, + ) { + match *self { + FungiblesError::InsufficientBalance => { + #[allow(clippy::unnecessary_cast)] + __codec_dest_edqy.push_byte(0usize as ::core::primitive::u8); + } + FungiblesError::InsufficientAllowance => { + #[allow(clippy::unnecessary_cast)] + __codec_dest_edqy.push_byte(1usize as ::core::primitive::u8); + } + FungiblesError::IncorrectStatus => { + #[allow(clippy::unnecessary_cast)] + __codec_dest_edqy.push_byte(2usize as ::core::primitive::u8); + } + FungiblesError::InUse => { + #[allow(clippy::unnecessary_cast)] + __codec_dest_edqy.push_byte(3usize as ::core::primitive::u8); + } + FungiblesError::MinBalanceZero => { + #[allow(clippy::unnecessary_cast)] + __codec_dest_edqy.push_byte(4usize as ::core::primitive::u8); + } + FungiblesError::NoPermission => { + #[allow(clippy::unnecessary_cast)] + __codec_dest_edqy.push_byte(5usize as ::core::primitive::u8); + } + FungiblesError::Unknown => { + #[allow(clippy::unnecessary_cast)] + __codec_dest_edqy.push_byte(6usize as ::core::primitive::u8); + } + FungiblesError::ZeroRecipientAddress => { + #[allow(clippy::unnecessary_cast)] + __codec_dest_edqy.push_byte(7usize as ::core::primitive::u8); + } + FungiblesError::ZeroSenderAddress => { + #[allow(clippy::unnecessary_cast)] + __codec_dest_edqy.push_byte(8usize as ::core::primitive::u8); + } + _ => {} + } + } + } + #[automatically_derived] + impl ::scale::EncodeLike for FungiblesError {} +}; +#[allow(deprecated)] +const _: () = { + #[automatically_derived] + impl ::scale::Decode for FungiblesError { + fn decode<__CodecInputEdqy: ::scale::Input>( + __codec_input_edqy: &mut __CodecInputEdqy, + ) -> ::core::result::Result { + match __codec_input_edqy + .read_byte() + .map_err(|e| { + e + .chain( + "Could not decode `FungiblesError`, failed to read variant byte", + ) + })? + { + #[allow(clippy::unnecessary_cast)] + __codec_x_edqy if __codec_x_edqy == 0usize as ::core::primitive::u8 => { + #[allow(clippy::redundant_closure_call)] + return (move || { + ::core::result::Result::Ok(FungiblesError::InsufficientBalance) + })(); + } + #[allow(clippy::unnecessary_cast)] + __codec_x_edqy if __codec_x_edqy == 1usize as ::core::primitive::u8 => { + #[allow(clippy::redundant_closure_call)] + return (move || { + ::core::result::Result::Ok(FungiblesError::InsufficientAllowance) + })(); + } + #[allow(clippy::unnecessary_cast)] + __codec_x_edqy if __codec_x_edqy == 2usize as ::core::primitive::u8 => { + #[allow(clippy::redundant_closure_call)] + return (move || { + ::core::result::Result::Ok(FungiblesError::IncorrectStatus) + })(); + } + #[allow(clippy::unnecessary_cast)] + __codec_x_edqy if __codec_x_edqy == 3usize as ::core::primitive::u8 => { + #[allow(clippy::redundant_closure_call)] + return (move || { + ::core::result::Result::Ok(FungiblesError::InUse) + })(); + } + #[allow(clippy::unnecessary_cast)] + __codec_x_edqy if __codec_x_edqy == 4usize as ::core::primitive::u8 => { + #[allow(clippy::redundant_closure_call)] + return (move || { + ::core::result::Result::Ok(FungiblesError::MinBalanceZero) + })(); + } + #[allow(clippy::unnecessary_cast)] + __codec_x_edqy if __codec_x_edqy == 5usize as ::core::primitive::u8 => { + #[allow(clippy::redundant_closure_call)] + return (move || { + ::core::result::Result::Ok(FungiblesError::NoPermission) + })(); + } + #[allow(clippy::unnecessary_cast)] + __codec_x_edqy if __codec_x_edqy == 6usize as ::core::primitive::u8 => { + #[allow(clippy::redundant_closure_call)] + return (move || { + ::core::result::Result::Ok(FungiblesError::Unknown) + })(); + } + #[allow(clippy::unnecessary_cast)] + __codec_x_edqy if __codec_x_edqy == 7usize as ::core::primitive::u8 => { + #[allow(clippy::redundant_closure_call)] + return (move || { + ::core::result::Result::Ok(FungiblesError::ZeroRecipientAddress) + })(); + } + #[allow(clippy::unnecessary_cast)] + __codec_x_edqy if __codec_x_edqy == 8usize as ::core::primitive::u8 => { + #[allow(clippy::redundant_closure_call)] + return (move || { + ::core::result::Result::Ok(FungiblesError::ZeroSenderAddress) + })(); + } + _ => { + #[allow(clippy::redundant_closure_call)] + return (move || { + ::core::result::Result::Err( + <_ as ::core::convert::Into< + _, + >>::into( + "Could not decode `FungiblesError`, variant doesn't exist", + ), + ) + })(); + } + } + } + } +}; +impl From for FungiblesError { + fn from(error: Error) -> Self { + match error { + Error::InUse => FungiblesError::InUse, + Error::MinBalanceZero => FungiblesError::MinBalanceZero, + Error::Unknown => FungiblesError::Unknown, + _ => ::core::panicking::panic("not yet implemented"), + } + } +} +/// The fungibles result type. +pub type Result = core::result::Result; +mod fungibles { + impl ::ink::env::ContractEnv for Fungibles { + type Env = pop_api::Environment; + } + type Environment = ::Env; + type AccountId = <::Env as ::ink::env::Environment>::AccountId; + type Balance = <::Env as ::ink::env::Environment>::Balance; + type Hash = <::Env as ::ink::env::Environment>::Hash; + type Timestamp = <::Env as ::ink::env::Environment>::Timestamp; + type BlockNumber = <::Env as ::ink::env::Environment>::BlockNumber; + type ChainExtension = <::Env as ::ink::env::Environment>::ChainExtension; + const MAX_EVENT_TOPICS: usize = <::Env as ::ink::env::Environment>::MAX_EVENT_TOPICS; + const _: () = { + struct Check { + salt: (), + } + }; + #[scale_info(crate = ::ink::scale_info)] + #[cfg(not(feature = "__ink_dylint_Storage"))] + pub struct Fungibles {} + const _: () = { + impl< + __ink_generic_salt: ::ink::storage::traits::StorageKey, + > ::ink::storage::traits::StorableHint<__ink_generic_salt> for Fungibles { + type Type = Fungibles; + type PreferredKey = ::ink::storage::traits::AutoKey; + } + }; + const _: () = { + impl ::ink::storage::traits::StorageKey for Fungibles { + const KEY: ::ink::primitives::Key = <() as ::ink::storage::traits::StorageKey>::KEY; + } + }; + const _: () = { + impl ::ink::storage::traits::Storable for Fungibles { + #[inline(always)] + #[allow(non_camel_case_types)] + fn decode<__ink_I: ::ink::scale::Input>( + __input: &mut __ink_I, + ) -> ::core::result::Result { + ::core::result::Result::Ok(Fungibles {}) + } + #[inline(always)] + #[allow(non_camel_case_types)] + fn encode<__ink_O: ::ink::scale::Output + ?::core::marker::Sized>( + &self, + __dest: &mut __ink_O, + ) { + match self { + Fungibles {} => {} + } + } + #[inline(always)] + #[allow(non_camel_case_types)] + fn encoded_size(&self) -> ::core::primitive::usize { + match self { + Fungibles {} => ::core::primitive::usize::MIN, + } + } + } + }; + #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] + const _: () = { + impl ::ink::scale_info::TypeInfo for Fungibles { + type Identity = Self; + fn type_info() -> ::ink::scale_info::Type { + ::ink::scale_info::Type::builder() + .path( + ::ink::scale_info::Path::new_with_replace( + "Fungibles", + "fungibles::fungibles", + &[], + ), + ) + .type_params(::alloc::vec::Vec::new()) + .composite(::ink::scale_info::build::Fields::named()) + } + } + }; + const _: () = { + impl ::ink::storage::traits::StorageLayout for Fungibles { + fn layout( + __key: &::ink::primitives::Key, + ) -> ::ink::metadata::layout::Layout { + ::ink::metadata::layout::Layout::Struct( + ::ink::metadata::layout::StructLayout::new("Fungibles", []), + ) + } + } + }; + #[automatically_derived] + impl ::core::default::Default for Fungibles { + #[inline] + fn default() -> Fungibles { + Fungibles {} + } + } + const _: () = { + impl ::ink::reflect::ContractName for Fungibles { + const NAME: &'static str = "Fungibles"; + } + }; + const _: () = { + impl<'a> ::ink::codegen::Env for &'a Fungibles { + type EnvAccess = ::ink::EnvAccess< + 'a, + ::Env, + >; + fn env(self) -> Self::EnvAccess { + <::EnvAccess as ::core::default::Default>::default() + } + } + impl<'a> ::ink::codegen::StaticEnv for Fungibles { + type EnvAccess = ::ink::EnvAccess< + 'static, + ::Env, + >; + fn env() -> Self::EnvAccess { + <::EnvAccess as ::core::default::Default>::default() + } + } + }; + const _: () = { + #[allow(unused_imports)] + use ::ink::codegen::{Env as _, StaticEnv as _}; + }; + impl ::ink::reflect::DispatchableConstructorInfo<0x9BAE9D5E_u32> for Fungibles { + type Input = (); + type Output = Self; + type Storage = Fungibles; + type Error = <::ink::reflect::ConstructorOutputValue< + Self, + > as ::ink::reflect::ConstructorOutput>::Error; + const IS_RESULT: ::core::primitive::bool = <::ink::reflect::ConstructorOutputValue< + Self, + > as ::ink::reflect::ConstructorOutput>::IS_RESULT; + const CALLABLE: fn(Self::Input) -> Self::Output = |_| { Fungibles::new() }; + const PAYABLE: ::core::primitive::bool = true; + const SELECTOR: [::core::primitive::u8; 4usize] = [ + 0x9B_u8, + 0xAE_u8, + 0x9D_u8, + 0x5E_u8, + ]; + const LABEL: &'static ::core::primitive::str = "new"; + } + impl ::ink::reflect::DispatchableMessageInfo<0xDB6375A8_u32> for Fungibles { + type Input = AssetId; + type Output = Result; + type Storage = Fungibles; + const CALLABLE: fn(&mut Self::Storage, Self::Input) -> Self::Output = | + storage, + __ink_binding_0| + { Fungibles::total_supply(storage, __ink_binding_0) }; + const SELECTOR: [::core::primitive::u8; 4usize] = [ + 0xDB_u8, + 0x63_u8, + 0x75_u8, + 0xA8_u8, + ]; + const PAYABLE: ::core::primitive::bool = false; + const MUTATES: ::core::primitive::bool = false; + const LABEL: &'static ::core::primitive::str = "total_supply"; + } + impl ::ink::reflect::DispatchableMessageInfo<0x0F755A56_u32> for Fungibles { + type Input = (AssetId, AccountId32); + type Output = Result; + type Storage = Fungibles; + const CALLABLE: fn(&mut Self::Storage, Self::Input) -> Self::Output = | + storage, + (__ink_binding_0, __ink_binding_1)| + { Fungibles::balance_of(storage, __ink_binding_0, __ink_binding_1) }; + const SELECTOR: [::core::primitive::u8; 4usize] = [ + 0x0F_u8, + 0x75_u8, + 0x5A_u8, + 0x56_u8, + ]; + const PAYABLE: ::core::primitive::bool = false; + const MUTATES: ::core::primitive::bool = false; + const LABEL: &'static ::core::primitive::str = "balance_of"; + } + impl ::ink::reflect::DispatchableMessageInfo<0x6A00165E_u32> for Fungibles { + type Input = (AssetId, AccountId32, AccountId32); + type Output = Result; + type Storage = Fungibles; + const CALLABLE: fn(&mut Self::Storage, Self::Input) -> Self::Output = | + storage, + (__ink_binding_0, __ink_binding_1, __ink_binding_2)| + { + Fungibles::allowance( + storage, + __ink_binding_0, + __ink_binding_1, + __ink_binding_2, + ) + }; + const SELECTOR: [::core::primitive::u8; 4usize] = [ + 0x6A_u8, + 0x00_u8, + 0x16_u8, + 0x5E_u8, + ]; + const PAYABLE: ::core::primitive::bool = false; + const MUTATES: ::core::primitive::bool = false; + const LABEL: &'static ::core::primitive::str = "allowance"; + } + impl ::ink::reflect::DispatchableMessageInfo<0xAA6B65DB_u32> for Fungibles { + type Input = AssetId; + type Output = Result; + type Storage = Fungibles; + const CALLABLE: fn(&mut Self::Storage, Self::Input) -> Self::Output = | + storage, + __ink_binding_0| + { Fungibles::asset_exists(storage, __ink_binding_0) }; + const SELECTOR: [::core::primitive::u8; 4usize] = [ + 0xAA_u8, + 0x6B_u8, + 0x65_u8, + 0xDB_u8, + ]; + const PAYABLE: ::core::primitive::bool = false; + const MUTATES: ::core::primitive::bool = false; + const LABEL: &'static ::core::primitive::str = "asset_exists"; + } + impl ::ink::reflect::DispatchableMessageInfo<0x1F8E8E22_u32> for Fungibles { + type Input = (u32, AccountId32, Balance); + type Output = Result<()>; + type Storage = Fungibles; + const CALLABLE: fn(&mut Self::Storage, Self::Input) -> Self::Output = | + storage, + (__ink_binding_0, __ink_binding_1, __ink_binding_2)| + { + Fungibles::mint_asset( + storage, + __ink_binding_0, + __ink_binding_1, + __ink_binding_2, + ) + }; + const SELECTOR: [::core::primitive::u8; 4usize] = [ + 0x1F_u8, + 0x8E_u8, + 0x8E_u8, + 0x22_u8, + ]; + const PAYABLE: ::core::primitive::bool = false; + const MUTATES: ::core::primitive::bool = false; + const LABEL: &'static ::core::primitive::str = "mint_asset"; + } + const _: () = { + #[allow(non_camel_case_types)] + pub enum __ink_ConstructorDecoder { + Constructor0( + >::Input, + ), + } + impl ::ink::reflect::DecodeDispatch for __ink_ConstructorDecoder { + fn decode_dispatch( + input: &mut I, + ) -> ::core::result::Result + where + I: ::ink::scale::Input, + { + const CONSTRUCTOR_0: [::core::primitive::u8; 4usize] = >::SELECTOR; + match <[::core::primitive::u8; 4usize] as ::ink::scale::Decode>::decode( + input, + ) + .map_err(|_| ::ink::reflect::DispatchError::InvalidSelector)? + { + CONSTRUCTOR_0 => { + ::core::result::Result::Ok( + Self::Constructor0( + <>::Input as ::ink::scale::Decode>::decode(input) + .map_err(|_| { + ::ink::reflect::DispatchError::InvalidParameters + })?, + ), + ) + } + _invalid => { + ::core::result::Result::Err( + ::ink::reflect::DispatchError::UnknownSelector, + ) + } + } + } + } + impl ::ink::scale::Decode for __ink_ConstructorDecoder { + fn decode( + input: &mut I, + ) -> ::core::result::Result + where + I: ::ink::scale::Input, + { + ::decode_dispatch(input) + .map_err(::core::convert::Into::into) + } + } + impl ::ink::reflect::ExecuteDispatchable for __ink_ConstructorDecoder { + #[allow(clippy::nonminimal_bool)] + fn execute_dispatchable( + self, + ) -> ::core::result::Result<(), ::ink::reflect::DispatchError> { + match self { + Self::Constructor0(input) => { + if { + false + || { + let constructor_0 = false; + let constructor_0 = >::PAYABLE; + constructor_0 + } + } + && !>::PAYABLE + { + ::ink::codegen::deny_payment::< + ::Env, + >()?; + } + let result: >::Output = >::CALLABLE(input); + let output_value = ::ink::reflect::ConstructorOutputValue::new( + result, + ); + let output_result = <::ink::reflect::ConstructorOutputValue< + >::Output, + > as ::ink::reflect::ConstructorOutput< + Fungibles, + >>::as_result(&output_value); + if let ::core::result::Result::Ok(contract) = output_result + .as_ref() + { + ::ink::env::set_contract_storage::< + ::ink::primitives::Key, + Fungibles, + >( + &::KEY, + contract, + ); + } + let mut flag = ::ink::env::ReturnFlags::empty(); + if output_result.is_err() { + flag = ::ink::env::ReturnFlags::REVERT; + } + ::ink::env::return_value::< + ::ink::ConstructorResult< + ::core::result::Result< + (), + &<::ink::reflect::ConstructorOutputValue< + >::Output, + > as ::ink::reflect::ConstructorOutput>::Error, + >, + >, + >( + flag, + &::ink::ConstructorResult::Ok(output_result.map(|_| ())), + ); + } + } + } + } + impl ::ink::reflect::ContractConstructorDecoder for Fungibles { + type Type = __ink_ConstructorDecoder; + } + }; + const _: () = { + #[allow(non_camel_case_types)] + pub enum __ink_MessageDecoder { + Message0( + >::Input, + ), + Message1( + >::Input, + ), + Message2( + >::Input, + ), + Message3( + >::Input, + ), + Message4( + >::Input, + ), + } + impl ::ink::reflect::DecodeDispatch for __ink_MessageDecoder { + fn decode_dispatch( + input: &mut I, + ) -> ::core::result::Result + where + I: ::ink::scale::Input, + { + const MESSAGE_0: [::core::primitive::u8; 4usize] = >::SELECTOR; + const MESSAGE_1: [::core::primitive::u8; 4usize] = >::SELECTOR; + const MESSAGE_2: [::core::primitive::u8; 4usize] = >::SELECTOR; + const MESSAGE_3: [::core::primitive::u8; 4usize] = >::SELECTOR; + const MESSAGE_4: [::core::primitive::u8; 4usize] = >::SELECTOR; + match <[::core::primitive::u8; 4usize] as ::ink::scale::Decode>::decode( + input, + ) + .map_err(|_| ::ink::reflect::DispatchError::InvalidSelector)? + { + MESSAGE_0 => { + ::core::result::Result::Ok( + Self::Message0( + <>::Input as ::ink::scale::Decode>::decode(input) + .map_err(|_| { + ::ink::reflect::DispatchError::InvalidParameters + })?, + ), + ) + } + MESSAGE_1 => { + ::core::result::Result::Ok( + Self::Message1( + <>::Input as ::ink::scale::Decode>::decode(input) + .map_err(|_| { + ::ink::reflect::DispatchError::InvalidParameters + })?, + ), + ) + } + MESSAGE_2 => { + ::core::result::Result::Ok( + Self::Message2( + <>::Input as ::ink::scale::Decode>::decode(input) + .map_err(|_| { + ::ink::reflect::DispatchError::InvalidParameters + })?, + ), + ) + } + MESSAGE_3 => { + ::core::result::Result::Ok( + Self::Message3( + <>::Input as ::ink::scale::Decode>::decode(input) + .map_err(|_| { + ::ink::reflect::DispatchError::InvalidParameters + })?, + ), + ) + } + MESSAGE_4 => { + ::core::result::Result::Ok( + Self::Message4( + <>::Input as ::ink::scale::Decode>::decode(input) + .map_err(|_| { + ::ink::reflect::DispatchError::InvalidParameters + })?, + ), + ) + } + _invalid => { + ::core::result::Result::Err( + ::ink::reflect::DispatchError::UnknownSelector, + ) + } + } + } + } + impl ::ink::scale::Decode for __ink_MessageDecoder { + fn decode( + input: &mut I, + ) -> ::core::result::Result + where + I: ::ink::scale::Input, + { + ::decode_dispatch(input) + .map_err(::core::convert::Into::into) + } + } + fn push_contract(contract: ::core::mem::ManuallyDrop, mutates: bool) { + if mutates { + ::ink::env::set_contract_storage::< + ::ink::primitives::Key, + Fungibles, + >(&::KEY, &contract); + } + } + impl ::ink::reflect::ExecuteDispatchable for __ink_MessageDecoder { + #[allow(clippy::nonminimal_bool, clippy::let_unit_value)] + fn execute_dispatchable( + self, + ) -> ::core::result::Result<(), ::ink::reflect::DispatchError> { + let key = ::KEY; + let mut contract: ::core::mem::ManuallyDrop = ::core::mem::ManuallyDrop::new( + match ::ink::env::get_contract_storage(&key) { + ::core::result::Result::Ok( + ::core::option::Option::Some(value), + ) => value, + ::core::result::Result::Ok(::core::option::Option::None) => { + ::core::panicking::panic_fmt( + format_args!("storage entry was empty"), + ); + } + ::core::result::Result::Err(_) => { + ::core::panicking::panic_fmt( + format_args!("could not properly decode storage entry"), + ); + } + }, + ); + match self { + Self::Message0(input) => { + if { + false + || { + let message_0 = false; + let message_0 = >::PAYABLE; + message_0 + } + || { + let message_1 = false; + let message_1 = >::PAYABLE; + message_1 + } + || { + let message_2 = false; + let message_2 = >::PAYABLE; + message_2 + } + || { + let message_3 = false; + let message_3 = >::PAYABLE; + message_3 + } + || { + let message_4 = false; + let message_4 = >::PAYABLE; + message_4 + } + } + && !>::PAYABLE + { + ::ink::codegen::deny_payment::< + ::Env, + >()?; + } + let result: >::Output = >::CALLABLE(&mut contract, input); + let is_reverted = { + #[allow(unused_imports)] + use ::ink::result_info::IsResultTypeFallback as _; + ::ink::result_info::IsResultType::< + >::Output, + >::VALUE + } + && { + #[allow(unused_imports)] + use ::ink::result_info::IsResultErrFallback as _; + ::ink::result_info::IsResultErr(&result).value() + }; + let mut flag = ::ink::env::ReturnFlags::REVERT; + if !is_reverted { + flag = ::ink::env::ReturnFlags::empty(); + push_contract( + contract, + >::MUTATES, + ); + } + ::ink::env::return_value::< + ::ink::MessageResult< + >::Output, + >, + >(flag, &::ink::MessageResult::Ok(result)) + } + Self::Message1(input) => { + if { + false + || { + let message_0 = false; + let message_0 = >::PAYABLE; + message_0 + } + || { + let message_1 = false; + let message_1 = >::PAYABLE; + message_1 + } + || { + let message_2 = false; + let message_2 = >::PAYABLE; + message_2 + } + || { + let message_3 = false; + let message_3 = >::PAYABLE; + message_3 + } + || { + let message_4 = false; + let message_4 = >::PAYABLE; + message_4 + } + } + && !>::PAYABLE + { + ::ink::codegen::deny_payment::< + ::Env, + >()?; + } + let result: >::Output = >::CALLABLE(&mut contract, input); + let is_reverted = { + #[allow(unused_imports)] + use ::ink::result_info::IsResultTypeFallback as _; + ::ink::result_info::IsResultType::< + >::Output, + >::VALUE + } + && { + #[allow(unused_imports)] + use ::ink::result_info::IsResultErrFallback as _; + ::ink::result_info::IsResultErr(&result).value() + }; + let mut flag = ::ink::env::ReturnFlags::REVERT; + if !is_reverted { + flag = ::ink::env::ReturnFlags::empty(); + push_contract( + contract, + >::MUTATES, + ); + } + ::ink::env::return_value::< + ::ink::MessageResult< + >::Output, + >, + >(flag, &::ink::MessageResult::Ok(result)) + } + Self::Message2(input) => { + if { + false + || { + let message_0 = false; + let message_0 = >::PAYABLE; + message_0 + } + || { + let message_1 = false; + let message_1 = >::PAYABLE; + message_1 + } + || { + let message_2 = false; + let message_2 = >::PAYABLE; + message_2 + } + || { + let message_3 = false; + let message_3 = >::PAYABLE; + message_3 + } + || { + let message_4 = false; + let message_4 = >::PAYABLE; + message_4 + } + } + && !>::PAYABLE + { + ::ink::codegen::deny_payment::< + ::Env, + >()?; + } + let result: >::Output = >::CALLABLE(&mut contract, input); + let is_reverted = { + #[allow(unused_imports)] + use ::ink::result_info::IsResultTypeFallback as _; + ::ink::result_info::IsResultType::< + >::Output, + >::VALUE + } + && { + #[allow(unused_imports)] + use ::ink::result_info::IsResultErrFallback as _; + ::ink::result_info::IsResultErr(&result).value() + }; + let mut flag = ::ink::env::ReturnFlags::REVERT; + if !is_reverted { + flag = ::ink::env::ReturnFlags::empty(); + push_contract( + contract, + >::MUTATES, + ); + } + ::ink::env::return_value::< + ::ink::MessageResult< + >::Output, + >, + >(flag, &::ink::MessageResult::Ok(result)) + } + Self::Message3(input) => { + if { + false + || { + let message_0 = false; + let message_0 = >::PAYABLE; + message_0 + } + || { + let message_1 = false; + let message_1 = >::PAYABLE; + message_1 + } + || { + let message_2 = false; + let message_2 = >::PAYABLE; + message_2 + } + || { + let message_3 = false; + let message_3 = >::PAYABLE; + message_3 + } + || { + let message_4 = false; + let message_4 = >::PAYABLE; + message_4 + } + } + && !>::PAYABLE + { + ::ink::codegen::deny_payment::< + ::Env, + >()?; + } + let result: >::Output = >::CALLABLE(&mut contract, input); + let is_reverted = { + #[allow(unused_imports)] + use ::ink::result_info::IsResultTypeFallback as _; + ::ink::result_info::IsResultType::< + >::Output, + >::VALUE + } + && { + #[allow(unused_imports)] + use ::ink::result_info::IsResultErrFallback as _; + ::ink::result_info::IsResultErr(&result).value() + }; + let mut flag = ::ink::env::ReturnFlags::REVERT; + if !is_reverted { + flag = ::ink::env::ReturnFlags::empty(); + push_contract( + contract, + >::MUTATES, + ); + } + ::ink::env::return_value::< + ::ink::MessageResult< + >::Output, + >, + >(flag, &::ink::MessageResult::Ok(result)) + } + Self::Message4(input) => { + if { + false + || { + let message_0 = false; + let message_0 = >::PAYABLE; + message_0 + } + || { + let message_1 = false; + let message_1 = >::PAYABLE; + message_1 + } + || { + let message_2 = false; + let message_2 = >::PAYABLE; + message_2 + } + || { + let message_3 = false; + let message_3 = >::PAYABLE; + message_3 + } + || { + let message_4 = false; + let message_4 = >::PAYABLE; + message_4 + } + } + && !>::PAYABLE + { + ::ink::codegen::deny_payment::< + ::Env, + >()?; + } + let result: >::Output = >::CALLABLE(&mut contract, input); + let is_reverted = { + #[allow(unused_imports)] + use ::ink::result_info::IsResultTypeFallback as _; + ::ink::result_info::IsResultType::< + >::Output, + >::VALUE + } + && { + #[allow(unused_imports)] + use ::ink::result_info::IsResultErrFallback as _; + ::ink::result_info::IsResultErr(&result).value() + }; + let mut flag = ::ink::env::ReturnFlags::REVERT; + if !is_reverted { + flag = ::ink::env::ReturnFlags::empty(); + push_contract( + contract, + >::MUTATES, + ); + } + ::ink::env::return_value::< + ::ink::MessageResult< + >::Output, + >, + >(flag, &::ink::MessageResult::Ok(result)) + } + }; + } + } + impl ::ink::reflect::ContractMessageDecoder for Fungibles { + type Type = __ink_MessageDecoder; + } + }; + const _: () = { + use ::ink::codegen::{Env as _, StaticEnv as _}; + const _: ::ink::codegen::utils::IsSameType = ::ink::codegen::utils::IsSameType::< + Fungibles, + >::new(); + impl Fungibles { + #[cfg(not(feature = "__ink_dylint_Constructor"))] + pub fn new() -> Self { + ::ink_env::debug_message( + &{ + let res = ::alloc::fmt::format( + format_args!( + "{0}\n", + { + let res = ::alloc::fmt::format( + format_args!("PopApiAssetsExample::new"), + ); + res + }, + ), + ); + res + }, + ); + Default::default() + } + pub fn total_supply(&self, id: AssetId) -> Result { + total_supply(id).map_err(From::from) + } + pub fn balance_of( + &self, + id: AssetId, + owner: AccountId32, + ) -> Result { + balance_of(id, owner).map_err(From::from) + } + pub fn allowance( + &self, + id: AssetId, + owner: AccountId32, + spender: AccountId32, + ) -> Result { + allowance(id, owner, spender).map_err(From::from) + } + pub fn asset_exists(&self, id: AssetId) -> Result { + asset_exists(id).map_err(From::from) + } + pub fn mint_asset( + &self, + id: u32, + beneficiary: AccountId32, + amount: Balance, + ) -> Result<()> { + ::ink_env::debug_message( + &{ + let res = ::alloc::fmt::format( + format_args!( + "{0}\n", + { + let res = ::alloc::fmt::format( + format_args!( + "PopApiAssetsExample::mint_asset_through_runtime: id: {0:?} beneficiary: {1:?} amount: {2:?}", + id, + beneficiary, + amount, + ), + ); + res + }, + ), + ); + res + }, + ); + let result = mint(id, beneficiary, amount)?; + ::ink_env::debug_message( + &{ + let res = ::alloc::fmt::format( + format_args!( + "{0}\n", + { + let res = ::alloc::fmt::format( + format_args!("Result: {0:?}", result), + ); + res + }, + ), + ); + res + }, + ); + Ok(()) + } + } + const _: () = { + ::ink::codegen::utils::consume_type::< + ::ink::codegen::DispatchInput, + >(); + ::ink::codegen::utils::consume_type::< + ::ink::codegen::DispatchOutput>, + >(); + ::ink::codegen::utils::consume_type::< + ::ink::codegen::DispatchInput, + >(); + ::ink::codegen::utils::consume_type::< + ::ink::codegen::DispatchInput, + >(); + ::ink::codegen::utils::consume_type::< + ::ink::codegen::DispatchOutput>, + >(); + ::ink::codegen::utils::consume_type::< + ::ink::codegen::DispatchInput, + >(); + ::ink::codegen::utils::consume_type::< + ::ink::codegen::DispatchInput, + >(); + ::ink::codegen::utils::consume_type::< + ::ink::codegen::DispatchInput, + >(); + ::ink::codegen::utils::consume_type::< + ::ink::codegen::DispatchOutput>, + >(); + ::ink::codegen::utils::consume_type::< + ::ink::codegen::DispatchInput, + >(); + ::ink::codegen::utils::consume_type::< + ::ink::codegen::DispatchOutput>, + >(); + ::ink::codegen::utils::consume_type::<::ink::codegen::DispatchInput>(); + ::ink::codegen::utils::consume_type::< + ::ink::codegen::DispatchInput, + >(); + ::ink::codegen::utils::consume_type::< + ::ink::codegen::DispatchInput, + >(); + ::ink::codegen::utils::consume_type::< + ::ink::codegen::DispatchOutput>, + >(); + }; + }; + const _: () = { + #[codec(crate = ::ink::scale)] + #[scale_info(crate = ::ink::scale_info)] + /// The ink! smart contract's call builder. + /// + /// Implements the underlying on-chain calling of the ink! smart contract + /// messages and trait implementations in a type safe way. + #[repr(transparent)] + pub struct CallBuilder { + account_id: AccountId, + } + #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] + const _: () = { + impl ::ink::scale_info::TypeInfo for CallBuilder { + type Identity = Self; + fn type_info() -> ::ink::scale_info::Type { + ::ink::scale_info::Type::builder() + .path( + ::ink::scale_info::Path::new_with_replace( + "CallBuilder", + "fungibles::fungibles", + &[], + ), + ) + .type_params(::alloc::vec::Vec::new()) + .docs( + &[ + "The ink! smart contract's call builder.", + "", + "Implements the underlying on-chain calling of the ink! smart contract", + "messages and trait implementations in a type safe way.", + ], + ) + .composite( + ::ink::scale_info::build::Fields::named() + .field(|f| { + f + .ty::() + .name("account_id") + .type_name("AccountId") + }), + ) + } + } + }; + #[allow(deprecated)] + const _: () = { + #[automatically_derived] + impl ::ink::scale::Decode for CallBuilder { + fn decode<__CodecInputEdqy: ::ink::scale::Input>( + __codec_input_edqy: &mut __CodecInputEdqy, + ) -> ::core::result::Result { + ::core::result::Result::Ok(CallBuilder { + account_id: { + let __codec_res_edqy = ::decode( + __codec_input_edqy, + ); + match __codec_res_edqy { + ::core::result::Result::Err(e) => { + return ::core::result::Result::Err( + e.chain("Could not decode `CallBuilder::account_id`"), + ); + } + ::core::result::Result::Ok(__codec_res_edqy) => { + __codec_res_edqy + } + } + }, + }) + } + fn decode_into<__CodecInputEdqy: ::ink::scale::Input>( + __codec_input_edqy: &mut __CodecInputEdqy, + dst_: &mut ::core::mem::MaybeUninit, + ) -> ::core::result::Result< + ::ink::scale::DecodeFinished, + ::ink::scale::Error, + > { + match ( + &::core::mem::size_of::(), + &::core::mem::size_of::(), + ) { + (left_val, right_val) => { + if !(*left_val == *right_val) { + let kind = ::core::panicking::AssertKind::Eq; + ::core::panicking::assert_failed( + kind, + &*left_val, + &*right_val, + ::core::option::Option::None, + ); + } + } + }; + if !(if ::core::mem::size_of::() > 0 { 1 } else { 0 } + <= 1) + { + ::core::panicking::panic( + "assertion failed: if ::core::mem::size_of::() > 0 { 1 } else { 0 } <= 1", + ) + } + { + let dst_: &mut ::core::mem::MaybeUninit = dst_; + let dst_: &mut ::core::mem::MaybeUninit = unsafe { + &mut *dst_ + .as_mut_ptr() + .cast::<::core::mem::MaybeUninit>() + }; + ::decode_into( + __codec_input_edqy, + dst_, + )?; + } + unsafe { + ::core::result::Result::Ok( + ::ink::scale::DecodeFinished::assert_decoding_finished(), + ) + } + } + } + }; + #[allow(deprecated)] + const _: () = { + #[automatically_derived] + impl ::ink::scale::Encode for CallBuilder { + fn size_hint(&self) -> usize { + ::ink::scale::Encode::size_hint(&&self.account_id) + } + fn encode_to< + __CodecOutputEdqy: ::ink::scale::Output + ?::core::marker::Sized, + >(&self, __codec_dest_edqy: &mut __CodecOutputEdqy) { + ::ink::scale::Encode::encode_to(&&self.account_id, __codec_dest_edqy) + } + fn encode( + &self, + ) -> ::ink::scale::alloc::vec::Vec<::core::primitive::u8> { + ::ink::scale::Encode::encode(&&self.account_id) + } + fn using_encoded< + __CodecOutputReturn, + __CodecUsingEncodedCallback: ::core::ops::FnOnce( + &[::core::primitive::u8], + ) -> __CodecOutputReturn, + >(&self, f: __CodecUsingEncodedCallback) -> __CodecOutputReturn { + ::ink::scale::Encode::using_encoded(&&self.account_id, f) + } + } + #[automatically_derived] + impl ::ink::scale::EncodeLike for CallBuilder {} + }; + #[automatically_derived] + impl ::core::fmt::Debug for CallBuilder { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_struct_field1_finish( + f, + "CallBuilder", + "account_id", + &&self.account_id, + ) + } + } + #[automatically_derived] + impl ::core::hash::Hash for CallBuilder { + #[inline] + fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () { + ::core::hash::Hash::hash(&self.account_id, state) + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for CallBuilder {} + #[automatically_derived] + impl ::core::cmp::PartialEq for CallBuilder { + #[inline] + fn eq(&self, other: &CallBuilder) -> bool { + self.account_id == other.account_id + } + } + #[automatically_derived] + impl ::core::cmp::Eq for CallBuilder { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () { + let _: ::core::cmp::AssertParamIsEq; + } + } + #[automatically_derived] + impl ::core::clone::Clone for CallBuilder { + #[inline] + fn clone(&self) -> CallBuilder { + CallBuilder { + account_id: ::core::clone::Clone::clone(&self.account_id), + } + } + } + const _: () = { + impl ::ink::storage::traits::StorageLayout for CallBuilder { + fn layout( + __key: &::ink::primitives::Key, + ) -> ::ink::metadata::layout::Layout { + ::ink::metadata::layout::Layout::Struct( + ::ink::metadata::layout::StructLayout::new( + "CallBuilder", + [ + ::ink::metadata::layout::FieldLayout::new( + "account_id", + ::layout( + __key, + ), + ), + ], + ), + ) + } + } + }; + const _: () = { + impl ::ink::codegen::ContractCallBuilder for Fungibles { + type Type = CallBuilder; + } + impl ::ink::env::ContractEnv for CallBuilder { + type Env = ::Env; + } + }; + impl ::ink::env::call::FromAccountId for CallBuilder { + #[inline] + fn from_account_id(account_id: AccountId) -> Self { + Self { account_id } + } + } + impl ::ink::ToAccountId for CallBuilder { + #[inline] + fn to_account_id(&self) -> AccountId { + ::clone(&self.account_id) + } + } + impl ::core::convert::AsRef for CallBuilder { + fn as_ref(&self) -> &AccountId { + &self.account_id + } + } + impl ::core::convert::AsMut for CallBuilder { + fn as_mut(&mut self) -> &mut AccountId { + &mut self.account_id + } + } + impl CallBuilder { + #[allow(clippy::type_complexity)] + #[inline] + pub fn total_supply( + &self, + __ink_binding_0: AssetId, + ) -> ::ink::env::call::CallBuilder< + Environment, + ::ink::env::call::utils::Set<::ink::env::call::Call>, + ::ink::env::call::utils::Set< + ::ink::env::call::ExecutionInput< + ::ink::env::call::utils::ArgumentList< + ::ink::env::call::utils::Argument, + ::ink::env::call::utils::EmptyArgumentList, + >, + >, + >, + ::ink::env::call::utils::Set< + ::ink::env::call::utils::ReturnType>, + >, + > { + ::ink::env::call::build_call::() + .call(::ink::ToAccountId::to_account_id(self)) + .exec_input( + ::ink::env::call::ExecutionInput::new( + ::ink::env::call::Selector::new([ + 0xDB_u8, + 0x63_u8, + 0x75_u8, + 0xA8_u8, + ]), + ) + .push_arg(__ink_binding_0), + ) + .returns::>() + } + #[allow(clippy::type_complexity)] + #[inline] + pub fn balance_of( + &self, + __ink_binding_0: AssetId, + __ink_binding_1: AccountId32, + ) -> ::ink::env::call::CallBuilder< + Environment, + ::ink::env::call::utils::Set<::ink::env::call::Call>, + ::ink::env::call::utils::Set< + ::ink::env::call::ExecutionInput< + ::ink::env::call::utils::ArgumentList< + ::ink::env::call::utils::Argument, + ::ink::env::call::utils::ArgumentList< + ::ink::env::call::utils::Argument, + ::ink::env::call::utils::EmptyArgumentList, + >, + >, + >, + >, + ::ink::env::call::utils::Set< + ::ink::env::call::utils::ReturnType>, + >, + > { + ::ink::env::call::build_call::() + .call(::ink::ToAccountId::to_account_id(self)) + .exec_input( + ::ink::env::call::ExecutionInput::new( + ::ink::env::call::Selector::new([ + 0x0F_u8, + 0x75_u8, + 0x5A_u8, + 0x56_u8, + ]), + ) + .push_arg(__ink_binding_0) + .push_arg(__ink_binding_1), + ) + .returns::>() + } + #[allow(clippy::type_complexity)] + #[inline] + pub fn allowance( + &self, + __ink_binding_0: AssetId, + __ink_binding_1: AccountId32, + __ink_binding_2: AccountId32, + ) -> ::ink::env::call::CallBuilder< + Environment, + ::ink::env::call::utils::Set<::ink::env::call::Call>, + ::ink::env::call::utils::Set< + ::ink::env::call::ExecutionInput< + ::ink::env::call::utils::ArgumentList< + ::ink::env::call::utils::Argument, + ::ink::env::call::utils::ArgumentList< + ::ink::env::call::utils::Argument, + ::ink::env::call::utils::ArgumentList< + ::ink::env::call::utils::Argument, + ::ink::env::call::utils::EmptyArgumentList, + >, + >, + >, + >, + >, + ::ink::env::call::utils::Set< + ::ink::env::call::utils::ReturnType>, + >, + > { + ::ink::env::call::build_call::() + .call(::ink::ToAccountId::to_account_id(self)) + .exec_input( + ::ink::env::call::ExecutionInput::new( + ::ink::env::call::Selector::new([ + 0x6A_u8, + 0x00_u8, + 0x16_u8, + 0x5E_u8, + ]), + ) + .push_arg(__ink_binding_0) + .push_arg(__ink_binding_1) + .push_arg(__ink_binding_2), + ) + .returns::>() + } + #[allow(clippy::type_complexity)] + #[inline] + pub fn asset_exists( + &self, + __ink_binding_0: AssetId, + ) -> ::ink::env::call::CallBuilder< + Environment, + ::ink::env::call::utils::Set<::ink::env::call::Call>, + ::ink::env::call::utils::Set< + ::ink::env::call::ExecutionInput< + ::ink::env::call::utils::ArgumentList< + ::ink::env::call::utils::Argument, + ::ink::env::call::utils::EmptyArgumentList, + >, + >, + >, + ::ink::env::call::utils::Set< + ::ink::env::call::utils::ReturnType>, + >, + > { + ::ink::env::call::build_call::() + .call(::ink::ToAccountId::to_account_id(self)) + .exec_input( + ::ink::env::call::ExecutionInput::new( + ::ink::env::call::Selector::new([ + 0xAA_u8, + 0x6B_u8, + 0x65_u8, + 0xDB_u8, + ]), + ) + .push_arg(__ink_binding_0), + ) + .returns::>() + } + #[allow(clippy::type_complexity)] + #[inline] + pub fn mint_asset( + &self, + __ink_binding_0: u32, + __ink_binding_1: AccountId32, + __ink_binding_2: Balance, + ) -> ::ink::env::call::CallBuilder< + Environment, + ::ink::env::call::utils::Set<::ink::env::call::Call>, + ::ink::env::call::utils::Set< + ::ink::env::call::ExecutionInput< + ::ink::env::call::utils::ArgumentList< + ::ink::env::call::utils::Argument, + ::ink::env::call::utils::ArgumentList< + ::ink::env::call::utils::Argument, + ::ink::env::call::utils::ArgumentList< + ::ink::env::call::utils::Argument, + ::ink::env::call::utils::EmptyArgumentList, + >, + >, + >, + >, + >, + ::ink::env::call::utils::Set< + ::ink::env::call::utils::ReturnType>, + >, + > { + ::ink::env::call::build_call::() + .call(::ink::ToAccountId::to_account_id(self)) + .exec_input( + ::ink::env::call::ExecutionInput::new( + ::ink::env::call::Selector::new([ + 0x1F_u8, + 0x8E_u8, + 0x8E_u8, + 0x22_u8, + ]), + ) + .push_arg(__ink_binding_0) + .push_arg(__ink_binding_1) + .push_arg(__ink_binding_2), + ) + .returns::>() + } + } + }; + #[codec(crate = ::ink::scale)] + #[scale_info(crate = ::ink::scale_info)] + pub struct FungiblesRef { + inner: ::Type, + } + #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] + const _: () = { + impl ::ink::scale_info::TypeInfo for FungiblesRef { + type Identity = Self; + fn type_info() -> ::ink::scale_info::Type { + ::ink::scale_info::Type::builder() + .path( + ::ink::scale_info::Path::new_with_replace( + "FungiblesRef", + "fungibles::fungibles", + &[], + ), + ) + .type_params(::alloc::vec::Vec::new()) + .composite( + ::ink::scale_info::build::Fields::named() + .field(|f| { + f + .ty::< + ::Type, + >() + .name("inner") + .type_name( + "::Type", + ) + }), + ) + } + } + }; + #[allow(deprecated)] + const _: () = { + #[automatically_derived] + impl ::ink::scale::Decode for FungiblesRef { + fn decode<__CodecInputEdqy: ::ink::scale::Input>( + __codec_input_edqy: &mut __CodecInputEdqy, + ) -> ::core::result::Result { + ::core::result::Result::Ok(FungiblesRef { + inner: { + let __codec_res_edqy = <::Type as ::ink::scale::Decode>::decode( + __codec_input_edqy, + ); + match __codec_res_edqy { + ::core::result::Result::Err(e) => { + return ::core::result::Result::Err( + e.chain("Could not decode `FungiblesRef::inner`"), + ); + } + ::core::result::Result::Ok(__codec_res_edqy) => { + __codec_res_edqy + } + } + }, + }) + } + } + }; + #[allow(deprecated)] + const _: () = { + #[automatically_derived] + impl ::ink::scale::Encode for FungiblesRef { + fn size_hint(&self) -> usize { + ::ink::scale::Encode::size_hint(&&self.inner) + } + fn encode_to< + __CodecOutputEdqy: ::ink::scale::Output + ?::core::marker::Sized, + >(&self, __codec_dest_edqy: &mut __CodecOutputEdqy) { + ::ink::scale::Encode::encode_to(&&self.inner, __codec_dest_edqy) + } + fn encode(&self) -> ::ink::scale::alloc::vec::Vec<::core::primitive::u8> { + ::ink::scale::Encode::encode(&&self.inner) + } + fn using_encoded< + __CodecOutputReturn, + __CodecUsingEncodedCallback: ::core::ops::FnOnce( + &[::core::primitive::u8], + ) -> __CodecOutputReturn, + >(&self, f: __CodecUsingEncodedCallback) -> __CodecOutputReturn { + ::ink::scale::Encode::using_encoded(&&self.inner, f) + } + } + #[automatically_derived] + impl ::ink::scale::EncodeLike for FungiblesRef {} + }; + #[automatically_derived] + impl ::core::fmt::Debug for FungiblesRef { + #[inline] + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + ::core::fmt::Formatter::debug_struct_field1_finish( + f, + "FungiblesRef", + "inner", + &&self.inner, + ) + } + } + #[automatically_derived] + impl ::core::hash::Hash for FungiblesRef { + #[inline] + fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () { + ::core::hash::Hash::hash(&self.inner, state) + } + } + #[automatically_derived] + impl ::core::marker::StructuralPartialEq for FungiblesRef {} + #[automatically_derived] + impl ::core::cmp::PartialEq for FungiblesRef { + #[inline] + fn eq(&self, other: &FungiblesRef) -> bool { + self.inner == other.inner + } + } + #[automatically_derived] + impl ::core::cmp::Eq for FungiblesRef { + #[inline] + #[doc(hidden)] + #[coverage(off)] + fn assert_receiver_is_total_eq(&self) -> () { + let _: ::core::cmp::AssertParamIsEq< + ::Type, + >; + } + } + #[automatically_derived] + impl ::core::clone::Clone for FungiblesRef { + #[inline] + fn clone(&self) -> FungiblesRef { + FungiblesRef { + inner: ::core::clone::Clone::clone(&self.inner), + } + } + } + const _: () = { + impl ::ink::storage::traits::StorageLayout for FungiblesRef { + fn layout( + __key: &::ink::primitives::Key, + ) -> ::ink::metadata::layout::Layout { + ::ink::metadata::layout::Layout::Struct( + ::ink::metadata::layout::StructLayout::new( + "FungiblesRef", + [ + ::ink::metadata::layout::FieldLayout::new( + "inner", + <::Type as ::ink::storage::traits::StorageLayout>::layout( + __key, + ), + ), + ], + ), + ) + } + } + }; + const _: () = { + impl ::ink::env::ContractReference for Fungibles { + type Type = FungiblesRef; + } + impl ::ink::env::call::ConstructorReturnType for Fungibles { + type Output = FungiblesRef; + type Error = (); + fn ok(value: FungiblesRef) -> Self::Output { + value + } + } + impl ::ink::env::call::ConstructorReturnType + for ::core::result::Result + where + E: ::ink::scale::Decode, + { + const IS_RESULT: bool = true; + type Output = ::core::result::Result; + type Error = E; + fn ok(value: FungiblesRef) -> Self::Output { + ::core::result::Result::Ok(value) + } + fn err(err: Self::Error) -> ::core::option::Option { + ::core::option::Option::Some(::core::result::Result::Err(err)) + } + } + impl ::ink::env::ContractEnv for FungiblesRef { + type Env = ::Env; + } + }; + impl FungiblesRef { + #[inline] + #[allow(clippy::type_complexity)] + pub fn new() -> ::ink::env::call::CreateBuilder< + Environment, + Self, + ::ink::env::call::utils::Unset, + ::ink::env::call::utils::Set< + ::ink::env::call::LimitParamsV2< + ::Env, + >, + >, + ::ink::env::call::utils::Unset, + ::ink::env::call::utils::Set< + ::ink::env::call::ExecutionInput< + ::ink::env::call::utils::EmptyArgumentList, + >, + >, + ::ink::env::call::utils::Unset<::ink::env::call::state::Salt>, + ::ink::env::call::utils::Set<::ink::env::call::utils::ReturnType>, + > { + ::ink::env::call::build_create::() + .exec_input( + ::ink::env::call::ExecutionInput::new( + ::ink::env::call::Selector::new([ + 0x9B_u8, + 0xAE_u8, + 0x9D_u8, + 0x5E_u8, + ]), + ), + ) + .returns::() + } + #[inline] + pub fn total_supply(&self, id: AssetId) -> Result { + self.try_total_supply(id) + .unwrap_or_else(|error| { + ::core::panicking::panic_fmt( + format_args!( + "encountered error while calling {0}::{1}: {2:?}", + "Fungibles", + "total_supply", + error, + ), + ); + }) + } + #[inline] + pub fn try_total_supply( + &self, + id: AssetId, + ) -> ::ink::MessageResult> { + ::call(self) + .total_supply(id) + .try_invoke() + .unwrap_or_else(|error| { + ::core::panicking::panic_fmt( + format_args!( + "encountered error while calling {0}::{1}: {2:?}", + "Fungibles", + "total_supply", + error, + ), + ); + }) + } + #[inline] + pub fn balance_of(&self, id: AssetId, owner: AccountId32) -> Result { + self.try_balance_of(id, owner) + .unwrap_or_else(|error| { + ::core::panicking::panic_fmt( + format_args!( + "encountered error while calling {0}::{1}: {2:?}", + "Fungibles", + "balance_of", + error, + ), + ); + }) + } + #[inline] + pub fn try_balance_of( + &self, + id: AssetId, + owner: AccountId32, + ) -> ::ink::MessageResult> { + ::call(self) + .balance_of(id, owner) + .try_invoke() + .unwrap_or_else(|error| { + ::core::panicking::panic_fmt( + format_args!( + "encountered error while calling {0}::{1}: {2:?}", + "Fungibles", + "balance_of", + error, + ), + ); + }) + } + #[inline] + pub fn allowance( + &self, + id: AssetId, + owner: AccountId32, + spender: AccountId32, + ) -> Result { + self.try_allowance(id, owner, spender) + .unwrap_or_else(|error| { + ::core::panicking::panic_fmt( + format_args!( + "encountered error while calling {0}::{1}: {2:?}", + "Fungibles", + "allowance", + error, + ), + ); + }) + } + #[inline] + pub fn try_allowance( + &self, + id: AssetId, + owner: AccountId32, + spender: AccountId32, + ) -> ::ink::MessageResult> { + ::call(self) + .allowance(id, owner, spender) + .try_invoke() + .unwrap_or_else(|error| { + ::core::panicking::panic_fmt( + format_args!( + "encountered error while calling {0}::{1}: {2:?}", + "Fungibles", + "allowance", + error, + ), + ); + }) + } + #[inline] + pub fn asset_exists(&self, id: AssetId) -> Result { + self.try_asset_exists(id) + .unwrap_or_else(|error| { + ::core::panicking::panic_fmt( + format_args!( + "encountered error while calling {0}::{1}: {2:?}", + "Fungibles", + "asset_exists", + error, + ), + ); + }) + } + #[inline] + pub fn try_asset_exists( + &self, + id: AssetId, + ) -> ::ink::MessageResult> { + ::call(self) + .asset_exists(id) + .try_invoke() + .unwrap_or_else(|error| { + ::core::panicking::panic_fmt( + format_args!( + "encountered error while calling {0}::{1}: {2:?}", + "Fungibles", + "asset_exists", + error, + ), + ); + }) + } + #[inline] + pub fn mint_asset( + &self, + id: u32, + beneficiary: AccountId32, + amount: Balance, + ) -> Result<()> { + self.try_mint_asset(id, beneficiary, amount) + .unwrap_or_else(|error| { + ::core::panicking::panic_fmt( + format_args!( + "encountered error while calling {0}::{1}: {2:?}", + "Fungibles", + "mint_asset", + error, + ), + ); + }) + } + #[inline] + pub fn try_mint_asset( + &self, + id: u32, + beneficiary: AccountId32, + amount: Balance, + ) -> ::ink::MessageResult> { + ::call(self) + .mint_asset(id, beneficiary, amount) + .try_invoke() + .unwrap_or_else(|error| { + ::core::panicking::panic_fmt( + format_args!( + "encountered error while calling {0}::{1}: {2:?}", + "Fungibles", + "mint_asset", + error, + ), + ); + }) + } + } + const _: () = { + impl ::ink::codegen::TraitCallBuilder for FungiblesRef { + type Builder = ::Type; + #[inline] + fn call(&self) -> &Self::Builder { + &self.inner + } + #[inline] + fn call_mut(&mut self) -> &mut Self::Builder { + &mut self.inner + } + } + }; + impl ::ink::env::call::FromAccountId for FungiblesRef { + #[inline] + fn from_account_id(account_id: AccountId) -> Self { + Self { + inner: <::Type as ::ink::env::call::FromAccountId< + Environment, + >>::from_account_id(account_id), + } + } + } + impl ::ink::ToAccountId for FungiblesRef { + #[inline] + fn to_account_id(&self) -> AccountId { + <::Type as ::ink::ToAccountId< + Environment, + >>::to_account_id(&self.inner) + } + } + impl ::core::convert::AsRef for FungiblesRef { + fn as_ref(&self) -> &AccountId { + <_ as ::core::convert::AsRef>::as_ref(&self.inner) + } + } + impl ::core::convert::AsMut for FungiblesRef { + fn as_mut(&mut self) -> &mut AccountId { + <_ as ::core::convert::AsMut>::as_mut(&mut self.inner) + } + } + #[cfg(feature = "std")] + #[cfg(not(feature = "ink-as-dependency"))] + const _: () = { + #[no_mangle] + pub fn __ink_generate_metadata() -> ::ink::metadata::InkProject { + let layout = ::ink::metadata::layout::Layout::Root( + ::ink::metadata::layout::RootLayout::new( + <::ink::metadata::layout::LayoutKey as ::core::convert::From< + ::ink::primitives::Key, + >>::from(::KEY), + ::layout( + &::KEY, + ), + ::ink::scale_info::meta_type::(), + ), + ); + ::ink::metadata::layout::ValidateLayout::validate(&layout) + .unwrap_or_else(|error| { + { + ::core::panicking::panic_fmt( + format_args!("metadata ink! generation failed: {0}", error), + ); + } + }); + ::ink::metadata::InkProject::new( + layout, + ::ink::metadata::ContractSpec::new() + .constructors([ + ::ink::metadata::ConstructorSpec::from_label("new") + .selector([0x9B_u8, 0xAE_u8, 0x9D_u8, 0x5E_u8]) + .args([]) + .payable(true) + .default(false) + .returns( + ::ink::metadata::ReturnTypeSpec::new( + if >::IS_RESULT { + ::ink::metadata::TypeSpec::with_name_str::< + ::ink::ConstructorResult< + ::core::result::Result< + (), + >::Error, + >, + >, + >("ink_primitives::ConstructorResult") + } else { + ::ink::metadata::TypeSpec::with_name_str::< + ::ink::ConstructorResult<()>, + >("ink_primitives::ConstructorResult") + }, + ), + ) + .docs([]) + .done(), + ]) + .messages([ + ::ink::metadata::MessageSpec::from_label("total_supply") + .selector([0xDB_u8, 0x63_u8, 0x75_u8, 0xA8_u8]) + .args([ + ::ink::metadata::MessageParamSpec::new("id") + .of_type( + ::ink::metadata::TypeSpec::with_name_segs::< + AssetId, + _, + >( + ::core::iter::Iterator::map( + ::core::iter::IntoIterator::into_iter(["AssetId"]), + ::core::convert::AsRef::as_ref, + ), + ), + ) + .done(), + ]) + .returns( + ::ink::metadata::ReturnTypeSpec::new( + ::ink::metadata::TypeSpec::with_name_segs::< + ::ink::MessageResult>, + _, + >( + ::core::iter::Iterator::map( + ::core::iter::IntoIterator::into_iter([ + "ink", + "MessageResult", + ]), + ::core::convert::AsRef::as_ref, + ), + ), + ), + ) + .mutates(false) + .payable(false) + .default(false) + .docs([]) + .done(), + ::ink::metadata::MessageSpec::from_label("balance_of") + .selector([0x0F_u8, 0x75_u8, 0x5A_u8, 0x56_u8]) + .args([ + ::ink::metadata::MessageParamSpec::new("id") + .of_type( + ::ink::metadata::TypeSpec::with_name_segs::< + AssetId, + _, + >( + ::core::iter::Iterator::map( + ::core::iter::IntoIterator::into_iter(["AssetId"]), + ::core::convert::AsRef::as_ref, + ), + ), + ) + .done(), + ::ink::metadata::MessageParamSpec::new("owner") + .of_type( + ::ink::metadata::TypeSpec::with_name_segs::< + AccountId32, + _, + >( + ::core::iter::Iterator::map( + ::core::iter::IntoIterator::into_iter(["AccountId32"]), + ::core::convert::AsRef::as_ref, + ), + ), + ) + .done(), + ]) + .returns( + ::ink::metadata::ReturnTypeSpec::new( + ::ink::metadata::TypeSpec::with_name_segs::< + ::ink::MessageResult>, + _, + >( + ::core::iter::Iterator::map( + ::core::iter::IntoIterator::into_iter([ + "ink", + "MessageResult", + ]), + ::core::convert::AsRef::as_ref, + ), + ), + ), + ) + .mutates(false) + .payable(false) + .default(false) + .docs([]) + .done(), + ::ink::metadata::MessageSpec::from_label("allowance") + .selector([0x6A_u8, 0x00_u8, 0x16_u8, 0x5E_u8]) + .args([ + ::ink::metadata::MessageParamSpec::new("id") + .of_type( + ::ink::metadata::TypeSpec::with_name_segs::< + AssetId, + _, + >( + ::core::iter::Iterator::map( + ::core::iter::IntoIterator::into_iter(["AssetId"]), + ::core::convert::AsRef::as_ref, + ), + ), + ) + .done(), + ::ink::metadata::MessageParamSpec::new("owner") + .of_type( + ::ink::metadata::TypeSpec::with_name_segs::< + AccountId32, + _, + >( + ::core::iter::Iterator::map( + ::core::iter::IntoIterator::into_iter(["AccountId32"]), + ::core::convert::AsRef::as_ref, + ), + ), + ) + .done(), + ::ink::metadata::MessageParamSpec::new("spender") + .of_type( + ::ink::metadata::TypeSpec::with_name_segs::< + AccountId32, + _, + >( + ::core::iter::Iterator::map( + ::core::iter::IntoIterator::into_iter(["AccountId32"]), + ::core::convert::AsRef::as_ref, + ), + ), + ) + .done(), + ]) + .returns( + ::ink::metadata::ReturnTypeSpec::new( + ::ink::metadata::TypeSpec::with_name_segs::< + ::ink::MessageResult>, + _, + >( + ::core::iter::Iterator::map( + ::core::iter::IntoIterator::into_iter([ + "ink", + "MessageResult", + ]), + ::core::convert::AsRef::as_ref, + ), + ), + ), + ) + .mutates(false) + .payable(false) + .default(false) + .docs([]) + .done(), + ::ink::metadata::MessageSpec::from_label("asset_exists") + .selector([0xAA_u8, 0x6B_u8, 0x65_u8, 0xDB_u8]) + .args([ + ::ink::metadata::MessageParamSpec::new("id") + .of_type( + ::ink::metadata::TypeSpec::with_name_segs::< + AssetId, + _, + >( + ::core::iter::Iterator::map( + ::core::iter::IntoIterator::into_iter(["AssetId"]), + ::core::convert::AsRef::as_ref, + ), + ), + ) + .done(), + ]) + .returns( + ::ink::metadata::ReturnTypeSpec::new( + ::ink::metadata::TypeSpec::with_name_segs::< + ::ink::MessageResult>, + _, + >( + ::core::iter::Iterator::map( + ::core::iter::IntoIterator::into_iter([ + "ink", + "MessageResult", + ]), + ::core::convert::AsRef::as_ref, + ), + ), + ), + ) + .mutates(false) + .payable(false) + .default(false) + .docs([]) + .done(), + ::ink::metadata::MessageSpec::from_label("mint_asset") + .selector([0x1F_u8, 0x8E_u8, 0x8E_u8, 0x22_u8]) + .args([ + ::ink::metadata::MessageParamSpec::new("id") + .of_type( + ::ink::metadata::TypeSpec::with_name_segs::< + u32, + _, + >( + ::core::iter::Iterator::map( + ::core::iter::IntoIterator::into_iter(["u32"]), + ::core::convert::AsRef::as_ref, + ), + ), + ) + .done(), + ::ink::metadata::MessageParamSpec::new("beneficiary") + .of_type( + ::ink::metadata::TypeSpec::with_name_segs::< + AccountId32, + _, + >( + ::core::iter::Iterator::map( + ::core::iter::IntoIterator::into_iter(["AccountId32"]), + ::core::convert::AsRef::as_ref, + ), + ), + ) + .done(), + ::ink::metadata::MessageParamSpec::new("amount") + .of_type( + ::ink::metadata::TypeSpec::with_name_segs::< + Balance, + _, + >( + ::core::iter::Iterator::map( + ::core::iter::IntoIterator::into_iter(["Balance"]), + ::core::convert::AsRef::as_ref, + ), + ), + ) + .done(), + ]) + .returns( + ::ink::metadata::ReturnTypeSpec::new( + ::ink::metadata::TypeSpec::with_name_segs::< + ::ink::MessageResult>, + _, + >( + ::core::iter::Iterator::map( + ::core::iter::IntoIterator::into_iter([ + "ink", + "MessageResult", + ]), + ::core::convert::AsRef::as_ref, + ), + ), + ), + ) + .mutates(false) + .payable(false) + .default(false) + .docs([]) + .done(), + ]) + .collect_events() + .docs([]) + .lang_error( + ::ink::metadata::TypeSpec::with_name_segs::< + ::ink::LangError, + _, + >( + ::core::iter::Iterator::map( + ::core::iter::IntoIterator::into_iter(["ink", "LangError"]), + ::core::convert::AsRef::as_ref, + ), + ), + ) + .environment( + ::ink::metadata::EnvironmentSpec::new() + .account_id( + ::ink::metadata::TypeSpec::with_name_segs::< + AccountId, + _, + >( + ::core::iter::Iterator::map( + ::core::iter::IntoIterator::into_iter(["AccountId"]), + ::core::convert::AsRef::as_ref, + ), + ), + ) + .balance( + ::ink::metadata::TypeSpec::with_name_segs::< + Balance, + _, + >( + ::core::iter::Iterator::map( + ::core::iter::IntoIterator::into_iter(["Balance"]), + ::core::convert::AsRef::as_ref, + ), + ), + ) + .hash( + ::ink::metadata::TypeSpec::with_name_segs::< + Hash, + _, + >( + ::core::iter::Iterator::map( + ::core::iter::IntoIterator::into_iter(["Hash"]), + ::core::convert::AsRef::as_ref, + ), + ), + ) + .timestamp( + ::ink::metadata::TypeSpec::with_name_segs::< + Timestamp, + _, + >( + ::core::iter::Iterator::map( + ::core::iter::IntoIterator::into_iter(["Timestamp"]), + ::core::convert::AsRef::as_ref, + ), + ), + ) + .block_number( + ::ink::metadata::TypeSpec::with_name_segs::< + BlockNumber, + _, + >( + ::core::iter::Iterator::map( + ::core::iter::IntoIterator::into_iter(["BlockNumber"]), + ::core::convert::AsRef::as_ref, + ), + ), + ) + .chain_extension( + ::ink::metadata::TypeSpec::with_name_segs::< + ChainExtension, + _, + >( + ::core::iter::Iterator::map( + ::core::iter::IntoIterator::into_iter(["ChainExtension"]), + ::core::convert::AsRef::as_ref, + ), + ), + ) + .max_event_topics(MAX_EVENT_TOPICS) + .static_buffer_size(::ink::env::BUFFER_SIZE) + .done(), + ) + .done(), + ) + } + }; + use super::*; +} diff --git a/pop-api/examples/fungibles/lib.rs b/pop-api/examples/fungibles/lib.rs new file mode 100755 index 00000000..9c0ae754 --- /dev/null +++ b/pop-api/examples/fungibles/lib.rs @@ -0,0 +1,176 @@ +#![cfg_attr(not(feature = "std"), no_std, no_main)] + +// Fungibles wrapper contract to allow contracts to interact with local fungibles without the pop api. +use ink::prelude::vec::Vec; +use pop_api::{ + assets::fungibles::*, + primitives::{AccountId as AccountId32, AssetId}, +}; + +#[derive(Debug, Copy, Clone, PartialEq, Eq, scale::Encode, scale::Decode)] +#[cfg_attr(feature = "std", derive(scale_info::TypeInfo))] +pub enum ContractError { + // AssetsError(Error), + // /// The origin of the call doesn't have the right permission. + // BadOrigin, + // /// Custom error type for cases in which an implementation adds its own restrictions. + // Custom(String), + /// Not enough balance to fulfill a request is available. + InsufficientBalance, + /// Not enough allowance to fulfill a request is available. + InsufficientAllowance, + /// The asset status is not the expected status. + IncorrectStatus, + /// The asset ID is already taken. + InUse, + /// Minimum balance should be non-zero. + MinBalanceZero, + /// The signing account has no permission to do the operation. + NoPermission, + // /// Safe transfer check fails (e.g. if the receiving contract does not accept tokens). + // SafeTransferCheckFailed(String), + /// The given asset ID is unknown. + Unknown, + /// Recipient's address is zero. + ZeroRecipientAddress, + /// Sender's address is zero. + ZeroSenderAddress, + UndefinedError, +} + +impl From for ContractError { + fn from(error: FungiblesError) -> Self { + match error { + // Error::BalanceLow => Err(InsufficientBalance), + FungiblesError::InUse => ContractError::InUse, + FungiblesError::MinBalanceZero => ContractError::MinBalanceZero, + FungiblesError::Unknown => ContractError::Unknown, + _ => ContractError::UndefinedError, + } + } +} + +/// The fungibles result type. +pub type Result = core::result::Result; + +#[ink::contract(env = pop_api::Environment)] +mod fungibles { + use super::*; + + #[ink(storage)] + #[derive(Default)] + pub struct Fungibles; + + impl Fungibles { + #[ink(constructor, payable)] + pub fn new() -> Self { + ink::env::debug_println!("PopApiAssetsExample::new"); + Default::default() + } + + #[ink(message)] + pub fn total_supply(&self, id: AssetId) -> Result { + total_supply(id).map_err(From::from) + } + + #[ink(message)] + pub fn balance_of(&self, id: AssetId, owner: AccountId32) -> Result { + balance_of(id, owner).map_err(From::from) + } + + #[ink(message)] + pub fn allowance( + &self, + id: AssetId, + owner: AccountId32, + spender: AccountId32, + ) -> Result { + allowance(id, owner, spender).map_err(From::from) + } + + #[ink(message)] + pub fn asset_exists(&self, id: AssetId) -> Result { + asset_exists(id).map_err(From::from) + } + + #[ink(message)] + pub fn create(&self, id: AssetId, admin: AccountId32, min_balance: Balance) -> Result<()> { + // create(id, admin, min_balance).map_err(From::from) + ink::env::debug_println!( + "PopApiAssetsExample::create: id: {:?} admin: {:?} min_balance: {:?}", + id, + admin, + min_balance, + ); + let result = create(id, admin, min_balance); + ink::env::debug_println!("Result: {:?}", result); + result.map_err(From::from) + } + + #[ink(message)] + pub fn set_metadata( + &self, + id: AssetId, + name: Vec, + symbol: Vec, + decimals: u8, + ) -> Result<()> { + // set_metadata(id, name, symbol, decimals).map_err(From::from) + ink::env::debug_println!( + "PopApiAssetsExample::set_metadata: id: {:?} name: {:?} symbol: {:?}, decimals: {:?}", + id, + name, + symbol, + decimals, + ); + let result = set_metadata(id, name, symbol, decimals); + ink::env::debug_println!("Result: {:?}", result); + result.map_err(From::from) + } + + #[ink(message)] + pub fn mint(&self, id: AssetId, beneficiary: AccountId32, amount: Balance) -> Result<()> { + ink::env::debug_println!( + "PopApiAssetsExample::mint: id: {:?}, beneficiary: {:?} amount: {:?}", + id, + beneficiary, + amount, + ); + + let result = mint(id, beneficiary, amount); + ink::env::debug_println!("Result: {:?}", result); + result.map_err(From::from) + } + + // #[ink(message)] + // pub fn transfer_from( + // id: AssetId, + // from: Option, + // to: Option, + // value: Balance, + // data: [u8], + // ) -> Result<()> { + // ink::env::debug_println!( + // "PopApiAssetsExample::transfer_from: id: {:?}, from: {:?}, to: {:?} value: {:?}", + // id, + // from, + // to, + // value, + // ); + // + // let result = transfer_from(id, from, to, value)?; + // ink::env::debug_println!("Result: {:?}", result); + // result + // } + } + + #[cfg(test)] + mod tests { + use super::*; + + #[ink::test] + fn default_works() { + PopApiAssetsExample::new(); + } + } +} diff --git a/pop-api/examples/trust_backed_assets/lib.rs b/pop-api/examples/trust_backed_assets/lib.rs deleted file mode 100755 index 3606f852..00000000 --- a/pop-api/examples/trust_backed_assets/lib.rs +++ /dev/null @@ -1,74 +0,0 @@ -#![cfg_attr(not(feature = "std"), no_std, no_main)] - -// Utilizing Trust Backed Assets with the Pop API. -// -// This example demonstrates interaction with trust backed assets via the assets pallet. Trust backed assets are originated -// and managed within Pop Network, harnessing the platform's inherent trust, security, and governance models. -use pop_api::assets::trust_backed as trust_backed_assets; - -#[derive(Debug, Copy, Clone, PartialEq, Eq, scale::Encode, scale::Decode)] -#[cfg_attr(feature = "std", derive(scale_info::TypeInfo))] -pub enum ContractError { - TrustBackedAssetsError(trust_backed_assets::Error), - UnknownAsset, -} - -impl From for ContractError { - fn from(value: trust_backed_assets::Error) -> Self { - ContractError::TrustBackedAssetsError(value) - } -} - -#[ink::contract(env = pop_api::Environment)] -mod pop_api_tb_assets_example { - use super::*; - - #[ink(storage)] - #[derive(Default)] - pub struct PopApiTBAssetsExample; - - impl PopApiTBAssetsExample { - #[ink(constructor, payable)] - pub fn new() -> Self { - ink::env::debug_println!("Contract::new"); - Default::default() - } - - #[ink(message)] - pub fn mint_asset_through_runtime( - &mut self, - id: u32, - beneficiary: AccountId, - amount: Balance, - ) -> Result<(), ContractError> { - ink::env::debug_println!( - "Contract::mint_asset_through_runtime: id: {:?} beneficiary: {:?} amount: {:?}", - id, - beneficiary, - amount - ); - - // Check if asset doesn't exist. - if !trust_backed_assets::asset_exists(id)? { - return Err(ContractError::UnknownAsset); - } - - // Mint asset via pop api. - trust_backed_assets::mint(id, beneficiary, amount)?; - ink::env::debug_println!( - "Contract::mint_asset_through_runtime: asset(s) minted successfully" - ); - Ok(()) - } - } - - #[cfg(test)] - mod tests { - use super::*; - - #[ink::test] - fn default_works() { - PopApiTBAssetsExample::new(); - } - } -} diff --git a/pop-api/src/lib.rs b/pop-api/src/lib.rs index 68ce6906..0ca4a817 100644 --- a/pop-api/src/lib.rs +++ b/pop-api/src/lib.rs @@ -3,14 +3,15 @@ pub mod primitives; pub mod v0; -use crate::PopApiError::{Balances, Nfts, TrustBackedAssets, UnknownStatusCode}; +use crate::PopApiError::{Assets, Balances, Contracts, Nfts, UnknownStatusCode}; use ink::{prelude::vec::Vec, ChainExtensionInstance}; -use primitives::{cross_chain::*, storage_keys::*}; +use primitives::{cross_chain::*, storage_keys::*, AccountId as AccountId32}; pub use sp_runtime::{BoundedVec, MultiAddress, MultiSignature}; use v0::RuntimeCall; -pub use v0::{balances, cross_chain, nfts, relay_chain_block_number, state, assets}; +pub use v0::{assets, balances, contracts, cross_chain, nfts, relay_chain_block_number, state}; -type AccountId = ::AccountId; +// type AccountId = ::AccountId; +type AccountId = AccountId32; type Balance = ::Balance; type BlockNumber = ::BlockNumber; type StringLimit = u32; @@ -25,8 +26,9 @@ pub enum PopApiError { DecodingFailed, SystemCallFiltered, Balances(balances::Error), + Contracts(contracts::Error), Nfts(nfts::Error), - TrustBackedAssets(assets::trust_backed::Error), + Assets(assets::fungibles::AssetsError), Xcm(cross_chain::Error), } @@ -37,8 +39,9 @@ impl ink::env::chain_extension::FromStatusCode for PopApiError { // CallFiltered originates from `frame_system` with pallet-index 0. The CallFiltered error is at index 5 5 => Err(PopApiError::SystemCallFiltered), 10_000..=10_999 => Err(Balances((status_code - 10_000).try_into()?)), + 40_000..=40_999 => Err(Contracts((status_code - 40_000).try_into()?)), 50_000..=50_999 => Err(Nfts((status_code - 50_000).try_into()?)), - 52_000..=52_999 => Err(TrustBackedAssets((status_code - 52_000).try_into()?)), + 52_000..=52_999 => Err(Assets((status_code - 52_000).try_into()?)), _ => Err(UnknownStatusCode(status_code)), } } diff --git a/pop-api/src/v0/assets/fungibles.rs b/pop-api/src/v0/assets/fungibles.rs new file mode 100644 index 00000000..f2d87a0e --- /dev/null +++ b/pop-api/src/v0/assets/fungibles.rs @@ -0,0 +1,554 @@ +use crate::{AccountId, Balance, PopApiError::UnknownStatusCode, RuntimeCall, *}; +use ink::prelude::vec::Vec; +use primitives::AssetId; +use scale::{Compact, Encode}; + +type Result = core::result::Result; + +/// Local Fungibles: +/// 1. PSP-22 Interface +/// 2. PSP-22 Metadata Interface +/// 3. Asset Management + +/// 1. PSP-22 Interface: +/// - total_supply +/// - balance_of +/// - allowance +/// - transfer +/// - transfer_from +/// - approve +/// - increase_allowance +/// - decrease_allowance + +/// Returns the total token supply for a given asset ID. +/// +/// # Arguments +/// * `id` - The ID of the asset. +/// +/// # Returns +/// The total supply of the token, or an error if the operation fails. +pub fn total_supply(id: AssetId) -> Result { + Ok(state::read(RuntimeStateKeys::Assets(AssetsKeys::TotalSupply(id)))?) +} + +/// Returns the account balance for the specified `owner` for a given asset ID. Returns `0` if +/// the account is non-existent. +/// +/// # Arguments +/// * `id` - The ID of the asset. +/// * `owner` - The account whose balance is being queried. +/// +/// # Returns +/// The balance of the specified account, or an error if the operation fails. +pub fn balance_of(id: AssetId, owner: AccountId) -> Result { + Ok(state::read(RuntimeStateKeys::Assets(AssetsKeys::BalanceOf(id, owner)))?) +} + +/// Returns the amount which `spender` is still allowed to withdraw from `owner` for a given +/// asset ID. Returns `0` if no allowance has been set. +/// +/// # Arguments +/// * `id` - The ID of the asset. +/// * `owner` - The account that owns the tokens. +/// * `spender` - The account that is allowed to spend the tokens. +/// +/// # Returns +/// The remaining allowance, or an error if the operation fails. +pub fn allowance(id: AssetId, owner: AccountId, spender: AccountId) -> Result { + Ok(state::read(RuntimeStateKeys::Assets(AssetsKeys::Allowance(id, owner, spender)))?) +} + +/// Create a new token with a given asset ID. +/// +/// # Arguments +/// * `id` - The ID of the asset. +/// * `admin` - The account that will administer the asset. +/// * `min_balance` - The minimum balance required for accounts holding this asset. +/// +/// # Returns +/// Returns `Ok(())` if successful, or an error if the creation fails. +// pub fn create(id: AssetId, admin: impl Into>, min_balance: Balance) -> Result<()> { +pub fn create( + id: AssetId, + admin: impl Into>, + min_balance: Balance, +) -> Result<()> { + Ok(dispatch(RuntimeCall::Assets(AssetsCall::Create { + id: id.into(), + admin: admin.into(), + min_balance, + }))?) +} + +/// Transfers `value` amount of tokens from the caller's account to account `to`, with additional +/// `data` in unspecified format. +/// +/// # Arguments +/// * `id` - The ID of the asset. +/// * `to` - The recipient account. +/// * `value` - The number of tokens to transfer. +/// +/// # Returns +/// Returns `Ok(())` if successful, or an error if the transfer fails. +// #[allow(unused_variables)] +// pub fn transfer( +// id: AssetId, +// to: impl Into>, +// value: Balance, +// ) -> Result<()> { +// todo!() +// // TODO: transfer or transfer_keep_alive +// // Ok(dispatch(RuntimeCall::Assets(AssetsCall::Transfer { +// // id: id.into(), +// // target: target.into(), +// // amount: Compact(amount), +// // }))?) +// // Ok(dispatch(RuntimeCall::Assets(AssetsCall::TransferKeepAlive { +// // id: id.into(), +// // target: target.into(), +// // amount: Compact(amount), +// // }))?) +// } + +/// Transfers `value` tokens on the behalf of `from` to the account `to` with additional `data` +/// in unspecified format. This can be used to allow a contract to transfer tokens on ones behalf +/// and/or to charge fees in sub-currencies, for example. +/// +/// # Arguments +/// * `id` - The ID of the asset. +/// * `from` - The account from which the tokens are transferred. +/// * `to` - The recipient account. +/// * `value` - The number of tokens to transfer. +/// +/// # Returns +/// Returns `Ok(())` if successful, or an error if the transfer fails. +// pub fn transfer_from( +// id: AssetId, +// from: impl Into>, +// to: impl Into>, +// value: Balance, +// ) -> Result<()> { +//todo!() +// TODO: depending on `from` and `to`, decide whether to mint, burn or transfer_approved. +// Ok(dispatch(RuntimeCall::Assets(AssetsCall::Mint { +// id: id.into(), +// beneficiary: beneficiary.into(), +// amount: Compact(amount), +// }))?) +// Ok(dispatch(RuntimeCall::Assets(AssetsCall::Burn { +// id: id.into(), +// who: who.into(), +// amount: Compact(amount), +// }))?) +// Ok(dispatch(RuntimeCall::Assets(AssetsCall::TransferApproved { +// id: id.into(), +// owner: from.into(), +// destination: to.into(), +// amount: Compact(value), +// }))?) +// } + +/// Mint assets of a particular class. +pub fn mint( + id: AssetId, + beneficiary: impl Into>, + amount: Balance, +) -> Result<()> { + Ok(dispatch(RuntimeCall::Assets(AssetsCall::Mint { + id: id.into(), + beneficiary: beneficiary.into(), + amount: Compact(amount), + }))?) +} + +/// Approves an account to spend a specified number of tokens on behalf of the caller. +/// +/// # Arguments +/// * `id` - The ID of the asset. +/// * `spender` - The account that is allowed to spend the tokens. +/// * `value` - The number of tokens to approve. +/// +/// # Returns +/// Returns `Ok(())` if successful, or an error if the approval fails. +// #[allow(unused_variables)] +// fn approve(id: AssetId, spender: AccountId, value: Balance) -> Result<()> { +// todo!() +// // TODO: read allowance and increase or decrease. +// // Ok(dispatch(RuntimeCall::Assets(AssetsCall::ApproveTransfer { +// // id: id.into(), +// // delegate: spender.into(), +// // amount: Compact(value), +// // }))?) +// } + +/// Increases the allowance of a spender. +/// +/// # Arguments +/// * `id` - The ID of the asset. +/// * `spender` - The account that is allowed to spend the tokens. +/// * `value` - The number of tokens to increase the allowance by. +/// +/// # Returns +/// Returns `Ok(())` if successful, or an error if the operation fails. +// fn increase_allowance(id: AssetId, spender: AccountId, value: Balance) -> Result<()> { +// Ok(dispatch(RuntimeCall::Assets(AssetsCall::ApproveTransfer { +// id: id.into(), +// delegate: spender.into(), +// amount: Compact(value), +// }))?) +// } + +/// Decreases the allowance of a spender. +/// +/// # Arguments +/// * `id` - The ID of the asset. +/// * `spender` - The account that is allowed to spend the tokens. +/// * `value` - The number of tokens to decrease the allowance by. +/// +/// # Returns +/// Returns `Ok(())` if successful, or an error if the operation fails. +// #[allow(unused_variables)] +// fn decrease_allowance(id: AssetId, spender: AccountId, value: Balance) -> Result<()> { +// todo!() +// // TODO: cancel_approval + approve_transfer +// // Ok(dispatch(RuntimeCall::Assets(AssetsCall::CancelApproval { +// // id: id.into(), +// // delegate: delegate.into(), +// // }))?) +// // Ok(dispatch(RuntimeCall::Assets(AssetsCall::ApproveTransfer { +// // id: id.into(), +// // delegate: spender.into(), +// // amount: Compact(value), +// // }))?) +// } + +/// 2. PSP-22 Metadata Interface: +/// - token_name +/// - token_symbol +/// - token_decimals + +/// Returns the token name for a given asset ID. +/// +/// # Arguments +/// * `id` - The ID of the asset. +/// +/// # Returns +/// The name of the token as a byte vector, or an error if the operation fails. +// #[allow(unused_variables)] +// pub fn token_name(id: AssetId) -> Result>> { +// todo!() +// // Ok(state::read(RuntimeStateKeys::Assets(AssetsKeys::TokenName(id)))?) +// } + +/// Returns the token symbol for a given asset ID. +/// +/// # Arguments +/// * `id` - The ID of the asset. +/// +/// # Returns +/// The symbol of the token as a byte vector, or an error if the operation fails. +// #[allow(unused_variables)] +// fn token_symbol(id: AssetId) -> Result>> { +// todo!() +// } + +/// Returns the token decimals for a given asset ID. +/// +/// # Arguments +/// * `id` - The ID of the asset. +/// +/// # Returns +/// The number of decimals of the token as a byte vector, or an error if the operation fails. +// #[allow(unused_variables)] +// fn token_decimals(id: AssetId) -> Result>> { +// todo!() +// } + +/// 3. Asset Management: +/// - create +/// - start_destroy +/// - destroy_accounts +/// - destroy_approvals +/// - finish_destroy +/// - set_metadata +/// - clear_metadata + +/// Start the process of destroying a token with a given asset ID. +/// +/// # Arguments +/// * `id` - The ID of the asset. +/// +/// # Returns +/// Returns `Ok(())` if successful, or an error if the operation fails. +// fn start_destroy(id: AssetId) -> Result<()> { +// Ok(dispatch(RuntimeCall::Assets(AssetsCall::StartDestroy { +// id: id.into(), +// }))?) +// } + +/// Destroy all accounts associated with a token with a given asset ID. +/// +/// # Arguments +/// * `id` - The ID of the asset. +/// +/// # Returns +/// Returns `Ok(())` if successful, or an error if the operation fails. +// fn destroy_accounts(id: AssetId) -> Result<()> { +// Ok(dispatch(RuntimeCall::Assets(AssetsCall::DestroyAccounts { +// id: id.into(), +// }))?) +// } + +/// Destroy all approvals associated with a token with a given asset ID. +/// +/// # Arguments +/// * `id` - The ID of the asset. +/// +/// # Returns +/// Returns `Ok(())` if successful, or an error if the operation fails. +// fn destroy_approvals(id: AssetId) -> Result<()> { +// Ok(dispatch(RuntimeCall::Assets(AssetsCall::DestroyApprovals { +// id: id.into(), +// }))?) +// } + +/// Complete the process of destroying a token with a given asset ID. +/// +/// # Arguments +/// * `id` - The ID of the asset. +/// +/// # Returns +/// Returns `Ok(())` if successful, or an error if the operation fails. +// fn finish_destroy(id: AssetId) -> Result<()> { +// Ok(dispatch(RuntimeCall::Assets(AssetsCall::FinishDestroy { +// id: id.into(), +// }))?) +// } + +/// Set the metadata for a token with a given asset ID. +/// +/// # Arguments +/// * `id` - The ID of the asset. +/// +/// # Returns +/// Returns `Ok(())` if successful, or an error if the operation fails. +pub fn set_metadata(id: AssetId, name: Vec, symbol: Vec, decimals: u8) -> Result<()> { + Ok(dispatch(RuntimeCall::Assets(AssetsCall::SetMetadata { + id: id.into(), + name, + symbol, + decimals, + }))?) +} + +/// Clear the metadata for a token with a given asset ID. +/// +/// # Arguments +/// * `id` - The ID of the asset. +/// +/// # Returns +/// Returns `Ok(())` if successful, or an error if the operation fails. +// fn clear_metadata(id: AssetId) -> Result<()> { +// Ok(dispatch(RuntimeCall::Assets(AssetsCall::ClearMetadata { +// id: id.into(), +// }))?) +// } + +pub fn asset_exists(id: AssetId) -> Result { + Ok(state::read(RuntimeStateKeys::Assets(AssetsKeys::AssetExists(id)))?) +} + +// Parameters to extrinsics representing an asset id (`AssetIdParameter`) and a balance amount (`Balance`) are expected +// to be compact encoded. The pop api handles that for the developer. +// +// reference: https://substrate.stackexchange.com/questions/1873/what-is-the-meaning-of-palletcompact-in-pallet-development +// +// Asset id that is compact encoded. +type AssetIdParameter = Compact; +// Balance amount that is compact encoded. +type BalanceParameter = Compact; + +#[allow(warnings, unused)] +#[derive(Encode)] +pub(crate) enum AssetsCall { + #[codec(index = 0)] + Create { id: AssetIdParameter, admin: MultiAddress, min_balance: Balance }, + #[codec(index = 2)] + StartDestroy { id: AssetIdParameter }, + #[codec(index = 3)] + DestroyAccounts { id: AssetIdParameter }, + #[codec(index = 4)] + DestroyApprovals { id: AssetIdParameter }, + #[codec(index = 5)] + FinishDestroy { id: AssetIdParameter }, + #[codec(index = 6)] + Mint { + id: AssetIdParameter, + beneficiary: MultiAddress, + amount: BalanceParameter, + }, + #[codec(index = 7)] + Burn { id: AssetIdParameter, who: MultiAddress, amount: BalanceParameter }, + // TODO: ED or not + // #[codec(index = 8)] + // Transfer { id: AssetIdParameter, target: MultiAddress, amount: BalanceParameter }, + #[codec(index = 9)] + TransferKeepAlive { + id: AssetIdParameter, + target: MultiAddress, + amount: BalanceParameter, + }, + #[codec(index = 17)] + SetMetadata { id: AssetIdParameter, name: Vec, symbol: Vec, decimals: u8 }, + #[codec(index = 18)] + ClearMetadata { id: AssetIdParameter }, + #[codec(index = 22)] + ApproveTransfer { + id: AssetIdParameter, + delegate: MultiAddress, + amount: BalanceParameter, + }, + #[codec(index = 23)] + CancelApproval { id: AssetIdParameter, delegate: MultiAddress }, + #[codec(index = 25)] + TransferApproved { + id: AssetIdParameter, + owner: MultiAddress, + destination: MultiAddress, + amount: BalanceParameter, + }, +} + +// TODO: remove unnecessary errors +#[derive(Debug, Copy, Clone, PartialEq, Eq, Encode, scale::Decode)] +#[cfg_attr(feature = "std", derive(scale_info::TypeInfo))] +pub(crate) enum AssetsError { + /// Account balance must be greater than or equal to the transfer amount. + BalanceLow, + /// The account to alter does not exist. + NoAccount, + /// The signing account has no permission to do the operation. + NoPermission, + /// The given asset ID is unknown. + Unknown, + /// The origin account is frozen. + Frozen, + /// The asset ID is already taken. + InUse, + /// Invalid witness data given. + BadWitness, + /// Minimum balance should be non-zero. + MinBalanceZero, + /// Unable to increment the consumer reference counters on the account. Either no provider + /// reference exists to allow a non-zero balance of a non-self-sufficient asset, or one + /// fewer then the maximum number of consumers has been reached. + UnavailableConsumer, + /// Invalid metadata given. + BadMetadata, + /// No approval exists that would allow the transfer. + Unapproved, + /// The source account would not survive the transfer and it needs to stay alive. + WouldDie, + /// The asset-account already exists. + AlreadyExists, + /// The asset-account doesn't have an associated deposit. + NoDeposit, + /// The operation would result in funds being burned. + WouldBurn, + /// The asset is a live asset and is actively being used. Usually emit for operations such + /// as `start_destroy` which require the asset to be in a destroying state. + LiveAsset, + /// The asset is not live, and likely being destroyed. + AssetNotLive, + /// The asset status is not the expected status. + IncorrectStatus, + /// The asset should be frozen before the given operation. + NotFrozen, + /// Callback action resulted in error + CallbackFailed, +} + +impl From for AssetsError { + fn from(error: PopApiError) -> Self { + match error { + PopApiError::Assets(e) => e, + _ => panic!("Expected AssetsError"), + } + } +} + +impl TryFrom for AssetsError { + type Error = PopApiError; + + fn try_from(status_code: u32) -> core::result::Result { + use AssetsError::*; + match status_code { + 0 => Ok(BalanceLow), + 1 => Ok(NoAccount), + 2 => Ok(NoPermission), + 3 => Ok(Unknown), + 4 => Ok(Frozen), + 5 => Ok(InUse), + 6 => Ok(BadWitness), + 7 => Ok(MinBalanceZero), + 8 => Ok(UnavailableConsumer), + 9 => Ok(BadMetadata), + 10 => Ok(Unapproved), + 11 => Ok(WouldDie), + 12 => Ok(AlreadyExists), + 13 => Ok(NoDeposit), + 14 => Ok(WouldBurn), + 15 => Ok(LiveAsset), + 16 => Ok(AssetNotLive), + 17 => Ok(IncorrectStatus), + 18 => Ok(NotFrozen), + _ => Err(UnknownStatusCode(status_code)), + } + } +} + +#[derive(Debug, Copy, Clone, PartialEq, Eq, Encode, scale::Decode)] +#[cfg_attr(feature = "std", derive(scale_info::TypeInfo))] +pub enum FungiblesError { + /// The signing account has no permission to do the operation. + NoPermission, + /// The given asset ID is unknown. + Unknown, + InsufficientBalance, + /// The asset ID is already taken. + InUse, + /// Minimum balance should be non-zero. + MinBalanceZero, +} + +impl From for FungiblesError { + fn from(error: balances::Error) -> Self { + match error { + balances::Error::InsufficientBalance => FungiblesError::InsufficientBalance, + _ => panic!("Unexpected pallet assets error. This error is unknown to pallet assets"), + } + } +} + +impl From for FungiblesError { + fn from(error: AssetsError) -> Self { + match error { + AssetsError::InUse => FungiblesError::InUse, + _ => panic!("Unexpected pallet assets error. This error is unknown to pallet assets"), + } + } +} + +impl From for FungiblesError { + fn from(error: PopApiError) -> Self { + match error { + PopApiError::Assets(e) => e.into(), + // PopApiError::Balances(e) => todo!("balances: {:?}", e), + PopApiError::Balances(e) => e.into(), + // PopApiError::Contracts(_e) => todo!("contracts"), + // PopApiError::SystemCallFiltered => 100, + // PopApiError::UnknownStatusCode(u) => u, + _ => panic!("Unexpected pallet assets error. This error is unknown to pallet assets"), + } + } +} diff --git a/pop-api/src/v0/assets/mod.rs b/pop-api/src/v0/assets/mod.rs index 7ad40f15..d6b0261c 100644 --- a/pop-api/src/v0/assets/mod.rs +++ b/pop-api/src/v0/assets/mod.rs @@ -1 +1 @@ -pub mod trust_backed; \ No newline at end of file +pub mod fungibles; \ No newline at end of file diff --git a/pop-api/src/v0/assets/trust_backed.rs b/pop-api/src/v0/assets/trust_backed.rs deleted file mode 100644 index fb413413..00000000 --- a/pop-api/src/v0/assets/trust_backed.rs +++ /dev/null @@ -1,519 +0,0 @@ -use crate::{Balance, PopApiError::UnknownStatusCode, RuntimeCall, *}; -use ink::prelude::vec::Vec; -use primitives::{AssetId, MultiAddress}; -use scale::{Compact, Encode}; - -type Result = core::result::Result; - -/// https://github.com/paritytech/polkadot-sdk/blob/master/substrate/frame/assets/src/lib.rs -/// -/// Extrinsics within pallet assets (TrustBackedAssets Instance) that can be used via the pop api on Pop Network: -/// 1. create -/// 2. start_destroy -/// 3. destroy_accounts -/// 4. destroy_approvals -/// 5. finish_destroy -/// 6. mint -/// 7. burn -/// 8. transfer -/// 9. transfer_keep_alive -/// 10. force_transfer -/// 11. freeze -/// 12. thaw -/// 13. freeze_asset -/// 14. thaw_asset -/// 15. transfer_ownership -/// 16. set_team -/// 17. set_metadata -/// 18. clear_metadata -/// 19. approve_transfer -/// 20. cancel_approval -/// 21. force_cancel_approval -/// 22. transfer_approved -/// 23. touch -/// 24. refund -/// 25. set_min_balance -/// 26. touch_other -/// 27. refund_other -/// 28. block - - -/// Issue a new class of fungible assets from a public origin. -pub fn create( - id: AssetId, - admin: impl Into>, - min_balance: Balance, -) -> Result<()> { - Ok(dispatch(RuntimeCall::TrustBackedAssets(TrustBackedAssetsCalls::Create { - id: id.into(), - admin: admin.into(), - min_balance: Compact(min_balance), - }))?) -} - -/// Start the process of destroying a fungible asset class. -pub fn start_destroy(id: AssetId) -> Result<()> { - Ok(dispatch(RuntimeCall::TrustBackedAssets(TrustBackedAssetsCalls::StartDestroy { - id: id.into(), - }))?) -} - -/// Destroy all accounts associated with a given asset. -pub fn destroy_accounts(id: AssetId) -> Result<()> { - Ok(dispatch(RuntimeCall::TrustBackedAssets(TrustBackedAssetsCalls::DestroyAccounts { - id: id.into(), - }))?) -} - -/// Destroy all approvals associated with a given asset up to the max (see runtime configuration TrustBackedAssets `RemoveItemsLimit`). -pub fn destroy_approvals(id: AssetId) -> Result<()> { - Ok(dispatch(RuntimeCall::TrustBackedAssets(TrustBackedAssetsCalls::DestroyApprovals { - id: id.into(), - }))?) -} - -/// Complete destroying asset and unreserve currency. -pub fn finish_destroy(id: AssetId) -> Result<()> { - Ok(dispatch(RuntimeCall::TrustBackedAssets(TrustBackedAssetsCalls::FinishDestroy { - id: id.into(), - }))?) -} - -/// Mint assets of a particular class. -pub fn mint( - id: AssetId, - beneficiary: impl Into>, - amount: Balance, -) -> Result<()> { - Ok(dispatch(RuntimeCall::TrustBackedAssets(TrustBackedAssetsCalls::Mint { - id: id.into(), - beneficiary: beneficiary.into(), - amount: Compact(amount), - }))?) -} - -/// Reduce the balance of `who` by as much as possible up to `amount` assets of `id`. -pub fn burn( - id: AssetId, - who: impl Into>, - amount: Balance, -) -> Result<()> { - Ok(dispatch(RuntimeCall::TrustBackedAssets(TrustBackedAssetsCalls::Burn { - id: id.into(), - who: who.into(), - amount: Compact(amount), - }))?) -} - -/// Move some assets from the sender account to another. -pub fn transfer( - id: AssetId, - target: impl Into>, - amount: Balance, -) -> Result<()> { - Ok(dispatch(RuntimeCall::TrustBackedAssets(TrustBackedAssetsCalls::Transfer { - id: id.into(), - target: target.into(), - amount: Compact(amount), - }))?) -} - -/// Move some assets from the sender account to another, keeping the sender account alive. -pub fn transfer_keep_alive( - id: AssetId, - target: impl Into>, - amount: Balance, -) -> Result<()> { - Ok(dispatch(RuntimeCall::TrustBackedAssets(TrustBackedAssetsCalls::TransferKeepAlive { - id: id.into(), - target: target.into(), - amount: Compact(amount), - }))?) -} - -/// Move some assets from one account to another. Sender should be the Admin of the asset `id`. -pub fn force_transfer( - id: AssetId, - source: impl Into>, - dest: impl Into>, - amount: Balance, -) -> Result<()> { - Ok(dispatch(RuntimeCall::TrustBackedAssets(TrustBackedAssetsCalls::ForceTransfer { - id: id.into(), - source: source.into(), - dest: dest.into(), - amount: Compact(amount), - }))?) -} - -/// Disallow further unprivileged transfers of an asset `id` from an account `who`. `who` -/// must already exist as an entry in `Account`s of the asset. If you want to freeze an -/// account that does not have an entry, use `touch_other` first. -pub fn freeze(id: AssetId, who: impl Into>) -> Result<()> { - Ok(dispatch(RuntimeCall::TrustBackedAssets(TrustBackedAssetsCalls::Freeze { - id: id.into(), - who: who.into(), - }))?) -} - -/// Allow unprivileged transfers to and from an account again. -pub fn thaw(id: AssetId, who: impl Into>) -> Result<()> { - Ok(dispatch(RuntimeCall::TrustBackedAssets(TrustBackedAssetsCalls::Thaw { - id: id.into(), - who: who.into(), - }))?) -} - -/// Disallow further unprivileged transfers for the asset class. -pub fn freeze_asset(id: AssetId) -> Result<()> { - Ok(dispatch(RuntimeCall::TrustBackedAssets(TrustBackedAssetsCalls::FreezeAsset { - id: id.into(), - }))?) -} - -/// Allow unprivileged transfers for the asset again. -pub fn thaw_asset(id: AssetId) -> Result<()> { - Ok(dispatch(RuntimeCall::TrustBackedAssets(TrustBackedAssetsCalls::ThawAsset { - id: id.into(), - }))?) -} - -/// Change the Owner of an asset. -pub fn transfer_ownership( - id: AssetId, - owner: impl Into>, -) -> Result<()> { - Ok(dispatch(RuntimeCall::TrustBackedAssets(TrustBackedAssetsCalls::TransferOwnership { - id: id.into(), - owner: owner.into(), - }))?) -} - -/// Change the Issuer, Admin and Freezer of an asset. -pub fn set_team( - id: AssetId, - issuer: impl Into>, - admin: impl Into>, - freezer: impl Into>, -) -> Result<()> { - Ok(dispatch(RuntimeCall::TrustBackedAssets(TrustBackedAssetsCalls::SetTeam { - id: id.into(), - issuer: issuer.into(), - admin: admin.into(), - freezer: freezer.into(), - }))?) -} - -/// Set the metadata for an asset. -pub fn set_metadata(id: AssetId, name: Vec, symbol: Vec, decimals: u8) -> Result<()> { - Ok(dispatch(RuntimeCall::TrustBackedAssets(TrustBackedAssetsCalls::SetMetadata { - id: id.into(), - name, - symbol, - decimals, - }))?) -} - -/// Clear the metadata for an asset. -pub fn clear_metadata(id: AssetId) -> Result<()> { - Ok(dispatch(RuntimeCall::TrustBackedAssets(TrustBackedAssetsCalls::ClearMetadata { - id: id.into(), - }))?) -} - -/// Approve an amount of asset for transfer by a delegated third-party account. -pub fn approve_transfer( - id: AssetId, - delegate: impl Into>, - amount: Balance, -) -> Result<()> { - Ok(dispatch(RuntimeCall::TrustBackedAssets(TrustBackedAssetsCalls::ApproveTransfer { - id: id.into(), - delegate: delegate.into(), - amount: Compact(amount), - }))?) -} - -/// Cancel all of some asset approved for delegated transfer by a third-party account. -pub fn cancel_approval( - id: AssetId, - delegate: impl Into>, -) -> Result<()> { - Ok(dispatch(RuntimeCall::TrustBackedAssets(TrustBackedAssetsCalls::CancelApproval { - id: id.into(), - delegate: delegate.into(), - }))?) -} - -/// Cancel all of some asset approved for delegated transfer by a third-party account. -pub fn force_cancel_approval( - id: AssetId, - owner: impl Into>, - delegate: impl Into>, -) -> Result<()> { - Ok(dispatch(RuntimeCall::TrustBackedAssets(TrustBackedAssetsCalls::ForceCancelApproval { - id: id.into(), - owner: owner.into(), - delegate: delegate.into(), - }))?) -} - -/// Transfer some asset balance from a previously delegated account to some third-party -/// account. -pub fn transfer_approved( - id: AssetId, - owner: impl Into>, - destination: impl Into>, - amount: Balance, -) -> Result<()> { - Ok(dispatch(RuntimeCall::TrustBackedAssets(TrustBackedAssetsCalls::TransferApproved { - id: id.into(), - owner: owner.into(), - destination: destination.into(), - amount: Compact(amount), - }))?) -} - -/// Create an asset account for non-provider assets. -pub fn touch(id: AssetId) -> Result<()> { - Ok(dispatch(RuntimeCall::TrustBackedAssets(TrustBackedAssetsCalls::Touch { - id: id.into(), - }))?) -} - -/// Return the deposit (if any) of an asset account or a consumer reference (if any) of an -/// account. -pub fn refund(id: AssetId, allow_burn: bool) -> Result<()> { - Ok(dispatch(RuntimeCall::TrustBackedAssets(TrustBackedAssetsCalls::Refund { - id: id.into(), - allow_burn, - }))?) -} - -/// Sets the minimum balance of an asset. -pub fn set_min_balance(id: AssetId, min_balance: Balance) -> Result<()> { - Ok(dispatch(RuntimeCall::TrustBackedAssets(TrustBackedAssetsCalls::SetMinBalance { - id: id.into(), - min_balance: Compact(min_balance), - }))?) -} - -/// Create an asset account for `who`. -pub fn touch_other(id: AssetId, who: impl Into>) -> Result<()> { - Ok(dispatch(RuntimeCall::TrustBackedAssets(TrustBackedAssetsCalls::TouchOther { - id: id.into(), - who: who.into(), - }))?) -} - -/// Return the deposit (if any) of a target asset account. Useful if you are the depositor. -pub fn refund_other(id: AssetId, who: impl Into>) -> Result<()> { - Ok(dispatch(RuntimeCall::TrustBackedAssets(TrustBackedAssetsCalls::RefundOther { - id: id.into(), - who: who.into(), - }))?) -} - -/// Disallow further unprivileged transfers of an asset `id` to and from an account `who`. -pub fn block(id: AssetId, who: impl Into>) -> Result<()> { - Ok(dispatch(RuntimeCall::TrustBackedAssets(TrustBackedAssetsCalls::Block { - id: id.into(), - who: who.into(), - }))?) -} - -pub fn asset_exists(id: AssetId) -> Result { - Ok(state::read(RuntimeStateKeys::TrustBackedAssets(TrustBackedAssetsKeys::AssetExists(id)))?) -} - -// Parameters to extrinsics representing an asset id (`AssetIdParameter`) and a balance amount (`Balance`) are expected -// to be compact encoded. The pop api handles that for the developer. -// -// reference: https://substrate.stackexchange.com/questions/1873/what-is-the-meaning-of-palletcompact-in-pallet-development -// -// Asset id that is compact encoded. -type AssetIdParameter = Compact; -// Balance amount that is compact encoded. -type BalanceParameter = Compact; - -#[derive(Encode)] -pub(crate) enum TrustBackedAssetsCalls { - #[codec(index = 0)] - Create { - id: AssetIdParameter, - admin: MultiAddress, - min_balance: BalanceParameter, - }, - #[codec(index = 2)] - StartDestroy { id: AssetIdParameter }, - #[codec(index = 3)] - DestroyAccounts { id: AssetIdParameter }, - #[codec(index = 4)] - DestroyApprovals { id: AssetIdParameter }, - #[codec(index = 5)] - FinishDestroy { id: AssetIdParameter }, - #[codec(index = 6)] - Mint { - id: AssetIdParameter, - beneficiary: MultiAddress, - amount: BalanceParameter, - }, - #[codec(index = 7)] - Burn { id: AssetIdParameter, who: MultiAddress, amount: BalanceParameter }, - #[codec(index = 8)] - Transfer { id: AssetIdParameter, target: MultiAddress, amount: BalanceParameter }, - #[codec(index = 9)] - TransferKeepAlive { - id: AssetIdParameter, - target: MultiAddress, - amount: BalanceParameter, - }, - #[codec(index = 10)] - ForceTransfer { - id: AssetIdParameter, - source: MultiAddress, - dest: MultiAddress, - amount: BalanceParameter, - }, - #[codec(index = 11)] - Freeze { id: AssetIdParameter, who: MultiAddress }, - #[codec(index = 12)] - Thaw { id: AssetIdParameter, who: MultiAddress }, - #[codec(index = 13)] - FreezeAsset { id: AssetIdParameter }, - #[codec(index = 14)] - ThawAsset { id: AssetIdParameter }, - #[codec(index = 15)] - TransferOwnership { id: AssetIdParameter, owner: MultiAddress }, - #[codec(index = 16)] - SetTeam { - id: AssetIdParameter, - issuer: MultiAddress, - admin: MultiAddress, - freezer: MultiAddress, - }, - #[codec(index = 17)] - SetMetadata { id: AssetIdParameter, name: Vec, symbol: Vec, decimals: u8 }, - #[codec(index = 18)] - ClearMetadata { id: AssetIdParameter }, - #[codec(index = 22)] - ApproveTransfer { - id: AssetIdParameter, - delegate: MultiAddress, - amount: BalanceParameter, - }, - #[codec(index = 23)] - CancelApproval { id: AssetIdParameter, delegate: MultiAddress }, - #[codec(index = 24)] - ForceCancelApproval { - id: AssetIdParameter, - owner: MultiAddress, - delegate: MultiAddress, - }, - #[codec(index = 25)] - TransferApproved { - id: AssetIdParameter, - owner: MultiAddress, - destination: MultiAddress, - amount: BalanceParameter, - }, - #[codec(index = 26)] - Touch { id: AssetIdParameter }, - #[codec(index = 27)] - Refund { id: AssetIdParameter, allow_burn: bool }, - #[codec(index = 28)] - SetMinBalance { id: AssetIdParameter, min_balance: BalanceParameter }, - #[codec(index = 29)] - TouchOther { id: AssetIdParameter, who: MultiAddress }, - #[codec(index = 30)] - RefundOther { id: AssetIdParameter, who: MultiAddress }, - #[codec(index = 31)] - Block { id: AssetIdParameter, who: MultiAddress }, -} - -#[derive(Debug, Copy, Clone, PartialEq, Eq, Encode, scale::Decode)] -#[cfg_attr(feature = "std", derive(scale_info::TypeInfo))] -pub enum Error { - /// Account balance must be greater than or equal to the transfer amount. - BalanceLow, - /// The account to alter does not exist. - NoAccount, - /// The signing account has no permission to do the operation. - NoPermission, - /// The given asset ID is unknown. - Unknown, - /// The origin account is frozen. - Frozen, - /// The asset ID is already taken. - InUse, - /// Invalid witness data given. - BadWitness, - /// Minimum balance should be non-zero. - MinBalanceZero, - /// Unable to increment the consumer reference counters on the account. Either no provider - /// reference exists to allow a non-zero balance of a non-self-sufficient asset, or one - /// fewer then the maximum number of consumers has been reached. - UnavailableConsumer, - /// Invalid metadata given. - BadMetadata, - /// No approval exists that would allow the transfer. - Unapproved, - /// The source account would not survive the transfer and it needs to stay alive. - WouldDie, - /// The asset-account already exists. - AlreadyExists, - /// The asset-account doesn't have an associated deposit. - NoDeposit, - /// The operation would result in funds being burned. - WouldBurn, - /// The asset is a live asset and is actively being used. Usually emit for operations such - /// as `start_destroy` which require the asset to be in a destroying state. - LiveAsset, - /// The asset is not live, and likely being destroyed. - AssetNotLive, - /// The asset status is not the expected status. - IncorrectStatus, - /// The asset should be frozen before the given operation. - NotFrozen, - /// Callback action resulted in error - CallbackFailed, -} - -impl TryFrom for Error { - type Error = PopApiError; - - fn try_from(status_code: u32) -> core::result::Result { - use Error::*; - match status_code { - 0 => Ok(BalanceLow), - 1 => Ok(NoAccount), - 2 => Ok(NoPermission), - 3 => Ok(Unknown), - 4 => Ok(Frozen), - 5 => Ok(InUse), - 6 => Ok(BadWitness), - 7 => Ok(MinBalanceZero), - 8 => Ok(UnavailableConsumer), - 9 => Ok(BadMetadata), - 10 => Ok(Unapproved), - 11 => Ok(WouldDie), - 12 => Ok(AlreadyExists), - 13 => Ok(NoDeposit), - 14 => Ok(WouldBurn), - 15 => Ok(LiveAsset), - 16 => Ok(AssetNotLive), - 17 => Ok(IncorrectStatus), - 18 => Ok(NotFrozen), - _ => Err(UnknownStatusCode(status_code)), - } - } -} - -impl From for Error { - fn from(error: PopApiError) -> Self { - match error { - PopApiError::TrustBackedAssets(e) => e, - _ => panic!("Unexpected pallet assets error. This error is unknown to pallet assets"), - } - } -} diff --git a/pop-api/src/v0/balances.rs b/pop-api/src/v0/balances.rs index bf029178..bc48711e 100644 --- a/pop-api/src/v0/balances.rs +++ b/pop-api/src/v0/balances.rs @@ -28,7 +28,7 @@ pub(crate) enum BalancesCall { #[derive(Debug, Copy, Clone, PartialEq, Eq, scale::Encode, scale::Decode)] #[cfg_attr(feature = "std", derive(scale_info::TypeInfo))] -pub enum Error { +pub(crate) enum Error { /// Vesting balance too high to send value. VestingBalance, /// Account liquidity restrictions prevent withdrawal. diff --git a/pop-api/src/v0/contracts.rs b/pop-api/src/v0/contracts.rs new file mode 100644 index 00000000..d7a1a5dd --- /dev/null +++ b/pop-api/src/v0/contracts.rs @@ -0,0 +1,156 @@ +use crate::{ + PopApiError, + PopApiError::UnknownStatusCode, +}; + +#[derive(Debug, Copy, Clone, PartialEq, Eq, scale::Encode, scale::Decode)] +#[cfg_attr(feature = "std", derive(scale_info::TypeInfo))] +pub enum Error { + /// Invalid schedule supplied, e.g. with zero weight of a basic operation. + InvalidSchedule, + /// Invalid combination of flags supplied to `seal_call` or `seal_delegate_call`. + InvalidCallFlags, + /// The executed contract exhausted its gas limit. + OutOfGas, + /// The output buffer supplied to a contract API call was too small. + OutputBufferTooSmall, + /// Performing the requested transfer failed. Probably because there isn't enough + /// free balance in the sender's account. + TransferFailed, + /// Performing a call was denied because the calling depth reached the limit + /// of what is specified in the schedule. + MaxCallDepthReached, + /// No contract was found at the specified address. + ContractNotFound, + /// The code supplied to `instantiate_with_code` exceeds the limit specified in the + /// current schedule. + CodeTooLarge, + /// No code could be found at the supplied code hash. + CodeNotFound, + /// No code info could be found at the supplied code hash. + CodeInfoNotFound, + /// A buffer outside of sandbox memory was passed to a contract API function. + OutOfBounds, + /// Input passed to a contract API function failed to decode as expected type. + DecodingFailed, + /// Contract trapped during execution. + ContractTrapped, + /// The size defined in `T::MaxValueSize` was exceeded. + ValueTooLarge, + /// Termination of a contract is not allowed while the contract is already + /// on the call stack. Can be triggered by `seal_terminate`. + TerminatedWhileReentrant, + /// `seal_call` forwarded this contracts input. It therefore is no longer available. + InputForwarded, + /// The subject passed to `seal_random` exceeds the limit. + RandomSubjectTooLong, + /// The amount of topics passed to `seal_deposit_events` exceeds the limit. + TooManyTopics, + /// The chain does not provide a chain extension. Calling the chain extension results + /// in this error. Note that this usually shouldn't happen as deploying such contracts + /// is rejected. + NoChainExtension, + /// Failed to decode the XCM program. + XCMDecodeFailed, + /// A contract with the same AccountId already exists. + DuplicateContract, + /// A contract self destructed in its constructor. + /// + /// This can be triggered by a call to `seal_terminate`. + TerminatedInConstructor, + /// A call tried to invoke a contract that is flagged as non-reentrant. + /// The only other cause is that a call from a contract into the runtime tried to call back + /// into `pallet-contracts`. This would make the whole pallet reentrant with regard to + /// contract code execution which is not supported. + ReentranceDenied, + /// Origin doesn't have enough balance to pay the required storage deposits. + StorageDepositNotEnoughFunds, + /// More storage was created than allowed by the storage deposit limit. + StorageDepositLimitExhausted, + /// Code removal was denied because the code is still in use by at least one contract. + CodeInUse, + /// The contract ran to completion but decided to revert its storage changes. + /// Please note that this error is only returned from extrinsics. When called directly + /// or via RPC an `Ok` will be returned. In this case the caller needs to inspect the flags + /// to determine whether a reversion has taken place. + ContractReverted, + /// The contract's code was found to be invalid during validation. + /// + /// The most likely cause of this is that an API was used which is not supported by the + /// node. This happens if an older node is used with a new version of ink!. Try updating + /// your node to the newest available version. + /// + /// A more detailed error can be found on the node console if debug messages are enabled + /// by supplying `-lruntime::contracts=debug`. + CodeRejected, + /// An indeterministic code was used in a context where this is not permitted. + Indeterministic, + /// A pending migration needs to complete before the extrinsic can be called. + MigrationInProgress, + /// Migrate dispatch call was attempted but no migration was performed. + NoMigrationPerformed, + /// The contract has reached its maximum number of delegate dependencies. + MaxDelegateDependenciesReached, + /// The dependency was not found in the contract's delegate dependencies. + DelegateDependencyNotFound, + /// The contract already depends on the given delegate dependency. + DelegateDependencyAlreadyExists, + /// Can not add a delegate dependency to the code hash of the contract itself. + CannotAddSelfAsDelegateDependency, +} + + +impl TryFrom for Error { + type Error = PopApiError; + + fn try_from(status_code: u32) -> core::result::Result { + use Error::*; + match status_code { + 0 => Ok(InvalidSchedule), + 1 => Ok(InvalidCallFlags), + 2 => Ok(OutOfGas), + 3 => Ok(OutputBufferTooSmall), + 4 => Ok(TransferFailed), + 5 => Ok(MaxCallDepthReached), + 6 => Ok(ContractNotFound), + 7 => Ok(CodeTooLarge), + 8 => Ok(CodeNotFound), + 9 => Ok(CodeInfoNotFound), + 10 => Ok(OutOfBounds), + 11 => Ok(DecodingFailed), + 12 => Ok(ContractTrapped), + 13 => Ok(ValueTooLarge), + 14 => Ok(TerminatedWhileReentrant), + 15 => Ok(InputForwarded), + 16 => Ok(RandomSubjectTooLong), + 17 => Ok(TooManyTopics), + 18 => Ok(NoChainExtension), + 19 => Ok(XCMDecodeFailed), + 20 => Ok(DuplicateContract), + 21 => Ok(TerminatedInConstructor), + 22 => Ok(ReentranceDenied), + 23 => Ok(StorageDepositNotEnoughFunds), + 24 => Ok(StorageDepositLimitExhausted), + 25 => Ok(CodeInUse), + 26 => Ok(ContractReverted), + 27 => Ok(CodeRejected), + 28 => Ok(Indeterministic), + 29 => Ok(MigrationInProgress), + 30 => Ok(NoMigrationPerformed), + 31 => Ok(MaxDelegateDependenciesReached), + 32 => Ok(DelegateDependencyNotFound), + 33 => Ok(DelegateDependencyAlreadyExists), + 34 => Ok(CannotAddSelfAsDelegateDependency), + _ => Err(UnknownStatusCode(status_code)), + } + } +} + +impl From for Error { + fn from(error: PopApiError) -> Self { + match error { + PopApiError::Contracts(e) => e, + _ => panic!("expected balances error"), + } + } +} \ No newline at end of file diff --git a/pop-api/src/v0/mod.rs b/pop-api/src/v0/mod.rs index d914db24..def37e55 100644 --- a/pop-api/src/v0/mod.rs +++ b/pop-api/src/v0/mod.rs @@ -4,6 +4,7 @@ use crate::{ }; pub mod balances; +pub mod contracts; pub mod cross_chain; pub mod nfts; pub mod state; @@ -20,5 +21,5 @@ pub(crate) enum RuntimeCall { #[codec(index = 50)] Nfts(nfts::NftCalls), #[codec(index = 52)] - TrustBackedAssets(assets::trust_backed::TrustBackedAssetsCalls), + Assets(assets::fungibles::AssetsCall), } diff --git a/primitives/Cargo.toml b/primitives/Cargo.toml index b6f9adaa..1098b557 100644 --- a/primitives/Cargo.toml +++ b/primitives/Cargo.toml @@ -6,13 +6,25 @@ edition = "2021" [dependencies] bounded-collections = { version = "0.1", default-features = false } -scale = { package = "parity-scale-codec", version = "3", default-features = false, features = ["derive"] } + +scale = { package = "parity-scale-codec", version = "3.6.9", default-features = false, features = ["derive"] } +scale-decode = { version = "0.10.0", default-features = false, features = ["derive"], optional = true } +scale-encode = { version = "0.5.0", default-features = false, features = ["derive"], optional = true } scale-info = { version = "2.6", default-features = false, features = ["derive"], optional = true } +#scale = { workspace = true, features = ["max-encoded-len"] } +#scale-decode = { workspace = true, features = ["derive"], optional = true } +#scale-encode = { workspace = true, features = ["derive"], optional = true } +#scale-info = { workspace = true, features = ["derive"], optional = true } + [features] default = ["std"] std = [ "bounded-collections/std", "scale/std", + "scale-decode/std", + "scale-encode/std", "scale-info/std", ] +devnet = [] +testnet = [] \ No newline at end of file diff --git a/primitives/src/lib.rs b/primitives/src/lib.rs index ebad36d3..7c1672b8 100644 --- a/primitives/src/lib.rs +++ b/primitives/src/lib.rs @@ -1,10 +1,22 @@ #![cfg_attr(not(feature = "std"), no_std, no_main)] pub use bounded_collections::{BoundedBTreeMap, BoundedBTreeSet, BoundedVec, ConstU32}; +use scale::{Decode, Encode, MaxEncodedLen}; +#[cfg(feature = "std")] +use { + scale_decode::DecodeAsType, + scale_encode::EncodeAsType, + scale_info::TypeInfo, +}; + pub mod cross_chain; pub mod storage_keys; +#[derive(Encode, Decode, Debug, MaxEncodedLen, Eq, PartialEq, Ord, PartialOrd)] +#[cfg_attr(feature = "std", derive(TypeInfo, DecodeAsType, EncodeAsType))] +pub struct AccountId(pub [u8; 32]); + // Identifier for the class of asset. pub type AssetId = u32; // Id used for identifying non-fungible collections. diff --git a/primitives/src/storage_keys.rs b/primitives/src/storage_keys.rs index a03b3a09..67448842 100644 --- a/primitives/src/storage_keys.rs +++ b/primitives/src/storage_keys.rs @@ -1,11 +1,12 @@ use super::*; -use scale::{Decode, Encode, MaxEncodedLen}; +// use scale::{Decode, Encode, MaxEncodedLen}; #[derive(Encode, Decode, Debug, MaxEncodedLen)] pub enum RuntimeStateKeys { Nfts(NftsKeys), ParachainSystem(ParachainSystemKeys), - TrustBackedAssets(TrustBackedAssetsKeys), + #[cfg(feature = "devnet")] + Assets(AssetsKeys), } #[derive(Encode, Decode, Debug, MaxEncodedLen)] @@ -35,8 +36,15 @@ pub enum NftsKeys { CollectionAttribute(CollectionId, BoundedVec), } +/// The required input for state queries in pallet assets. +#[cfg(feature = "devnet")] #[derive(Encode, Decode, Debug, MaxEncodedLen)] -pub enum TrustBackedAssetsKeys { +pub enum AssetsKeys { + Allowance(AssetId, AccountId, AccountId), /// Check if the asset exists. AssetExists(AssetId), + /// Check balance. + BalanceOf(AssetId, AccountId), + /// Returns the total token supply for a given asset ID. + TotalSupply(AssetId), } diff --git a/runtime/devnet/Cargo.toml b/runtime/devnet/Cargo.toml index 55d9942d..d4fe2923 100644 --- a/runtime/devnet/Cargo.toml +++ b/runtime/devnet/Cargo.toml @@ -22,7 +22,7 @@ scale-info.workspace = true smallvec.workspace = true # Local -pop-primitives.workspace = true +pop-primitives = { workspace = true, default-features = false, features = ["devnet"] } pop-runtime-common = { workspace = true, default-features = false } # Substrate diff --git a/runtime/devnet/src/config/assets.rs b/runtime/devnet/src/config/assets.rs index f51f8875..2c8ea952 100644 --- a/runtime/devnet/src/config/assets.rs +++ b/runtime/devnet/src/config/assets.rs @@ -1,6 +1,6 @@ use crate::{ - deposit, AccountId, Balance, Balances, BlockNumber, Nfts, Runtime, RuntimeEvent, - RuntimeHoldReason, TrustBackedAssets, DAYS, EXISTENTIAL_DEPOSIT, UNIT, + deposit, AccountId, Assets, Balance, Balances, BlockNumber, Nfts, Runtime, RuntimeEvent, + RuntimeHoldReason, DAYS, EXISTENTIAL_DEPOSIT, UNIT, }; use frame_support::{ parameter_types, @@ -86,7 +86,7 @@ impl pallet_nft_fractionalization::Config for Runtime { type NftId = ::ItemId; type AssetBalance = >::Balance; type AssetId = >::AssetId; - type Assets = TrustBackedAssets; + type Assets = Assets; type Nfts = Nfts; type PalletId = NftFractionalizationPalletId; type WeightInfo = pallet_nft_fractionalization::weights::SubstrateWeight; @@ -96,7 +96,7 @@ impl pallet_nft_fractionalization::Config for Runtime { } pub type TrustBackedAssetsInstance = pallet_assets::Instance1; -pub(crate) type TrustBackedAssetsCall = pallet_assets::Call; +pub(crate) type AssetsCall = pallet_assets::Call; impl pallet_assets::Config for Runtime { type RuntimeEvent = RuntimeEvent; type Balance = Balance; diff --git a/runtime/devnet/src/config/mod.rs b/runtime/devnet/src/config/mod.rs index a3a64c92..c370bb1d 100644 --- a/runtime/devnet/src/config/mod.rs +++ b/runtime/devnet/src/config/mod.rs @@ -1,4 +1,4 @@ -mod assets; +pub(crate) mod assets; mod contracts; mod proxy; // Public due to integration tests crate. diff --git a/runtime/devnet/src/config/proxy.rs b/runtime/devnet/src/config/proxy.rs index a4fd479a..07d5f0f8 100644 --- a/runtime/devnet/src/config/proxy.rs +++ b/runtime/devnet/src/config/proxy.rs @@ -1,4 +1,4 @@ -use super::assets::TrustBackedAssetsCall; +use super::assets::AssetsCall; use crate::{Balances, Runtime, RuntimeCall, RuntimeEvent}; use frame_support::traits::InstanceFilter; use pop_runtime_common::proxy::{ @@ -34,16 +34,16 @@ impl InstanceFilter for ProxyType { }, ProxyType::AssetOwner => matches!( c, - RuntimeCall::Assets(TrustBackedAssetsCall::create { .. }) - | RuntimeCall::Assets(TrustBackedAssetsCall::start_destroy { .. }) - | RuntimeCall::Assets(TrustBackedAssetsCall::destroy_accounts { .. }) - | RuntimeCall::Assets(TrustBackedAssetsCall::destroy_approvals { .. }) - | RuntimeCall::Assets(TrustBackedAssetsCall::finish_destroy { .. }) - | RuntimeCall::Assets(TrustBackedAssetsCall::transfer_ownership { .. }) - | RuntimeCall::Assets(TrustBackedAssetsCall::set_team { .. }) - | RuntimeCall::Assets(TrustBackedAssetsCall::set_metadata { .. }) - | RuntimeCall::Assets(TrustBackedAssetsCall::clear_metadata { .. }) - | RuntimeCall::Assets(TrustBackedAssetsCall::set_min_balance { .. }) + RuntimeCall::Assets(AssetsCall::create { .. }) + | RuntimeCall::Assets(AssetsCall::start_destroy { .. }) + | RuntimeCall::Assets(AssetsCall::destroy_accounts { .. }) + | RuntimeCall::Assets(AssetsCall::destroy_approvals { .. }) + | RuntimeCall::Assets(AssetsCall::finish_destroy { .. }) + | RuntimeCall::Assets(AssetsCall::transfer_ownership { .. }) + | RuntimeCall::Assets(AssetsCall::set_team { .. }) + | RuntimeCall::Assets(AssetsCall::set_metadata { .. }) + | RuntimeCall::Assets(AssetsCall::clear_metadata { .. }) + | RuntimeCall::Assets(AssetsCall::set_min_balance { .. }) | RuntimeCall::Nfts(pallet_nfts::Call::create { .. }) | RuntimeCall::Nfts(pallet_nfts::Call::destroy { .. }) | RuntimeCall::Nfts(pallet_nfts::Call::redeposit { .. }) @@ -56,15 +56,15 @@ impl InstanceFilter for ProxyType { ), ProxyType::AssetManager => matches!( c, - RuntimeCall::Assets(TrustBackedAssetsCall::mint { .. }) - | RuntimeCall::Assets(TrustBackedAssetsCall::burn { .. }) - | RuntimeCall::Assets(TrustBackedAssetsCall::freeze { .. }) - | RuntimeCall::Assets(TrustBackedAssetsCall::block { .. }) - | RuntimeCall::Assets(TrustBackedAssetsCall::thaw { .. }) - | RuntimeCall::Assets(TrustBackedAssetsCall::freeze_asset { .. }) - | RuntimeCall::Assets(TrustBackedAssetsCall::thaw_asset { .. }) - | RuntimeCall::Assets(TrustBackedAssetsCall::touch_other { .. }) - | RuntimeCall::Assets(TrustBackedAssetsCall::refund_other { .. }) + RuntimeCall::Assets(AssetsCall::mint { .. }) + | RuntimeCall::Assets(AssetsCall::burn { .. }) + | RuntimeCall::Assets(AssetsCall::freeze { .. }) + | RuntimeCall::Assets(AssetsCall::block { .. }) + | RuntimeCall::Assets(AssetsCall::thaw { .. }) + | RuntimeCall::Assets(AssetsCall::freeze_asset { .. }) + | RuntimeCall::Assets(AssetsCall::thaw_asset { .. }) + | RuntimeCall::Assets(AssetsCall::touch_other { .. }) + | RuntimeCall::Assets(AssetsCall::refund_other { .. }) | RuntimeCall::Nfts(pallet_nfts::Call::force_mint { .. }) | RuntimeCall::Nfts(pallet_nfts::Call::update_mint_settings { .. }) | RuntimeCall::Nfts(pallet_nfts::Call::mint_pre_signed { .. }) diff --git a/runtime/devnet/src/extensions.rs b/runtime/devnet/src/extensions.rs deleted file mode 100644 index c8e88eb2..00000000 --- a/runtime/devnet/src/extensions.rs +++ /dev/null @@ -1,1018 +0,0 @@ -use cumulus_pallet_parachain_system::RelaychainDataProvider; -use frame_support::traits::{Contains, OriginTrait}; -use frame_support::{ - dispatch::{GetDispatchInfo, RawOrigin}, - pallet_prelude::*, - traits::{fungibles::Inspect, nonfungibles_v2::Inspect as NonFungiblesInspect}, -}; -use pallet_contracts::chain_extension::{ - BufInBufOutState, ChainExtension, ChargedAmount, Environment, Ext, InitState, RetVal, -}; -use pop_primitives::{ - cross_chain::CrossChainMessage, - storage_keys::{NftsKeys, ParachainSystemKeys, RuntimeStateKeys, TrustBackedAssetsKeys}, - AssetId, CollectionId, ItemId, -}; -use sp_core::crypto::UncheckedFrom; -use sp_runtime::{ - traits::{BlockNumberProvider, Dispatchable}, - DispatchError, -}; -use sp_std::{boxed::Box, vec::Vec}; -use xcm::{ - latest::{prelude::*, OriginKind::SovereignAccount}, - VersionedXcm, -}; - -use crate::{ - assets_config::TrustBackedAssetsInstance, AccountId, AllowedPopApiCalls, RuntimeCall, - RuntimeOrigin, UNIT, -}; - -const LOG_TARGET: &str = "pop-api::extension"; - -type ContractSchedule = ::Schedule; - -#[derive(Default)] -pub struct PopApiExtension; - -impl ChainExtension for PopApiExtension -where - T: pallet_contracts::Config - + pallet_xcm::Config - + pallet_assets::Config - + pallet_nfts::Config - + cumulus_pallet_parachain_system::Config - + frame_system::Config< - RuntimeOrigin = RuntimeOrigin, - AccountId = AccountId, - RuntimeCall = RuntimeCall, - >, - T::AccountId: UncheckedFrom + AsRef<[u8]>, -{ - fn call(&mut self, env: Environment) -> Result - where - E: Ext, - T::AccountId: UncheckedFrom + AsRef<[u8]>, - { - log::debug!(target:LOG_TARGET, " extension called "); - match v0::FuncId::try_from(env.func_id())? { - v0::FuncId::Dispatch => { - match dispatch::(env) { - Ok(()) => Ok(RetVal::Converging(0)), - Err(DispatchError::Module(error)) => { - // encode status code = pallet index in runtime + error index, allowing for - // 999 errors - Ok(RetVal::Converging( - (error.index as u32 * 1_000) + u32::from_le_bytes(error.error), - )) - }, - Err(e) => Err(e), - } - }, - v0::FuncId::ReadState => { - read_state::(env)?; - Ok(RetVal::Converging(0)) - }, - v0::FuncId::SendXcm => { - send_xcm::(env)?; - Ok(RetVal::Converging(0)) - }, - } - } -} - -pub mod v0 { - #[derive(Debug)] - pub enum FuncId { - Dispatch, - ReadState, - SendXcm, - } -} - -impl TryFrom for v0::FuncId { - type Error = DispatchError; - - fn try_from(func_id: u16) -> Result { - let id = match func_id { - 0x0 => Self::Dispatch, - 0x1 => Self::ReadState, - 0x2 => Self::SendXcm, - _ => { - log::error!("called an unregistered `func_id`: {:}", func_id); - return Err(DispatchError::Other("unimplemented func_id")); - }, - }; - - Ok(id) - } -} - -fn dispatch_call( - env: &mut Environment, - call: RuntimeCall, - mut origin: RuntimeOrigin, - log_prefix: &str, -) -> Result<(), DispatchError> -where - T: frame_system::Config, - RuntimeOrigin: From>, - E: Ext, -{ - let charged_dispatch_weight = env.charge_weight(call.get_dispatch_info().weight)?; - - log::debug!(target:LOG_TARGET, "{} inputted RuntimeCall: {:?}", log_prefix, call); - - origin.add_filter(AllowedPopApiCalls::contains); - - match call.dispatch(origin) { - Ok(info) => { - log::debug!(target:LOG_TARGET, "{} success, actual weight: {:?}", log_prefix, info.actual_weight); - - // refund weight if the actual weight is less than the charged weight - if let Some(actual_weight) = info.actual_weight { - env.adjust_weight(charged_dispatch_weight, actual_weight); - } - - Ok(()) - }, - Err(err) => { - log::debug!(target:LOG_TARGET, "{} failed: error: {:?}", log_prefix, err.error); - Err(err.error) - }, - } -} - -fn charge_overhead_weight( - env: &mut Environment, - len: u32, - log_prefix: &str, -) -> Result -where - T: pallet_contracts::Config, - E: Ext, -{ - let contract_host_weight = ContractSchedule::::get().host_fn_weights; - - // calculate weight for reading bytes of `len` - // reference: https://github.com/paritytech/polkadot-sdk/blob/117a9433dac88d5ac00c058c9b39c511d47749d2/substrate/frame/contracts/src/wasm/runtime.rs#L267 - let base_weight: Weight = contract_host_weight.return_per_byte.saturating_mul(len.into()); - - // debug_message weight is a good approximation of the additional overhead of going - // from contract layer to substrate layer. - // reference: https://github.com/paritytech/ink-examples/blob/b8d2caa52cf4691e0ddd7c919e4462311deb5ad0/psp22-extension/runtime/psp22-extension-example.rs#L236 - let overhead = contract_host_weight.debug_message; - - let charged_weight = env.charge_weight(base_weight.saturating_add(overhead))?; - log::debug!(target: LOG_TARGET, "{} charged weight: {:?}", log_prefix, charged_weight); - - Ok(charged_weight) -} - -fn dispatch(env: Environment) -> Result<(), DispatchError> -where - T: pallet_contracts::Config - + frame_system::Config, - RuntimeOrigin: From>, - E: Ext, -{ - const LOG_PREFIX: &str = " dispatch |"; - - let mut env = env.buf_in_buf_out(); - let len = env.in_len(); - - charge_overhead_weight::(&mut env, len, LOG_PREFIX)?; - - // read the input as RuntimeCall - let call: RuntimeCall = env.read_as_unbounded(len)?; - - // contract is the origin by default - let origin: RuntimeOrigin = RawOrigin::Signed(env.ext().address().clone()).into(); - - dispatch_call::(&mut env, call, origin, LOG_PREFIX) -} - -fn read_state(env: Environment) -> Result<(), DispatchError> -where - T: pallet_contracts::Config - + pallet_assets::Config - + pallet_nfts::Config - + cumulus_pallet_parachain_system::Config - + frame_system::Config, - E: Ext, -{ - const LOG_PREFIX: &str = " read_state |"; - - let mut env = env.buf_in_buf_out(); - - // To be conservative, we charge the weight for reading the input bytes of a fixed-size type. - let base_weight: Weight = ContractSchedule::::get() - .host_fn_weights - .return_per_byte - .saturating_mul(env.in_len().into()); - let charged_weight = env.charge_weight(base_weight)?; - - log::debug!(target:LOG_TARGET, "{} charged weight: {:?}", LOG_PREFIX, charged_weight); - - let key: RuntimeStateKeys = env.read_as()?; - - let result = match key { - RuntimeStateKeys::Nfts(key) => read_nfts_state::(key, &mut env), - RuntimeStateKeys::ParachainSystem(key) => { - read_parachain_system_state::(key, &mut env) - }, - RuntimeStateKeys::TrustBackedAssets(key) => { - read_trust_backed_assets_state::(key, &mut env) - }, - }? - .encode(); - - log::trace!( - target:LOG_TARGET, - "{} result: {:?}.", LOG_PREFIX, result - ); - env.write(&result, false, None).map_err(|e| { - log::trace!(target: LOG_TARGET, "{:?}", e); - DispatchError::Other("unable to write results to contract memory") - }) -} - -fn read_parachain_system_state( - key: ParachainSystemKeys, - env: &mut Environment, -) -> Result, DispatchError> -where - T: pallet_contracts::Config + cumulus_pallet_parachain_system::Config, - E: Ext, -{ - match key { - ParachainSystemKeys::LastRelayChainBlockNumber => { - env.charge_weight(T::DbWeight::get().reads(1_u64))?; - Ok(RelaychainDataProvider::::current_block_number().encode()) - }, - } -} - -fn read_nfts_state( - key: NftsKeys, - env: &mut Environment, -) -> Result, DispatchError> -where - T: pallet_contracts::Config + pallet_nfts::Config, - E: Ext, -{ - match key { - NftsKeys::Collection(collection) => { - env.charge_weight(T::DbWeight::get().reads(1_u64))?; - Ok(pallet_nfts::Collection::::get(collection).encode()) - }, - NftsKeys::CollectionOwner(collection) => { - env.charge_weight(T::DbWeight::get().reads(1_u64))?; - Ok(pallet_nfts::Pallet::::collection_owner(collection).encode()) - }, - NftsKeys::Item(collection, item) => { - env.charge_weight(T::DbWeight::get().reads(1_u64))?; - Ok(pallet_nfts::Item::::get(collection, item).encode()) - }, - NftsKeys::Owner(collection, item) => { - env.charge_weight(T::DbWeight::get().reads(1_u64))?; - Ok(pallet_nfts::Pallet::::owner(collection, item).encode()) - }, - NftsKeys::Attribute(collection, item, key) => { - env.charge_weight(T::DbWeight::get().reads(1_u64))?; - Ok(pallet_nfts::Pallet::::attribute(&collection, &item, &key).encode()) - }, - // NftsKeys::CustomAttribute(account, collection, item, key) => { - // env.charge_weight(T::DbWeight::get().reads(1_u64))?; - // Ok(pallet_nfts::Pallet::::custom_attribute(&account, &collection, &item, &key) - // .encode()) - // }, - NftsKeys::SystemAttribute(collection, item, key) => { - env.charge_weight(T::DbWeight::get().reads(1_u64))?; - Ok(pallet_nfts::Pallet::::system_attribute(&collection, item.as_ref(), &key) - .encode()) - }, - NftsKeys::CollectionAttribute(collection, key) => { - env.charge_weight(T::DbWeight::get().reads(1_u64))?; - Ok(pallet_nfts::Pallet::::collection_attribute(&collection, &key).encode()) - }, - } -} - -fn read_trust_backed_assets_state( - key: TrustBackedAssetsKeys, - env: &mut Environment, -) -> Result, DispatchError> -where - T: pallet_contracts::Config - + pallet_assets::Config, - E: Ext, -{ - match key { - TrustBackedAssetsKeys::AssetExists(id) => { - env.charge_weight(T::DbWeight::get().reads(1_u64))?; - Ok(pallet_assets::Pallet::::asset_exists(id).encode()) - }, - } -} - -fn send_xcm(env: Environment) -> Result<(), DispatchError> -where - T: pallet_contracts::Config - + frame_system::Config< - RuntimeOrigin = RuntimeOrigin, - AccountId = AccountId, - RuntimeCall = RuntimeCall, - >, - E: Ext, -{ - const LOG_PREFIX: &str = " send_xcm |"; - - let mut env = env.buf_in_buf_out(); - let len = env.in_len(); - - let _ = charge_overhead_weight::(&mut env, len, LOG_PREFIX)?; - - // read the input as CrossChainMessage - let xc_call: CrossChainMessage = env.read_as::()?; - - // Determine the call to dispatch - let (dest, message) = match xc_call { - CrossChainMessage::Relay(message) => { - let dest = Location::parent().into_versioned(); - let assets: Asset = (Here, 10 * UNIT).into(); - let beneficiary: Location = - AccountId32 { id: (env.ext().address().clone()).into(), network: None }.into(); - let message = Xcm::builder() - .withdraw_asset(assets.clone().into()) - .buy_execution(assets.clone(), Unlimited) - .transact( - SovereignAccount, - Weight::from_parts(250_000_000, 10_000), - message.encode().into(), - ) - .refund_surplus() - .deposit_asset(assets.into(), beneficiary) - .build(); - (dest, message) - }, - }; - - // TODO: revisit to replace with signed contract origin - let origin: RuntimeOrigin = RawOrigin::Root.into(); - - // Generate runtime call to dispatch - let call = RuntimeCall::PolkadotXcm(pallet_xcm::Call::send { - dest: Box::new(dest), - message: Box::new(VersionedXcm::V4(message)), - }); - - dispatch_call::(&mut env, call, origin, LOG_PREFIX) -} - -#[cfg(test)] -mod tests { - pub use super::*; - pub use crate::*; - use enumflags2::BitFlags; - pub use pallet_contracts::Code; - use pallet_nfts::{CollectionConfig, CollectionSetting, CollectionSettings, MintSettings}; - use parachains_common::CollectionId; - pub use sp_runtime::{traits::Hash, AccountId32}; - - const DEBUG_OUTPUT: pallet_contracts::DebugInfo = pallet_contracts::DebugInfo::UnsafeDebug; - - const ALICE: AccountId32 = AccountId32::new([1_u8; 32]); - const BOB: AccountId32 = AccountId32::new([2_u8; 32]); - const INITIAL_AMOUNT: u128 = 100_000 * UNIT; - const GAS_LIMIT: Weight = Weight::from_parts(100_000_000_000, 3 * 1024 * 1024); - - fn new_test_ext() -> sp_io::TestExternalities { - let mut t = frame_system::GenesisConfig::::default() - .build_storage() - .expect("Frame system builds valid default genesis config"); - - pallet_balances::GenesisConfig:: { - balances: vec![(ALICE, INITIAL_AMOUNT), (BOB, INITIAL_AMOUNT)], - } - .assimilate_storage(&mut t) - .expect("Pallet balances storage can be assimilated"); - - let mut ext = sp_io::TestExternalities::new(t); - ext.execute_with(|| System::set_block_number(1)); - ext - } - - fn load_wasm_module(path: &str) -> std::io::Result<(Vec, ::Output)> - where - T: frame_system::Config, - { - let wasm_binary = std::fs::read(path)?; - let code_hash = T::Hashing::hash(&wasm_binary); - Ok((wasm_binary, code_hash)) - } - - fn function_selector(name: &str) -> Vec { - let hash = sp_io::hashing::blake2_256(name.as_bytes()); - [hash[0..4].to_vec()].concat() - } - - // NFT helper functions - fn collection_config_from_disabled_settings( - settings: BitFlags, - ) -> CollectionConfig { - CollectionConfig { - settings: CollectionSettings::from_disabled(settings), - max_supply: None, - mint_settings: MintSettings::default(), - } - } - - fn default_collection_config() -> CollectionConfig { - collection_config_from_disabled_settings(CollectionSetting::DepositRequired.into()) - } - - #[test] - #[ignore] - fn dispatch_balance_transfer_from_contract_works() { - new_test_ext().execute_with(|| { - let _ = env_logger::try_init(); - - let (wasm_binary, _) = load_wasm_module::( - "../../pop-api/examples/balance-transfer/target/ink/balance_transfer.wasm", - ) - .unwrap(); - - let init_value = 100 * UNIT; - - let result = Contracts::bare_instantiate( - ALICE, - init_value, - GAS_LIMIT, - None, - Code::Upload(wasm_binary), - function_selector("new"), - vec![], - DEBUG_OUTPUT, - pallet_contracts::CollectEvents::Skip, - ) - .result - .unwrap(); - - assert!(!result.result.did_revert(), "deploying contract reverted {:?}", result); - - let addr = result.account_id; - - let function = function_selector("transfer_through_runtime"); - let value_to_send: u128 = 10 * UNIT; - let params = [function, BOB.encode(), value_to_send.encode()].concat(); - - let bob_balance_before = Balances::free_balance(&BOB); - assert_eq!(bob_balance_before, INITIAL_AMOUNT); - - let result = Contracts::bare_call( - ALICE, - addr.clone(), - 0, - Weight::from_parts(100_000_000_000, 3 * 1024 * 1024), - None, - params, - DEBUG_OUTPUT, - pallet_contracts::CollectEvents::Skip, - pallet_contracts::Determinism::Enforced, - ); - - if DEBUG_OUTPUT == pallet_contracts::DebugInfo::UnsafeDebug { - log::debug!( - "Contract debug buffer - {:?}", - String::from_utf8(result.debug_message.clone()) - ); - log::debug!("result: {:?}", result); - } - - // check for revert - assert!(!result.result.unwrap().did_revert(), "Contract reverted!"); - - let bob_balance_after = Balances::free_balance(&BOB); - assert_eq!(bob_balance_before + value_to_send, bob_balance_after); - }); - } - - // Create a test for tesing create_nft_collection - #[test] - #[ignore] - fn dispatch_nfts_create_nft_collection() { - new_test_ext().execute_with(|| { - let _ = env_logger::try_init(); - - let (wasm_binary, _) = load_wasm_module::( - "../../pop-api/examples/nfts/target/ink/pop_api_nft_example.wasm", - ) - .unwrap(); - - let init_value = 100 * UNIT; - - let result = Contracts::bare_instantiate( - ALICE, - init_value, - GAS_LIMIT, - None, - Code::Upload(wasm_binary), - function_selector("new"), - vec![], - DEBUG_OUTPUT, - pallet_contracts::CollectEvents::Skip, - ) - .result - .unwrap(); - - assert!(!result.result.did_revert(), "deploying contract reverted {:?}", result); - - let addr = result.account_id; - - let function = function_selector("create_nft_collection"); - - let params = [function].concat(); - - let result = Contracts::bare_call( - ALICE, - addr.clone(), - 0, - Weight::from_parts(100_000_000_000, 3 * 1024 * 1024), - None, - params, - DEBUG_OUTPUT, - pallet_contracts::CollectEvents::Skip, - pallet_contracts::Determinism::Enforced, - ); - - if DEBUG_OUTPUT == pallet_contracts::DebugInfo::UnsafeDebug { - log::debug!( - "Contract debug buffer - {:?}", - String::from_utf8(result.debug_message.clone()) - ); - log::debug!("result: {:?}", result); - } - - // check that the nft collection was created - assert_eq!(Nfts::collection_owner(0), Some(addr.clone().into())); - - // test reading the collection - let function = function_selector("read_collection"); - - let params = [function, 0.encode()].concat(); - - let result = Contracts::bare_call( - ALICE, - addr.clone(), - 0, - Weight::from_parts(100_000_000_000, 3 * 1024 * 1024), - None, - params, - DEBUG_OUTPUT, - pallet_contracts::CollectEvents::Skip, - pallet_contracts::Determinism::Enforced, - ); - - if DEBUG_OUTPUT == pallet_contracts::DebugInfo::UnsafeDebug { - log::debug!( - "Contract debug buffer - {:?}", - String::from_utf8(result.debug_message.clone()) - ); - log::debug!("result: {:?}", result); - } - - // assert that the collection was read successfully - assert_eq!(result.result.clone().unwrap().data, vec![1, 1]); - }); - } - - #[test] - #[ignore] - fn dispatch_nfts_mint_from_contract_works() { - new_test_ext().execute_with(|| { - let _ = env_logger::try_init(); - - let (wasm_binary, _) = - load_wasm_module::("../../pop-api/examples/nfts/target/ink/nfts.wasm") - .unwrap(); - - let init_value = 100; - - let result = Contracts::bare_instantiate( - ALICE, - init_value, - GAS_LIMIT, - None, - Code::Upload(wasm_binary), - function_selector("new"), - vec![], - DEBUG_OUTPUT, - pallet_contracts::CollectEvents::Skip, - ) - .result - .unwrap(); - - assert!(!result.result.did_revert(), "deploying contract reverted {:?}", result); - - let addr = result.account_id; - - let collection_id: u32 = 0; - let item_id: u32 = 1; - - // create nft collection with contract as owner - assert_eq!( - Nfts::force_create( - RuntimeOrigin::root(), - addr.clone().into(), - default_collection_config() - ), - Ok(()) - ); - - assert_eq!(Nfts::collection_owner(collection_id), Some(addr.clone().into())); - // assert that the item does not exist yet - assert_eq!(Nfts::owner(collection_id, item_id), None); - - let function = function_selector("mint_through_runtime"); - - let params = - [function, collection_id.encode(), item_id.encode(), BOB.encode()].concat(); - - let result = Contracts::bare_call( - ALICE, - addr.clone(), - 0, - Weight::from_parts(100_000_000_000, 3 * 1024 * 1024), - None, - params, - DEBUG_OUTPUT, - pallet_contracts::CollectEvents::Skip, - pallet_contracts::Determinism::Enforced, - ); - - if DEBUG_OUTPUT == pallet_contracts::DebugInfo::UnsafeDebug { - log::debug!( - "Contract debug buffer - {:?}", - String::from_utf8(result.debug_message.clone()) - ); - log::debug!("result: {:?}", result); - } - - // check for revert - assert!(!result.result.unwrap().did_revert(), "Contract reverted!"); - - assert_eq!(Nfts::owner(collection_id, item_id), Some(BOB.into())); - }); - } - - #[test] - #[ignore] - fn nfts_mint_surfaces_error() { - new_test_ext().execute_with(|| { - let _ = env_logger::try_init(); - - let (wasm_binary, _) = - load_wasm_module::("../../pop-api/examples/nfts/target/ink/nfts.wasm") - .unwrap(); - - let init_value = 100; - - let result = Contracts::bare_instantiate( - ALICE, - init_value, - GAS_LIMIT, - None, - Code::Upload(wasm_binary), - function_selector("new"), - vec![], - DEBUG_OUTPUT, - pallet_contracts::CollectEvents::Skip, - ) - .result - .unwrap(); - - assert!(!result.result.did_revert(), "deploying contract reverted {:?}", result); - - let addr = result.account_id; - - let collection_id: u32 = 0; - let item_id: u32 = 1; - - let function = function_selector("mint_through_runtime"); - - let params = - [function, collection_id.encode(), item_id.encode(), BOB.encode()].concat(); - - let result = Contracts::bare_call( - ALICE, - addr.clone(), - 0, - Weight::from_parts(100_000_000_000, 3 * 1024 * 1024), - None, - params, - DEBUG_OUTPUT, - pallet_contracts::CollectEvents::Skip, - pallet_contracts::Determinism::Enforced, - ); - - if DEBUG_OUTPUT == pallet_contracts::DebugInfo::UnsafeDebug { - log::debug!( - "Contract debug buffer - {:?}", - String::from_utf8(result.debug_message.clone()) - ); - log::debug!("result: {:?}", result); - } - - // check for revert with expected error - let result = result.result.unwrap(); - assert!(result.did_revert()); - }); - } - - #[test] - #[ignore] - fn reading_last_relay_chain_block_number_works() { - new_test_ext().execute_with(|| { - let _ = env_logger::try_init(); - - let (wasm_binary, _) = load_wasm_module::( - "../../pop-api/examples/read-runtime-state/target/ink/read_relay_blocknumber.wasm", - ) - .unwrap(); - - let init_value = 100; - - let contract = Contracts::bare_instantiate( - ALICE, - init_value, - GAS_LIMIT, - None, - Code::Upload(wasm_binary), - function_selector("new"), - vec![], - DEBUG_OUTPUT, - pallet_contracts::CollectEvents::Skip, - ) - .result - .unwrap(); - - assert!(!contract.result.did_revert(), "deploying contract reverted {:?}", contract); - - let addr = contract.account_id; - - let function = function_selector("read_relay_block_number"); - let params = [function].concat(); - - let result = Contracts::bare_call( - ALICE, - addr.clone(), - 0, - Weight::from_parts(100_000_000_000, 3 * 1024 * 1024), - None, - params, - DEBUG_OUTPUT, - pallet_contracts::CollectEvents::UnsafeCollect, - pallet_contracts::Determinism::Relaxed, - ); - - if DEBUG_OUTPUT == pallet_contracts::DebugInfo::UnsafeDebug { - log::debug!( - "Contract debug buffer - {:?}", - String::from_utf8(result.debug_message.clone()) - ); - log::debug!("result: {:?}", result); - } - - // check for revert - assert!(!result.result.unwrap().did_revert(), "Contract reverted!"); - }); - } - - #[test] - #[ignore] - fn place_spot_order_from_contract_works() { - new_test_ext().execute_with(|| { - let _ = env_logger::try_init(); - - let (wasm_binary, _) = load_wasm_module::( - "../../pop-api/examples/place-spot-order/target/ink/spot_order.wasm", - ) - .unwrap(); - - let init_value = 100 * UNIT; - - let result = Contracts::bare_instantiate( - ALICE, - init_value, - GAS_LIMIT, - None, - Code::Upload(wasm_binary), - function_selector("new"), - vec![], - DEBUG_OUTPUT, - pallet_contracts::CollectEvents::Skip, - ) - .result - .unwrap(); - - assert!(!result.result.did_revert(), "deploying contract reverted {:?}", result); - - let addr = result.account_id; - - let function = function_selector("place_spot_order"); - - let max_amount = 1 * UNIT; - let para_id = 2000; - - let params = [function, max_amount.encode(), para_id.encode()].concat(); - - let result = Contracts::bare_call( - ALICE, - addr.clone(), - 0, - Weight::from_parts(100_000_000_000, 3 * 1024 * 1024), - None, - params, - DEBUG_OUTPUT, - pallet_contracts::CollectEvents::Skip, - pallet_contracts::Determinism::Enforced, - ); - - if DEBUG_OUTPUT == pallet_contracts::DebugInfo::UnsafeDebug { - log::debug!( - "Contract debug buffer - {:?}", - String::from_utf8(result.debug_message.clone()) - ); - log::debug!("result: {:?}", result); - } - - // check for revert - assert!(!result.result.unwrap().did_revert(), "Contract reverted!"); - }); - } - - #[test] - #[ignore] - fn dispatch_trust_backed_assets_mint_from_contract_works() { - new_test_ext().execute_with(|| { - let _ = env_logger::try_init(); - - let (wasm_binary, _) = load_wasm_module::( - "../../pop-api/examples/trust_backed_assets/target/ink/pop_api_trust_backed_assets_example.wasm", - ) - .unwrap(); - - let init_value = 100; - - let result = Contracts::bare_instantiate( - ALICE, - init_value, - GAS_LIMIT, - None, - Code::Upload(wasm_binary), - function_selector("new"), - vec![], - DEBUG_OUTPUT, - pallet_contracts::CollectEvents::Skip, - ) - .result - .unwrap(); - - assert!(!result.result.did_revert(), "deploying contract reverted {:?}", result); - let addr = result.account_id; - - let asset_id: u32 = 1; - let min_balance = 1; - let amount: u128 = 100 * UNIT; - let function = function_selector("mint_asset_through_runtime"); - let params = [function, asset_id.encode(), BOB.encode(), amount.encode()].concat(); - - // Mint asset which does not exist. - let result = Contracts::bare_call( - ALICE, - addr.clone(), - 0, - GAS_LIMIT, - None, - params.clone(), - DEBUG_OUTPUT, - pallet_contracts::CollectEvents::Skip, - pallet_contracts::Determinism::Enforced, - ); - - if DEBUG_OUTPUT == pallet_contracts::DebugInfo::UnsafeDebug { - log::debug!( - "Contract debug buffer - {:?}", - String::from_utf8(result.debug_message.clone()) - ); - log::debug!("result: {:?}", result); - } - - // Check for revert. - assert!(result.result.unwrap().did_revert(), "Contract should have been reverted!"); - - // Create asset with contract as owner. - assert_eq!( - TrustBackedAssets::force_create( - RuntimeOrigin::root(), - asset_id.into(), - addr.clone().into(), - true, - min_balance, - ), - Ok(()) - ); - - // Check Bob's asset balance before minting through contract. - let bob_balance_before = TrustBackedAssets::balance(asset_id, &BOB); - assert_eq!(bob_balance_before, 0); - - let result = Contracts::bare_call( - ALICE, - addr.clone(), - 0, - GAS_LIMIT, - None, - params, - DEBUG_OUTPUT, - pallet_contracts::CollectEvents::Skip, - pallet_contracts::Determinism::Enforced, - ); - - if DEBUG_OUTPUT == pallet_contracts::DebugInfo::UnsafeDebug { - log::debug!( - "Contract debug buffer - {:?}", - String::from_utf8(result.debug_message.clone()) - ); - log::debug!("result: {:?}", result); - } - - // Check for revert - assert!(!result.result.unwrap().did_revert(), "Contract reverted!"); - - let bob_balance_after = TrustBackedAssets::balance(asset_id, &BOB); - assert_eq!(bob_balance_after, bob_balance_before + amount); - }); - } - - #[test] - #[ignore] - fn allow_call_filter_blocks_call() { - new_test_ext().execute_with(|| { - let _ = env_logger::try_init(); - - let (wasm_binary, _) = load_wasm_module::( - "../../tests/contracts/filtered-call/target/ink/pop_api_filtered_call.wasm", - ) - .unwrap(); - - let init_value = 100 * UNIT; - - let result = Contracts::bare_instantiate( - ALICE, - init_value, - GAS_LIMIT, - None, - Code::Upload(wasm_binary), - function_selector("new"), - vec![], - DEBUG_OUTPUT, - pallet_contracts::CollectEvents::Skip, - ) - .result - .unwrap(); - - assert!(!result.result.did_revert(), "deploying contract reverted {:?}", result); - - let addr = result.account_id; - - let function = function_selector("get_filtered"); - let params = [function].concat(); - - let result = Contracts::bare_call( - ALICE, - addr.clone(), - 0, - Weight::from_parts(100_000_000_000, 3 * 1024 * 1024), - None, - params, - DEBUG_OUTPUT, - pallet_contracts::CollectEvents::Skip, - pallet_contracts::Determinism::Enforced, - ); - - if DEBUG_OUTPUT == pallet_contracts::DebugInfo::UnsafeDebug { - log::debug!( - "Contract debug buffer - {:?}", - String::from_utf8(result.debug_message.clone()) - ); - log::debug!("filtered result: {:?}", result); - } - - // check for revert - assert!(!result.result.unwrap().did_revert(), "Contract reverted!"); - }); - } -} diff --git a/runtime/devnet/src/extensions/mod.rs b/runtime/devnet/src/extensions/mod.rs new file mode 100644 index 00000000..096f21c9 --- /dev/null +++ b/runtime/devnet/src/extensions/mod.rs @@ -0,0 +1,896 @@ +use cumulus_pallet_parachain_system::RelaychainDataProvider; +use frame_support::traits::{Contains, OriginTrait}; +use frame_support::{ + dispatch::{GetDispatchInfo, RawOrigin}, + pallet_prelude::*, + traits::{ + fungibles::{approvals::Inspect as ApprovalInspect, Inspect}, + nonfungibles_v2::Inspect as NonFungiblesInspect, + }, +}; +use pallet_contracts::chain_extension::{ + BufInBufOutState, ChainExtension, ChargedAmount, Environment, Ext, InitState, RetVal, +}; +use pop_primitives::{ + cross_chain::CrossChainMessage, + storage_keys::{AssetsKeys, NftsKeys, ParachainSystemKeys, RuntimeStateKeys}, + AssetId, CollectionId, ItemId, +}; +use sp_core::crypto::UncheckedFrom; +use sp_runtime::{ + traits::{BlockNumberProvider, Dispatchable}, + DispatchError, +}; +use sp_std::{boxed::Box, vec::Vec}; +use xcm::{ + latest::{prelude::*, OriginKind::SovereignAccount}, + VersionedXcm, +}; + +use crate::{ + config::assets::TrustBackedAssetsInstance, AccountId, AllowedPopApiCalls, RuntimeCall, + RuntimeOrigin, UNIT, +}; + +#[cfg(test)] +mod tests; + +const LOG_TARGET: &str = "pop-api::extension"; + +type ContractSchedule = ::Schedule; + +#[derive(Default)] +pub struct PopApiExtension; + +impl ChainExtension for PopApiExtension +where + T: pallet_contracts::Config + + pallet_xcm::Config + + pallet_assets::Config + + pallet_nfts::Config + + cumulus_pallet_parachain_system::Config + + frame_system::Config< + RuntimeOrigin = RuntimeOrigin, + AccountId = AccountId, + RuntimeCall = RuntimeCall, + >, + T::AccountId: UncheckedFrom + AsRef<[u8]>, +{ + fn call(&mut self, env: Environment) -> Result + where + E: Ext, + // T::AccountId: UncheckedFrom + AsRef<[u8]>, + { + log::debug!(target:LOG_TARGET, " extension called "); + match v0::FuncId::try_from(env.func_id())? { + v0::FuncId::Dispatch => { + match dispatch::(env) { + Ok(()) => Ok(RetVal::Converging(0)), + Err(DispatchError::Module(error)) => { + // encode status code = pallet index in runtime + error index, allowing for + // 999 errors + Ok(RetVal::Converging( + (error.index as u32 * 1_000) + u32::from_le_bytes(error.error), + )) + }, + Err(e) => Err(e), + } + }, + v0::FuncId::ReadState => { + read_state::(env)?; + Ok(RetVal::Converging(0)) + }, + v0::FuncId::SendXcm => { + send_xcm::(env)?; + Ok(RetVal::Converging(0)) + }, + } + } +} + +pub mod v0 { + #[derive(Debug)] + pub enum FuncId { + Dispatch, + ReadState, + SendXcm, + } +} + +impl TryFrom for v0::FuncId { + type Error = DispatchError; + + fn try_from(func_id: u16) -> Result { + let id = match func_id { + 0x0 => Self::Dispatch, + 0x1 => Self::ReadState, + 0x2 => Self::SendXcm, + _ => { + log::error!("called an unregistered `func_id`: {:}", func_id); + return Err(DispatchError::Other("unimplemented func_id")); + }, + }; + + Ok(id) + } +} + +fn dispatch_call( + env: &mut Environment, + call: RuntimeCall, + mut origin: RuntimeOrigin, + log_prefix: &str, +) -> Result<(), DispatchError> +where + T: frame_system::Config, + RuntimeOrigin: From>, + E: Ext, +{ + let charged_dispatch_weight = env.charge_weight(call.get_dispatch_info().weight)?; + + log::debug!(target:LOG_TARGET, "{} Inputted RuntimeCall: {:?}", log_prefix, call); + + origin.add_filter(AllowedPopApiCalls::contains); + + match call.dispatch(origin) { + Ok(info) => { + log::debug!(target:LOG_TARGET, "{} success, actual weight: {:?}", log_prefix, info.actual_weight); + + // refund weight if the actual weight is less than the charged weight + if let Some(actual_weight) = info.actual_weight { + env.adjust_weight(charged_dispatch_weight, actual_weight); + } + + Ok(()) + }, + Err(err) => { + log::debug!(target:LOG_TARGET, "{} failed: error: {:?}", log_prefix, err.error); + Err(err.error) + }, + } +} + +fn charge_overhead_weight( + env: &mut Environment, + len: u32, + log_prefix: &str, +) -> Result +where + T: pallet_contracts::Config, + E: Ext, +{ + let contract_host_weight = ContractSchedule::::get().host_fn_weights; + + // calculate weight for reading bytes of `len` + // reference: https://github.com/paritytech/polkadot-sdk/blob/117a9433dac88d5ac00c058c9b39c511d47749d2/substrate/frame/contracts/src/wasm/runtime.rs#L267 + let base_weight: Weight = contract_host_weight.return_per_byte.saturating_mul(len.into()); + + // debug_message weight is a good approximation of the additional overhead of going + // from contract layer to substrate layer. + // reference: https://github.com/paritytech/ink-examples/blob/b8d2caa52cf4691e0ddd7c919e4462311deb5ad0/psp22-extension/runtime/psp22-extension-example.rs#L236 + let overhead = contract_host_weight.debug_message; + + let charged_weight = env.charge_weight(base_weight.saturating_add(overhead))?; + log::debug!(target: LOG_TARGET, "{} charged weight: {:?}", log_prefix, charged_weight); + + Ok(charged_weight) +} + +fn dispatch(env: Environment) -> Result<(), DispatchError> +where + T: pallet_contracts::Config + + frame_system::Config, + RuntimeOrigin: From>, + E: Ext, +{ + const LOG_PREFIX: &str = " dispatch |"; + + let mut env = env.buf_in_buf_out(); + let len = env.in_len(); + + charge_overhead_weight::(&mut env, len, LOG_PREFIX)?; + + // read the input as RuntimeCall + let call: RuntimeCall = env.read_as_unbounded(len)?; + + log::debug!(target: LOG_TARGET, "Read input as call successfully"); + + // contract is the origin by default + let origin: RuntimeOrigin = RawOrigin::Signed(env.ext().address().clone()).into(); + + dispatch_call::(&mut env, call, origin, LOG_PREFIX) +} + +fn read_state(env: Environment) -> Result<(), DispatchError> +where + T: pallet_contracts::Config + + pallet_assets::Config + + pallet_nfts::Config + + cumulus_pallet_parachain_system::Config + + frame_system::Config, + E: Ext, +{ + const LOG_PREFIX: &str = " read_state |"; + + let mut env = env.buf_in_buf_out(); + + // To be conservative, we charge the weight for reading the input bytes of a fixed-size type. + let base_weight: Weight = ContractSchedule::::get() + .host_fn_weights + .return_per_byte + .saturating_mul(env.in_len().into()); + let charged_weight = env.charge_weight(base_weight)?; + + log::debug!(target:LOG_TARGET, "{} charged weight: {:?}", LOG_PREFIX, charged_weight); + + let key: RuntimeStateKeys = env.read_as()?; + + let result = match key { + RuntimeStateKeys::Nfts(key) => read_nfts_state::(key, &mut env), + RuntimeStateKeys::ParachainSystem(key) => { + read_parachain_system_state::(key, &mut env) + }, + RuntimeStateKeys::Assets(key) => read_trust_backed_assets_state::(key, &mut env), + }? + .encode(); + + log::trace!( + target:LOG_TARGET, + "{} result: {:?}.", LOG_PREFIX, result + ); + env.write(&result, false, None).map_err(|e| { + log::trace!(target: LOG_TARGET, "{:?}", e); + DispatchError::Other("unable to write results to contract memory") + }) +} + +fn read_parachain_system_state( + key: ParachainSystemKeys, + env: &mut Environment, +) -> Result, DispatchError> +where + T: pallet_contracts::Config + cumulus_pallet_parachain_system::Config, + E: Ext, +{ + match key { + ParachainSystemKeys::LastRelayChainBlockNumber => { + env.charge_weight(T::DbWeight::get().reads(1_u64))?; + Ok(RelaychainDataProvider::::current_block_number().encode()) + }, + } +} + +fn read_nfts_state( + key: NftsKeys, + env: &mut Environment, +) -> Result, DispatchError> +where + T: pallet_contracts::Config + pallet_nfts::Config, + E: Ext, +{ + match key { + NftsKeys::Collection(collection) => { + env.charge_weight(T::DbWeight::get().reads(1_u64))?; + Ok(pallet_nfts::Collection::::get(collection).encode()) + }, + NftsKeys::CollectionOwner(collection) => { + env.charge_weight(T::DbWeight::get().reads(1_u64))?; + Ok(pallet_nfts::Pallet::::collection_owner(collection).encode()) + }, + NftsKeys::Item(collection, item) => { + env.charge_weight(T::DbWeight::get().reads(1_u64))?; + Ok(pallet_nfts::Item::::get(collection, item).encode()) + }, + NftsKeys::Owner(collection, item) => { + env.charge_weight(T::DbWeight::get().reads(1_u64))?; + Ok(pallet_nfts::Pallet::::owner(collection, item).encode()) + }, + NftsKeys::Attribute(collection, item, key) => { + env.charge_weight(T::DbWeight::get().reads(1_u64))?; + Ok(pallet_nfts::Pallet::::attribute(&collection, &item, &key).encode()) + }, + // NftsKeys::CustomAttribute(account, collection, item, key) => { + // env.charge_weight(T::DbWeight::get().reads(1_u64))?; + // Ok(pallet_nfts::Pallet::::custom_attribute(&account, &collection, &item, &key) + // .encode()) + // }, + NftsKeys::SystemAttribute(collection, item, key) => { + env.charge_weight(T::DbWeight::get().reads(1_u64))?; + Ok(pallet_nfts::Pallet::::system_attribute(&collection, item.as_ref(), &key) + .encode()) + }, + NftsKeys::CollectionAttribute(collection, key) => { + env.charge_weight(T::DbWeight::get().reads(1_u64))?; + Ok(pallet_nfts::Pallet::::collection_attribute(&collection, &key).encode()) + }, + } +} + +fn read_trust_backed_assets_state( + key: AssetsKeys, + env: &mut Environment, +) -> Result, DispatchError> +where + T: pallet_contracts::Config + + pallet_assets::Config, + E: Ext, + T: frame_system::Config, +{ + match key { + AssetsKeys::Allowance(id, owner, spender) => { + env.charge_weight(T::DbWeight::get().reads(1_u64))?; + Ok(pallet_assets::Pallet::::allowance( + id, + &owner.0.into(), + &spender.0.into(), + ) + .encode()) + }, + AssetsKeys::AssetExists(id) => { + env.charge_weight(T::DbWeight::get().reads(1_u64))?; + Ok(pallet_assets::Pallet::::asset_exists(id).encode()) + }, + AssetsKeys::BalanceOf(id, owner) => { + env.charge_weight(T::DbWeight::get().reads(1_u64))?; + Ok(pallet_assets::Pallet::::balance(id, &owner.0.into()) + .encode()) + }, + AssetsKeys::TotalSupply(id) => { + env.charge_weight(T::DbWeight::get().reads(1_u64))?; + Ok(pallet_assets::Pallet::::total_supply(id).encode()) + }, + } +} + +fn send_xcm(env: Environment) -> Result<(), DispatchError> +where + T: pallet_contracts::Config + + frame_system::Config< + RuntimeOrigin = RuntimeOrigin, + AccountId = AccountId, + RuntimeCall = RuntimeCall, + >, + E: Ext, +{ + const LOG_PREFIX: &str = " send_xcm |"; + + let mut env = env.buf_in_buf_out(); + let len = env.in_len(); + + let _ = charge_overhead_weight::(&mut env, len, LOG_PREFIX)?; + + // read the input as CrossChainMessage + let xc_call: CrossChainMessage = env.read_as::()?; + + // Determine the call to dispatch + let (dest, message) = match xc_call { + CrossChainMessage::Relay(message) => { + let dest = Location::parent().into_versioned(); + let assets: Asset = (Here, 10 * UNIT).into(); + let beneficiary: Location = + AccountId32 { id: (env.ext().address().clone()).into(), network: None }.into(); + let message = Xcm::builder() + .withdraw_asset(assets.clone().into()) + .buy_execution(assets.clone(), Unlimited) + .transact( + SovereignAccount, + Weight::from_parts(250_000_000, 10_000), + message.encode().into(), + ) + .refund_surplus() + .deposit_asset(assets.into(), beneficiary) + .build(); + (dest, message) + }, + }; + + // TODO: revisit to replace with signed contract origin + let origin: RuntimeOrigin = RawOrigin::Root.into(); + + // Generate runtime call to dispatch + let call = RuntimeCall::PolkadotXcm(pallet_xcm::Call::send { + dest: Box::new(dest), + message: Box::new(VersionedXcm::V4(message)), + }); + + dispatch_call::(&mut env, call, origin, LOG_PREFIX) +} + +// use enumflags2::BitFlags; +// use pallet_nfts::{CollectionConfig, CollectionSetting, CollectionSettings, MintSettings}; +// use parachains_common::CollectionId; +// { +// // NFT helper functions +// fn collection_config_from_disabled_settings( +// settings: BitFlags, +// ) -> CollectionConfig { +// CollectionConfig { +// settings: CollectionSettings::from_disabled(settings), +// max_supply: None, +// mint_settings: MintSettings::default(), +// } +// } +// +// fn default_collection_config() -> CollectionConfig { +// collection_config_from_disabled_settings(CollectionSetting::DepositRequired.into()) +// } +// +// #[test] +// #[ignore] +// fn dispatch_balance_transfer_from_contract_works() { +// new_test_ext().execute_with(|| { +// let _ = env_logger::try_init(); +// +// let (wasm_binary, _) = load_wasm_module::( +// "../../pop-api/examples/balance-transfer/target/ink/balance_transfer.wasm", +// ) +// .unwrap(); +// +// let init_value = 100 * UNIT; +// +// let result = Contracts::bare_instantiate( +// ALICE, +// init_value, +// GAS_LIMIT, +// None, +// Code::Upload(wasm_binary), +// function_selector("new"), +// vec![], +// DEBUG_OUTPUT, +// pallet_contracts::CollectEvents::Skip, +// ) +// .result +// .unwrap(); +// +// assert!(!result.result.did_revert(), "deploying contract reverted {:?}", result); +// +// let addr = result.account_id; +// +// let function = function_selector("transfer_through_runtime"); +// let value_to_send: u128 = 10 * UNIT; +// let params = [function, BOB.encode(), value_to_send.encode()].concat(); +// +// let bob_balance_before = Balances::free_balance(&BOB); +// assert_eq!(bob_balance_before, INITIAL_AMOUNT); +// +// let result = Contracts::bare_call( +// ALICE, +// addr.clone(), +// 0, +// Weight::from_parts(100_000_000_000, 3 * 1024 * 1024), +// None, +// params, +// DEBUG_OUTPUT, +// pallet_contracts::CollectEvents::Skip, +// pallet_contracts::Determinism::Enforced, +// ); +// +// if DEBUG_OUTPUT == pallet_contracts::DebugInfo::UnsafeDebug { +// log::debug!( +// "Contract debug buffer - {:?}", +// String::from_utf8(result.debug_message.clone()) +// ); +// log::debug!("result: {:?}", result); +// } +// +// // check for revert +// assert!(!result.result.unwrap().did_revert(), "Contract reverted!"); +// +// let bob_balance_after = Balances::free_balance(&BOB); +// assert_eq!(bob_balance_before + value_to_send, bob_balance_after); +// }); +// } +// +// // Create a test for tesing create_nft_collection +// #[test] +// #[ignore] +// fn dispatch_nfts_create_nft_collection() { +// new_test_ext().execute_with(|| { +// let _ = env_logger::try_init(); +// +// let (wasm_binary, _) = load_wasm_module::( +// "../../pop-api/examples/nfts/target/ink/pop_api_nft_example.wasm", +// ) +// .unwrap(); +// +// let init_value = 100 * UNIT; +// +// let result = Contracts::bare_instantiate( +// ALICE, +// init_value, +// GAS_LIMIT, +// None, +// Code::Upload(wasm_binary), +// function_selector("new"), +// vec![], +// DEBUG_OUTPUT, +// pallet_contracts::CollectEvents::Skip, +// ) +// .result +// .unwrap(); +// +// assert!(!result.result.did_revert(), "deploying contract reverted {:?}", result); +// +// let addr = result.account_id; +// +// let function = function_selector("create_nft_collection"); +// +// let params = [function].concat(); +// +// let result = Contracts::bare_call( +// ALICE, +// addr.clone(), +// 0, +// Weight::from_parts(100_000_000_000, 3 * 1024 * 1024), +// None, +// params, +// DEBUG_OUTPUT, +// pallet_contracts::CollectEvents::Skip, +// pallet_contracts::Determinism::Enforced, +// ); +// +// if DEBUG_OUTPUT == pallet_contracts::DebugInfo::UnsafeDebug { +// log::debug!( +// "Contract debug buffer - {:?}", +// String::from_utf8(result.debug_message.clone()) +// ); +// log::debug!("result: {:?}", result); +// } +// +// // check that the nft collection was created +// assert_eq!(Nfts::collection_owner(0), Some(addr.clone().into())); +// +// // test reading the collection +// let function = function_selector("read_collection"); +// +// let params = [function, 0.encode()].concat(); +// +// let result = Contracts::bare_call( +// ALICE, +// addr.clone(), +// 0, +// Weight::from_parts(100_000_000_000, 3 * 1024 * 1024), +// None, +// params, +// DEBUG_OUTPUT, +// pallet_contracts::CollectEvents::Skip, +// pallet_contracts::Determinism::Enforced, +// ); +// +// if DEBUG_OUTPUT == pallet_contracts::DebugInfo::UnsafeDebug { +// log::debug!( +// "Contract debug buffer - {:?}", +// String::from_utf8(result.debug_message.clone()) +// ); +// log::debug!("result: {:?}", result); +// } +// +// // assert that the collection was read successfully +// assert_eq!(result.result.clone().unwrap().data, vec![1, 1]); +// }); +// } +// +// #[test] +// #[ignore] +// fn dispatch_nfts_mint_from_contract_works() { +// new_test_ext().execute_with(|| { +// let _ = env_logger::try_init(); +// +// let (wasm_binary, _) = +// load_wasm_module::("../../pop-api/examples/nfts/target/ink/nfts.wasm") +// .unwrap(); +// +// let init_value = 100; +// +// let result = Contracts::bare_instantiate( +// ALICE, +// init_value, +// GAS_LIMIT, +// None, +// Code::Upload(wasm_binary), +// function_selector("new"), +// vec![], +// DEBUG_OUTPUT, +// pallet_contracts::CollectEvents::Skip, +// ) +// .result +// .unwrap(); +// +// assert!(!result.result.did_revert(), "deploying contract reverted {:?}", result); +// +// let addr = result.account_id; +// +// let collection_id: u32 = 0; +// let item_id: u32 = 1; +// +// // create nft collection with contract as owner +// assert_eq!( +// Nfts::force_create( +// RuntimeOrigin::root(), +// addr.clone().into(), +// default_collection_config() +// ), +// Ok(()) +// ); +// +// assert_eq!(Nfts::collection_owner(collection_id), Some(addr.clone().into())); +// // assert that the item does not exist yet +// assert_eq!(Nfts::owner(collection_id, item_id), None); +// +// let function = function_selector("mint_through_runtime"); +// +// let params = +// [function, collection_id.encode(), item_id.encode(), BOB.encode()].concat(); +// +// let result = Contracts::bare_call( +// ALICE, +// addr.clone(), +// 0, +// Weight::from_parts(100_000_000_000, 3 * 1024 * 1024), +// None, +// params, +// DEBUG_OUTPUT, +// pallet_contracts::CollectEvents::Skip, +// pallet_contracts::Determinism::Enforced, +// ); +// +// if DEBUG_OUTPUT == pallet_contracts::DebugInfo::UnsafeDebug { +// log::debug!( +// "Contract debug buffer - {:?}", +// String::from_utf8(result.debug_message.clone()) +// ); +// log::debug!("result: {:?}", result); +// } +// +// // check for revert +// assert!(!result.result.unwrap().did_revert(), "Contract reverted!"); +// +// assert_eq!(Nfts::owner(collection_id, item_id), Some(BOB.into())); +// }); +// } +// +// #[test] +// #[ignore] +// fn nfts_mint_surfaces_error() { +// new_test_ext().execute_with(|| { +// let _ = env_logger::try_init(); +// +// let (wasm_binary, _) = +// load_wasm_module::("../../pop-api/examples/nfts/target/ink/nfts.wasm") +// .unwrap(); +// +// let init_value = 100; +// +// let result = Contracts::bare_instantiate( +// ALICE, +// init_value, +// GAS_LIMIT, +// None, +// Code::Upload(wasm_binary), +// function_selector("new"), +// vec![], +// DEBUG_OUTPUT, +// pallet_contracts::CollectEvents::Skip, +// ) +// .result +// .unwrap(); +// +// assert!(!result.result.did_revert(), "deploying contract reverted {:?}", result); +// +// let addr = result.account_id; +// +// let collection_id: u32 = 0; +// let item_id: u32 = 1; +// +// let function = function_selector("mint_through_runtime"); +// +// let params = +// [function, collection_id.encode(), item_id.encode(), BOB.encode()].concat(); +// +// let result = Contracts::bare_call( +// ALICE, +// addr.clone(), +// 0, +// Weight::from_parts(100_000_000_000, 3 * 1024 * 1024), +// None, +// params, +// DEBUG_OUTPUT, +// pallet_contracts::CollectEvents::Skip, +// pallet_contracts::Determinism::Enforced, +// ); +// +// if DEBUG_OUTPUT == pallet_contracts::DebugInfo::UnsafeDebug { +// log::debug!( +// "Contract debug buffer - {:?}", +// String::from_utf8(result.debug_message.clone()) +// ); +// log::debug!("result: {:?}", result); +// } +// +// // check for revert with expected error +// let result = result.result.unwrap(); +// assert!(result.did_revert()); +// }); +// } +// +// #[test] +// #[ignore] +// fn reading_last_relay_chain_block_number_works() { +// new_test_ext().execute_with(|| { +// let _ = env_logger::try_init(); +// +// let (wasm_binary, _) = load_wasm_module::( +// "../../pop-api/examples/read-runtime-state/target/ink/read_relay_blocknumber.wasm", +// ) +// .unwrap(); +// +// let init_value = 100; +// +// let contract = Contracts::bare_instantiate( +// ALICE, +// init_value, +// GAS_LIMIT, +// None, +// Code::Upload(wasm_binary), +// function_selector("new"), +// vec![], +// DEBUG_OUTPUT, +// pallet_contracts::CollectEvents::Skip, +// ) +// .result +// .unwrap(); +// +// assert!(!contract.result.did_revert(), "deploying contract reverted {:?}", contract); +// +// let addr = contract.account_id; +// +// let function = function_selector("read_relay_block_number"); +// let params = [function].concat(); +// +// let result = Contracts::bare_call( +// ALICE, +// addr.clone(), +// 0, +// Weight::from_parts(100_000_000_000, 3 * 1024 * 1024), +// None, +// params, +// DEBUG_OUTPUT, +// pallet_contracts::CollectEvents::UnsafeCollect, +// pallet_contracts::Determinism::Relaxed, +// ); +// +// if DEBUG_OUTPUT == pallet_contracts::DebugInfo::UnsafeDebug { +// log::debug!( +// "Contract debug buffer - {:?}", +// String::from_utf8(result.debug_message.clone()) +// ); +// log::debug!("result: {:?}", result); +// } +// +// // check for revert +// assert!(!result.result.unwrap().did_revert(), "Contract reverted!"); +// }); +// } +// +// #[test] +// #[ignore] +// fn place_spot_order_from_contract_works() { +// new_test_ext().execute_with(|| { +// let _ = env_logger::try_init(); +// +// let (wasm_binary, _) = load_wasm_module::( +// "../../pop-api/examples/place-spot-order/target/ink/spot_order.wasm", +// ) +// .unwrap(); +// +// let init_value = 100 * UNIT; +// +// let result = Contracts::bare_instantiate( +// ALICE, +// init_value, +// GAS_LIMIT, +// None, +// Code::Upload(wasm_binary), +// function_selector("new"), +// vec![], +// DEBUG_OUTPUT, +// pallet_contracts::CollectEvents::Skip, +// ) +// .result +// .unwrap(); +// +// assert!(!result.result.did_revert(), "deploying contract reverted {:?}", result); +// +// let addr = result.account_id; +// +// let function = function_selector("place_spot_order"); +// +// let max_amount = 1 * UNIT; +// let para_id = 2000; +// +// let params = [function, max_amount.encode(), para_id.encode()].concat(); +// +// let result = Contracts::bare_call( +// ALICE, +// addr.clone(), +// 0, +// Weight::from_parts(100_000_000_000, 3 * 1024 * 1024), +// None, +// params, +// DEBUG_OUTPUT, +// pallet_contracts::CollectEvents::Skip, +// pallet_contracts::Determinism::Enforced, +// ); +// +// if DEBUG_OUTPUT == pallet_contracts::DebugInfo::UnsafeDebug { +// log::debug!( +// "Contract debug buffer - {:?}", +// String::from_utf8(result.debug_message.clone()) +// ); +// log::debug!("result: {:?}", result); +// } +// +// // check for revert +// assert!(!result.result.unwrap().did_revert(), "Contract reverted!"); +// }); +// } +// +// #[test] +// #[ignore] +// fn allow_call_filter_blocks_call() { +// new_test_ext().execute_with(|| { +// let _ = env_logger::try_init(); +// +// let (wasm_binary, _) = load_wasm_module::( +// "../../tests/contracts/filtered-call/target/ink/pop_api_filtered_call.wasm", +// ) +// .unwrap(); +// +// let init_value = 100 * UNIT; +// +// let result = Contracts::bare_instantiate( +// ALICE, +// init_value, +// GAS_LIMIT, +// None, +// Code::Upload(wasm_binary), +// function_selector("new"), +// vec![], +// DEBUG_OUTPUT, +// pallet_contracts::CollectEvents::Skip, +// ) +// .result +// .unwrap(); +// +// assert!(!result.result.did_revert(), "deploying contract reverted {:?}", result); +// +// let addr = result.account_id; +// +// let function = function_selector("get_filtered"); +// let params = [function].concat(); +// +// let result = Contracts::bare_call( +// ALICE, +// addr.clone(), +// 0, +// Weight::from_parts(100_000_000_000, 3 * 1024 * 1024), +// None, +// params, +// DEBUG_OUTPUT, +// pallet_contracts::CollectEvents::Skip, +// pallet_contracts::Determinism::Enforced, +// ); +// +// if DEBUG_OUTPUT == pallet_contracts::DebugInfo::UnsafeDebug { +// log::debug!( +// "Contract debug buffer - {:?}", +// String::from_utf8(result.debug_message.clone()) +// ); +// log::debug!("filtered result: {:?}", result); +// } +// +// // check for revert +// assert!(!result.result.unwrap().did_revert(), "Contract reverted!"); +// }); +// } +// } diff --git a/runtime/devnet/src/extensions/tests/local_fungibles.rs b/runtime/devnet/src/extensions/tests/local_fungibles.rs new file mode 100644 index 00000000..2d752361 --- /dev/null +++ b/runtime/devnet/src/extensions/tests/local_fungibles.rs @@ -0,0 +1,302 @@ +#![cfg(test)] + +use super::*; +use pallet_contracts::debug::ExecResult; + +#[derive(Decode, Encode, Debug, Eq, PartialEq)] +enum FungiblesError { + // AssetsError(Error), + // /// The origin of the call doesn't have the right permission. + // BadOrigin, + // /// Custom error type for cases in which an implementation adds its own restrictions. + // Custom(String), + /// Not enough balance to fulfill a request is available. + InsufficientBalance, + /// Not enough allowance to fulfill a request is available. + InsufficientAllowance, + /// The asset status is not the expected status. + IncorrectStatus, + /// The asset ID is already taken. + InUse, + /// Minimum balance should be non-zero. + MinBalanceZero, + /// The signing account has no permission to do the operation. + NoPermission, + // /// Safe transfer check fails (e.g. if the receiving contract does not accept tokens). + // SafeTransferCheckFailed(String), + /// The given asset ID is unknown. + Unknown, + /// Recipient's address is zero. + ZeroRecipientAddress, + /// Sender's address is zero. + ZeroSenderAddress, + UndefinedError, +} + +const ASSET_ID: u32 = 1; + +fn allowance( + addr: AccountId32, + asset_id: u32, + owner: AccountId32, + spender: AccountId32, +) -> ExecReturnValue { + let function = function_selector("allowance"); + let params = [function, asset_id.encode(), owner.encode(), spender.encode()].concat(); + do_bare_call(addr, params, 0).expect("should work") +} + +// Call balance_of contract message. +fn balance_of(addr: AccountId32, asset_id: u32, owner: AccountId32) -> ExecReturnValue { + let function = function_selector("balance_of"); + let params = [function, asset_id.encode(), owner.encode()].concat(); + do_bare_call(addr, params, 0).expect("should work") +} + +// Call total_supply contract message. +fn total_supply(addr: AccountId32, asset_id: u32) -> ExecReturnValue { + let function = function_selector("total_supply"); + let params = [function, asset_id.encode()].concat(); + do_bare_call(addr, params, 0).expect("should work") +} + +fn asset_exists(addr: AccountId32, asset_id: u32) -> ExecReturnValue { + let function = function_selector("asset_exists"); + let params = [function, asset_id.encode()].concat(); + do_bare_call(addr, params, 0).expect("should work") +} + +fn create( + addr: AccountId32, + asset_id: u32, + admin: AccountId32, + min_balance: u128, +) -> ExecReturnValue { + let function = function_selector("create"); + let params = [function, asset_id.encode(), admin.encode(), min_balance.encode()].concat(); + do_bare_call(addr, params, 0).expect("should work") +} + +fn set_metadata( + addr: AccountId32, + asset_id: u32, + name: Vec, + symbol: Vec, + decimals: u8, +) -> ExecReturnValue { + let function = function_selector("set_metadata"); + let params = + [function, asset_id.encode(), name.encode(), symbol.encode(), decimals.encode()].concat(); + do_bare_call(addr, params, 0).expect("should work") +} + +fn transfer_from( + addr: AccountId32, + asset_id: u32, + _from: Option, + to: Option, + value: u128, + _data: &[u8], +) -> ExecReturnValue { + // let function = function_selector("transfer_from"); + // let params = + // [function, asset_id.encode(), from.encode(), to.encode(), value.encode(), data.encode()] + // .concat(); + // do_bare_call(addr, params, 0) + let function = function_selector("mint"); + let params = [function, asset_id.encode(), to.unwrap().encode(), value.encode()].concat(); + do_bare_call(addr, params, 0).expect("should work") +} + +// Create an asset and mint to owner. +fn create_asset(asset_id: u32, owner: AccountId32) { + assert_eq!( + Assets::create(RuntimeOrigin::signed(owner.clone()), asset_id.into(), owner.into(), 1), + Ok(()) + ); +} + +// Create an asset and mint to owner. +fn create_asset_and_mint_to(asset_id: u32, owner: AccountId32, to: AccountId32, value: u128) { + create_asset(asset_id, owner.clone()); + assert_eq!( + Assets::mint(RuntimeOrigin::signed(owner.into()), asset_id.into(), to.into(), value,), + Ok(()) + ); +} + +// Create an asset, mints to, and approves spender. +fn create_asset_mint_and_approve( + asset_id: u32, + owner: AccountId32, + to: AccountId32, + mint: u128, + spender: AccountId32, + approve: u128, +) { + create_asset_and_mint_to(asset_id, owner.clone(), to.clone(), mint); + assert_eq!( + Assets::approve_transfer( + RuntimeOrigin::signed(to.into()), + asset_id.into(), + spender.into(), + approve, + ), + Ok(()) + ); +} + +#[test] +#[ignore] +fn total_supply_works() { + new_test_ext().execute_with(|| { + let _ = env_logger::try_init(); + let addr = + instantiate("../../pop-api/examples/fungibles/target/ink/fungibles.wasm", INIT_VALUE); + + // No tokens in circulation. + assert_eq!( + Assets::total_supply(ASSET_ID).encode(), + total_supply(addr.clone(), ASSET_ID).data[2..] + ); + + // Tokens in circulation. + create_asset_and_mint_to(ASSET_ID, addr.clone(), BOB, 100); + assert_eq!(Assets::total_supply(ASSET_ID).encode(), total_supply(addr, ASSET_ID).data[2..]); + }); +} + +#[test] +#[ignore] +fn balance_of_works() { + new_test_ext().execute_with(|| { + let _ = env_logger::try_init(); + let addr = + instantiate("../../pop-api/examples/fungibles/target/ink/fungibles.wasm", INIT_VALUE); + + // No tokens in circulation. + assert_eq!( + Assets::balance(ASSET_ID, BOB).encode(), + balance_of(addr.clone(), ASSET_ID, BOB).data[2..] + ); + + // Tokens in circulation. + create_asset_and_mint_to(ASSET_ID, addr.clone(), BOB, 100); + assert_eq!( + Assets::balance(ASSET_ID, BOB).encode(), + balance_of(addr, ASSET_ID, BOB).data[2..] + ); + }); +} + +#[test] +#[ignore] +fn allowance_works() { + new_test_ext().execute_with(|| { + let _ = env_logger::try_init(); + let addr = + instantiate("../../pop-api/examples/fungibles/target/ink/fungibles.wasm", INIT_VALUE); + + // No tokens in circulation. + assert_eq!( + Assets::allowance(ASSET_ID, &BOB, &ALICE).encode(), + allowance(addr.clone(), ASSET_ID, BOB, ALICE).data[2..] + ); + + // Tokens in circulation. + create_asset_mint_and_approve(ASSET_ID, addr.clone(), BOB, 100, ALICE, 50); + assert_eq!( + Assets::allowance(ASSET_ID, &BOB, &ALICE).encode(), + allowance(addr, ASSET_ID, BOB, ALICE).data[2..] + ); + }); +} + +#[test] +#[ignore] +fn asset_exists_works() { + new_test_ext().execute_with(|| { + let _ = env_logger::try_init(); + let addr = + instantiate("../../pop-api/examples/fungibles/target/ink/fungibles.wasm", INIT_VALUE); + + // No tokens in circulation. + assert_eq!( + Assets::asset_exists(ASSET_ID).encode(), + asset_exists(addr.clone(), ASSET_ID).data[2..] + ); + + // Tokens in circulation. + create_asset(ASSET_ID, addr.clone()); + assert_eq!(Assets::asset_exists(ASSET_ID).encode(), asset_exists(addr, ASSET_ID).data[2..]); + }); +} + +fn decode_error(result: ExecReturnValue) -> FungiblesError { + FungiblesError::decode(&mut &result.data[2..]).unwrap() +} + +#[test] +#[ignore] +fn create_works() { + new_test_ext().execute_with(|| { + let _ = env_logger::try_init(); + let addr = instantiate("../../pop-api/examples/fungibles/target/ink/fungibles.wasm", 0); + let new_asset = 2; + + assert_eq!( + decode_error(create(addr.clone(), new_asset, BOB, 1)), + FungiblesError::UndefinedError + ); + // Todo: errors Badorigin, Lookup, reserve(), Callback + // create_asset(ASSET_ID, ALICE); + // // Error `InUse`. + // assert_eq!(decode_error(create(addr.clone(), ASSET_ID, BOB, 1)), FungiblesError::InUse); + // // Error `MinBalanceZero`. + // assert_eq!( + // decode_error(create(addr.clone(), new_asset, BOB, 0)), + // FungiblesError::MinBalanceZero + // ); + // assert!( + // !create(addr.clone(), new_asset, BOB, 1).did_revert(), + // "Contract should have been reverted!" + // ); + }); +} + +#[test] +#[ignore] +fn set_metadata_works() { + new_test_ext().execute_with(|| { + let _ = env_logger::try_init(); + let addr = + instantiate("../../pop-api/examples/fungibles/target/ink/fungibles.wasm", INIT_VALUE); + + create_asset(ASSET_ID, addr.clone()); + + let result = set_metadata(addr.clone(), ASSET_ID, vec![12], vec![12], 12); + assert!(!result.did_revert(), "Contract should have been reverted!"); + }); +} + +#[test] +#[ignore] +fn transfer_from_aka_mint_works() { + new_test_ext().execute_with(|| { + let _ = env_logger::try_init(); + let addr = + instantiate("../../pop-api/examples/fungibles/target/ink/fungibles.wasm", INIT_VALUE); + + let amount: u128 = 100 * UNIT; + // Create asset with contract as owner. + create_asset(ASSET_ID, addr.clone()); + // Check Bob's asset balance before minting through contract. + let bob_balance_before = Assets::balance(ASSET_ID, &BOB); + + let result = transfer_from(addr.clone(), ASSET_ID, None, Some(BOB), 100 * UNIT, &[0u8]); + assert!(!result.did_revert(), "Contract reverted!"); + + let bob_balance_after = Assets::balance(ASSET_ID, &BOB); + assert_eq!(bob_balance_after, bob_balance_before + amount); + }); +} diff --git a/runtime/devnet/src/extensions/tests/mod.rs b/runtime/devnet/src/extensions/tests/mod.rs new file mode 100644 index 00000000..30d1a924 --- /dev/null +++ b/runtime/devnet/src/extensions/tests/mod.rs @@ -0,0 +1,86 @@ +#![cfg(test)] +use super::*; +use crate::{Assets, Balances, Contracts, Runtime, System}; +use pallet_contracts::{Code, CollectEvents, Determinism, ExecReturnValue}; +use sp_runtime::{traits::Hash, AccountId32, BuildStorage}; + +mod local_fungibles; + +const DEBUG_OUTPUT: pallet_contracts::DebugInfo = pallet_contracts::DebugInfo::UnsafeDebug; + +const ALICE: AccountId32 = AccountId32::new([1_u8; 32]); +const BOB: AccountId32 = AccountId32::new([2_u8; 32]); +const INIT_VALUE: u128 = 100_000_000 * UNIT; +const GAS_LIMIT: Weight = Weight::from_parts(100_000_000_000, 3 * 1024 * 1024); + +fn new_test_ext() -> sp_io::TestExternalities { + let mut t = frame_system::GenesisConfig::::default() + .build_storage() + .expect("Frame system builds valid default genesis config"); + + pallet_balances::GenesisConfig:: { + balances: vec![(ALICE, INIT_VALUE), (BOB, INIT_VALUE)], + } + .assimilate_storage(&mut t) + .expect("Pallet balances storage can be assimilated"); + + let mut ext = sp_io::TestExternalities::new(t); + ext.execute_with(|| System::set_block_number(1)); + ext +} + +fn load_wasm_module(path: &str) -> std::io::Result<(Vec, ::Output)> +where + T: frame_system::Config, +{ + let wasm_binary = std::fs::read(path)?; + let code_hash = T::Hashing::hash(&wasm_binary); + Ok((wasm_binary, code_hash)) +} + +fn function_selector(name: &str) -> Vec { + let hash = sp_io::hashing::blake2_256(name.as_bytes()); + [hash[0..4].to_vec()].concat() +} + +fn do_bare_call( + addr: AccountId32, + input: Vec, + value: u128, +) -> Result { + let result = Contracts::bare_call( + ALICE, + addr.into(), + value.into(), + GAS_LIMIT, + None, + input, + DEBUG_OUTPUT, + CollectEvents::Skip, + Determinism::Enforced, + ); + log::debug!("Contract debug buffer - {:?}", String::from_utf8(result.debug_message.clone())); + log::debug!("result: {:?}", result); + result.result +} + +// Deploy, instantiate and return contract address. +fn instantiate(contract: &str, init_value: u128) -> AccountId32 { + let (wasm_binary, _) = + load_wasm_module::(contract).expect("could not read .wasm file"); + let result = Contracts::bare_instantiate( + ALICE, + init_value, + GAS_LIMIT, + None, + Code::Upload(wasm_binary), + function_selector("new"), + vec![], + DEBUG_OUTPUT, + CollectEvents::Skip, + ) + .result + .unwrap(); + assert!(!result.result.did_revert(), "deploying contract reverted {:?}", result); + result.account_id +} diff --git a/runtime/devnet/src/lib.rs b/runtime/devnet/src/lib.rs index 52a0938f..a82be804 100644 --- a/runtime/devnet/src/lib.rs +++ b/runtime/devnet/src/lib.rs @@ -254,40 +254,40 @@ impl Contains for FilteredCalls { pub struct AllowedPopApiCalls; impl Contains for crate::AllowedPopApiCalls { fn contains(c: &RuntimeCall) -> bool { - use assets_config::TrustBackedAssetsCall; + use config::assets::AssetsCall; use pallet_nfts::Call as NftsCall; matches!( c, RuntimeCall::Balances(BalancesCall::transfer_keep_alive { .. }) - | RuntimeCall::TrustBackedAssets( - TrustBackedAssetsCall::create { .. } - | TrustBackedAssetsCall::start_destroy { .. } - | TrustBackedAssetsCall::destroy_accounts { .. } - | TrustBackedAssetsCall::destroy_approvals { .. } - | TrustBackedAssetsCall::finish_destroy { .. } - | TrustBackedAssetsCall::mint { .. } - | TrustBackedAssetsCall::burn { .. } - | TrustBackedAssetsCall::transfer { .. } - | TrustBackedAssetsCall::transfer_keep_alive { .. } - | TrustBackedAssetsCall::force_transfer { .. } - | TrustBackedAssetsCall::freeze { .. } - | TrustBackedAssetsCall::thaw { .. } - | TrustBackedAssetsCall::freeze_asset { .. } - | TrustBackedAssetsCall::thaw_asset { .. } - | TrustBackedAssetsCall::transfer_ownership { .. } - | TrustBackedAssetsCall::set_team { .. } - | TrustBackedAssetsCall::set_metadata { .. } - | TrustBackedAssetsCall::clear_metadata { .. } - | TrustBackedAssetsCall::approve_transfer { .. } - | TrustBackedAssetsCall::cancel_approval { .. } - | TrustBackedAssetsCall::force_cancel_approval { .. } - | TrustBackedAssetsCall::transfer_approved { .. } - | TrustBackedAssetsCall::touch { .. } - | TrustBackedAssetsCall::refund { .. } - | TrustBackedAssetsCall::set_min_balance { .. } - | TrustBackedAssetsCall::touch_other { .. } - | TrustBackedAssetsCall::refund_other { .. } - | TrustBackedAssetsCall::block { .. } + | RuntimeCall::Assets( + AssetsCall::create { .. } + | AssetsCall::start_destroy { .. } + | AssetsCall::destroy_accounts { .. } + | AssetsCall::destroy_approvals { .. } + | AssetsCall::finish_destroy { .. } + | AssetsCall::mint { .. } + | AssetsCall::burn { .. } + | AssetsCall::transfer { .. } + | AssetsCall::transfer_keep_alive { .. } + | AssetsCall::force_transfer { .. } + | AssetsCall::freeze { .. } + | AssetsCall::thaw { .. } + | AssetsCall::freeze_asset { .. } + | AssetsCall::thaw_asset { .. } + | AssetsCall::transfer_ownership { .. } + | AssetsCall::set_team { .. } + | AssetsCall::set_metadata { .. } + | AssetsCall::clear_metadata { .. } + | AssetsCall::approve_transfer { .. } + | AssetsCall::cancel_approval { .. } + | AssetsCall::force_cancel_approval { .. } + | AssetsCall::transfer_approved { .. } + | AssetsCall::touch { .. } + | AssetsCall::refund { .. } + | AssetsCall::set_min_balance { .. } + | AssetsCall::touch_other { .. } + | AssetsCall::refund_other { .. } + | AssetsCall::block { .. } ) | RuntimeCall::Nfts( NftsCall::create { .. } | NftsCall::destroy { .. } @@ -662,7 +662,7 @@ construct_runtime!( // Assets Nfts: pallet_nfts = 50, NftFractionalization: pallet_nft_fractionalization = 51, - TrustBackedAssets: pallet_assets:: = 52, + Assets: pallet_assets:: = 52, } ); diff --git a/runtime/testnet/Cargo.toml b/runtime/testnet/Cargo.toml index d68bfd15..43b1e310 100644 --- a/runtime/testnet/Cargo.toml +++ b/runtime/testnet/Cargo.toml @@ -22,7 +22,7 @@ scale-info.workspace = true smallvec.workspace = true # Local -pop-primitives.workspace = true +pop-primitives = { workspace = true, features = ["testnet"] } pop-runtime-common = { workspace = true, default-features = false } # Substrate diff --git a/runtime/testnet/src/config/assets.rs b/runtime/testnet/src/config/assets.rs index f51f8875..2c8ea952 100644 --- a/runtime/testnet/src/config/assets.rs +++ b/runtime/testnet/src/config/assets.rs @@ -1,6 +1,6 @@ use crate::{ - deposit, AccountId, Balance, Balances, BlockNumber, Nfts, Runtime, RuntimeEvent, - RuntimeHoldReason, TrustBackedAssets, DAYS, EXISTENTIAL_DEPOSIT, UNIT, + deposit, AccountId, Assets, Balance, Balances, BlockNumber, Nfts, Runtime, RuntimeEvent, + RuntimeHoldReason, DAYS, EXISTENTIAL_DEPOSIT, UNIT, }; use frame_support::{ parameter_types, @@ -86,7 +86,7 @@ impl pallet_nft_fractionalization::Config for Runtime { type NftId = ::ItemId; type AssetBalance = >::Balance; type AssetId = >::AssetId; - type Assets = TrustBackedAssets; + type Assets = Assets; type Nfts = Nfts; type PalletId = NftFractionalizationPalletId; type WeightInfo = pallet_nft_fractionalization::weights::SubstrateWeight; @@ -96,7 +96,7 @@ impl pallet_nft_fractionalization::Config for Runtime { } pub type TrustBackedAssetsInstance = pallet_assets::Instance1; -pub(crate) type TrustBackedAssetsCall = pallet_assets::Call; +pub(crate) type AssetsCall = pallet_assets::Call; impl pallet_assets::Config for Runtime { type RuntimeEvent = RuntimeEvent; type Balance = Balance; diff --git a/runtime/testnet/src/config/proxy.rs b/runtime/testnet/src/config/proxy.rs index a4fd479a..07d5f0f8 100644 --- a/runtime/testnet/src/config/proxy.rs +++ b/runtime/testnet/src/config/proxy.rs @@ -1,4 +1,4 @@ -use super::assets::TrustBackedAssetsCall; +use super::assets::AssetsCall; use crate::{Balances, Runtime, RuntimeCall, RuntimeEvent}; use frame_support::traits::InstanceFilter; use pop_runtime_common::proxy::{ @@ -34,16 +34,16 @@ impl InstanceFilter for ProxyType { }, ProxyType::AssetOwner => matches!( c, - RuntimeCall::Assets(TrustBackedAssetsCall::create { .. }) - | RuntimeCall::Assets(TrustBackedAssetsCall::start_destroy { .. }) - | RuntimeCall::Assets(TrustBackedAssetsCall::destroy_accounts { .. }) - | RuntimeCall::Assets(TrustBackedAssetsCall::destroy_approvals { .. }) - | RuntimeCall::Assets(TrustBackedAssetsCall::finish_destroy { .. }) - | RuntimeCall::Assets(TrustBackedAssetsCall::transfer_ownership { .. }) - | RuntimeCall::Assets(TrustBackedAssetsCall::set_team { .. }) - | RuntimeCall::Assets(TrustBackedAssetsCall::set_metadata { .. }) - | RuntimeCall::Assets(TrustBackedAssetsCall::clear_metadata { .. }) - | RuntimeCall::Assets(TrustBackedAssetsCall::set_min_balance { .. }) + RuntimeCall::Assets(AssetsCall::create { .. }) + | RuntimeCall::Assets(AssetsCall::start_destroy { .. }) + | RuntimeCall::Assets(AssetsCall::destroy_accounts { .. }) + | RuntimeCall::Assets(AssetsCall::destroy_approvals { .. }) + | RuntimeCall::Assets(AssetsCall::finish_destroy { .. }) + | RuntimeCall::Assets(AssetsCall::transfer_ownership { .. }) + | RuntimeCall::Assets(AssetsCall::set_team { .. }) + | RuntimeCall::Assets(AssetsCall::set_metadata { .. }) + | RuntimeCall::Assets(AssetsCall::clear_metadata { .. }) + | RuntimeCall::Assets(AssetsCall::set_min_balance { .. }) | RuntimeCall::Nfts(pallet_nfts::Call::create { .. }) | RuntimeCall::Nfts(pallet_nfts::Call::destroy { .. }) | RuntimeCall::Nfts(pallet_nfts::Call::redeposit { .. }) @@ -56,15 +56,15 @@ impl InstanceFilter for ProxyType { ), ProxyType::AssetManager => matches!( c, - RuntimeCall::Assets(TrustBackedAssetsCall::mint { .. }) - | RuntimeCall::Assets(TrustBackedAssetsCall::burn { .. }) - | RuntimeCall::Assets(TrustBackedAssetsCall::freeze { .. }) - | RuntimeCall::Assets(TrustBackedAssetsCall::block { .. }) - | RuntimeCall::Assets(TrustBackedAssetsCall::thaw { .. }) - | RuntimeCall::Assets(TrustBackedAssetsCall::freeze_asset { .. }) - | RuntimeCall::Assets(TrustBackedAssetsCall::thaw_asset { .. }) - | RuntimeCall::Assets(TrustBackedAssetsCall::touch_other { .. }) - | RuntimeCall::Assets(TrustBackedAssetsCall::refund_other { .. }) + RuntimeCall::Assets(AssetsCall::mint { .. }) + | RuntimeCall::Assets(AssetsCall::burn { .. }) + | RuntimeCall::Assets(AssetsCall::freeze { .. }) + | RuntimeCall::Assets(AssetsCall::block { .. }) + | RuntimeCall::Assets(AssetsCall::thaw { .. }) + | RuntimeCall::Assets(AssetsCall::freeze_asset { .. }) + | RuntimeCall::Assets(AssetsCall::thaw_asset { .. }) + | RuntimeCall::Assets(AssetsCall::touch_other { .. }) + | RuntimeCall::Assets(AssetsCall::refund_other { .. }) | RuntimeCall::Nfts(pallet_nfts::Call::force_mint { .. }) | RuntimeCall::Nfts(pallet_nfts::Call::update_mint_settings { .. }) | RuntimeCall::Nfts(pallet_nfts::Call::mint_pre_signed { .. }) diff --git a/runtime/testnet/src/extensions.rs b/runtime/testnet/src/extensions.rs index 0d552090..6bbfaa36 100644 --- a/runtime/testnet/src/extensions.rs +++ b/runtime/testnet/src/extensions.rs @@ -3,25 +3,23 @@ use frame_support::traits::{Contains, OriginTrait}; use frame_support::{ dispatch::{GetDispatchInfo, RawOrigin}, pallet_prelude::*, - traits::{fungibles::Inspect, nonfungibles_v2::Inspect as NonFungiblesInspect}, + traits::nonfungibles_v2::Inspect as NonFungiblesInspect, }; use pallet_contracts::chain_extension::{ BufInBufOutState, ChainExtension, ChargedAmount, Environment, Ext, InitState, RetVal, }; use pop_primitives::{ - storage_keys::{NftsKeys, ParachainSystemKeys, RuntimeStateKeys, TrustBackedAssetsKeys}, - AssetId, CollectionId, ItemId, + storage_keys::{NftsKeys, ParachainSystemKeys, RuntimeStateKeys}, + CollectionId, ItemId, }; use sp_core::crypto::UncheckedFrom; use sp_runtime::{ traits::{BlockNumberProvider, Dispatchable}, DispatchError, }; +use sp_std::vec::Vec; -use crate::{ - assets_config::TrustBackedAssetsInstance, AccountId, AllowedPopApiCalls, RuntimeCall, - RuntimeOrigin, -}; +use crate::{AccountId, AllowedPopApiCalls, RuntimeCall, RuntimeOrigin}; const LOG_TARGET: &str = "pop-api::extension"; @@ -34,7 +32,6 @@ impl ChainExtension for PopApiExtension where T: pallet_contracts::Config + pallet_xcm::Config - + pallet_assets::Config + pallet_nfts::Config + cumulus_pallet_parachain_system::Config + frame_system::Config< @@ -184,7 +181,6 @@ where fn read_state(env: Environment) -> Result<(), DispatchError> where T: pallet_contracts::Config - + pallet_assets::Config + pallet_nfts::Config + cumulus_pallet_parachain_system::Config + frame_system::Config, @@ -210,9 +206,6 @@ where RuntimeStateKeys::ParachainSystem(key) => { read_parachain_system_state::(key, &mut env) }, - RuntimeStateKeys::TrustBackedAssets(key) => { - read_trust_backed_assets_state::(key, &mut env) - }, }? .encode(); @@ -288,23 +281,6 @@ where } } -fn read_trust_backed_assets_state( - key: TrustBackedAssetsKeys, - env: &mut Environment, -) -> Result, DispatchError> -where - T: pallet_contracts::Config - + pallet_assets::Config, - E: Ext, -{ - match key { - TrustBackedAssetsKeys::AssetExists(id) => { - env.charge_weight(T::DbWeight::get().reads(1_u64))?; - Ok(pallet_assets::Pallet::::asset_exists(id).encode()) - }, - } -} - #[cfg(test)] mod tests { pub use super::*; @@ -701,110 +677,6 @@ mod tests { }); } - #[test] - #[ignore] - fn dispatch_trust_backed_assets_mint_from_contract_works() { - new_test_ext().execute_with(|| { - let _ = env_logger::try_init(); - - let (wasm_binary, _) = load_wasm_module::( - "../../pop-api/examples/trust_backed_assets/target/ink/pop_api_trust_backed_assets_example.wasm", - ) - .unwrap(); - - let init_value = 100; - - let result = Contracts::bare_instantiate( - ALICE, - init_value, - GAS_LIMIT, - None, - Code::Upload(wasm_binary), - function_selector("new"), - vec![], - DEBUG_OUTPUT, - pallet_contracts::CollectEvents::Skip, - ) - .result - .unwrap(); - - assert!(!result.result.did_revert(), "deploying contract reverted {:?}", result); - let addr = result.account_id; - - let asset_id: u32 = 1; - let min_balance = 1; - let amount: u128 = 100 * UNIT; - let function = function_selector("mint_asset_through_runtime"); - let params = [function, asset_id.encode(), BOB.encode(), amount.encode()].concat(); - - // Mint asset which does not exist. - let result = Contracts::bare_call( - ALICE, - addr.clone(), - 0, - GAS_LIMIT, - None, - params.clone(), - DEBUG_OUTPUT, - pallet_contracts::CollectEvents::Skip, - pallet_contracts::Determinism::Enforced, - ); - - if DEBUG_OUTPUT == pallet_contracts::DebugInfo::UnsafeDebug { - log::debug!( - "Contract debug buffer - {:?}", - String::from_utf8(result.debug_message.clone()) - ); - log::debug!("result: {:?}", result); - } - - // Check for revert. - assert!(result.result.unwrap().did_revert(), "Contract should have been reverted!"); - - // Create asset with contract as owner. - assert_eq!( - TrustBackedAssets::force_create( - RuntimeOrigin::root(), - asset_id.into(), - addr.clone().into(), - true, - min_balance, - ), - Ok(()) - ); - - // Check Bob's asset balance before minting through contract. - let bob_balance_before = TrustBackedAssets::balance(asset_id, &BOB); - assert_eq!(bob_balance_before, 0); - - let result = Contracts::bare_call( - ALICE, - addr.clone(), - 0, - GAS_LIMIT, - None, - params, - DEBUG_OUTPUT, - pallet_contracts::CollectEvents::Skip, - pallet_contracts::Determinism::Enforced, - ); - - if DEBUG_OUTPUT == pallet_contracts::DebugInfo::UnsafeDebug { - log::debug!( - "Contract debug buffer - {:?}", - String::from_utf8(result.debug_message.clone()) - ); - log::debug!("result: {:?}", result); - } - - // Check for revert - assert!(!result.result.unwrap().did_revert(), "Contract reverted!"); - - let bob_balance_after = TrustBackedAssets::balance(asset_id, &BOB); - assert_eq!(bob_balance_after, bob_balance_before + amount); - }); - } - #[test] #[ignore] fn allow_call_filter_blocks_call() { diff --git a/runtime/testnet/src/lib.rs b/runtime/testnet/src/lib.rs index 312d9b50..66a5092c 100644 --- a/runtime/testnet/src/lib.rs +++ b/runtime/testnet/src/lib.rs @@ -253,74 +253,43 @@ impl Contains for FilteredCalls { pub struct AllowedPopApiCalls; impl Contains for crate::AllowedPopApiCalls { fn contains(c: &RuntimeCall) -> bool { - use assets_config::TrustBackedAssetsCall; use pallet_nfts::Call as NftsCall; matches!( c, RuntimeCall::Balances(BalancesCall::transfer_keep_alive { .. }) - | RuntimeCall::TrustBackedAssets( - TrustBackedAssetsCall::create { .. } - | TrustBackedAssetsCall::start_destroy { .. } - | TrustBackedAssetsCall::destroy_accounts { .. } - | TrustBackedAssetsCall::destroy_approvals { .. } - | TrustBackedAssetsCall::finish_destroy { .. } - | TrustBackedAssetsCall::mint { .. } - | TrustBackedAssetsCall::burn { .. } - | TrustBackedAssetsCall::transfer { .. } - | TrustBackedAssetsCall::transfer_keep_alive { .. } - | TrustBackedAssetsCall::force_transfer { .. } - | TrustBackedAssetsCall::freeze { .. } - | TrustBackedAssetsCall::thaw { .. } - | TrustBackedAssetsCall::freeze_asset { .. } - | TrustBackedAssetsCall::thaw_asset { .. } - | TrustBackedAssetsCall::transfer_ownership { .. } - | TrustBackedAssetsCall::set_team { .. } - | TrustBackedAssetsCall::set_metadata { .. } - | TrustBackedAssetsCall::clear_metadata { .. } - | TrustBackedAssetsCall::approve_transfer { .. } - | TrustBackedAssetsCall::cancel_approval { .. } - | TrustBackedAssetsCall::force_cancel_approval { .. } - | TrustBackedAssetsCall::transfer_approved { .. } - | TrustBackedAssetsCall::touch { .. } - | TrustBackedAssetsCall::refund { .. } - | TrustBackedAssetsCall::set_min_balance { .. } - | TrustBackedAssetsCall::touch_other { .. } - | TrustBackedAssetsCall::refund_other { .. } - | TrustBackedAssetsCall::block { .. } - ) | RuntimeCall::Nfts( - NftsCall::create { .. } - | NftsCall::destroy { .. } - | NftsCall::mint { .. } - | NftsCall::burn { .. } - | NftsCall::transfer { .. } - | NftsCall::redeposit { .. } - | NftsCall::lock_item_transfer { .. } - | NftsCall::unlock_item_transfer { .. } - | NftsCall::lock_collection { .. } - | NftsCall::transfer_ownership { .. } - | NftsCall::set_team { .. } - | NftsCall::approve_transfer { .. } - | NftsCall::cancel_approval { .. } - | NftsCall::clear_all_transfer_approvals { .. } - | NftsCall::lock_item_properties { .. } - | NftsCall::set_attribute { .. } - | NftsCall::clear_attribute { .. } - | NftsCall::approve_item_attributes { .. } - | NftsCall::cancel_item_attributes_approval { .. } - | NftsCall::set_metadata { .. } - | NftsCall::clear_metadata { .. } - | NftsCall::set_collection_metadata { .. } - | NftsCall::clear_collection_metadata { .. } - | NftsCall::set_accept_ownership { .. } - | NftsCall::set_collection_max_supply { .. } - | NftsCall::update_mint_settings { .. } - | NftsCall::set_price { .. } - | NftsCall::buy_item { .. } - | NftsCall::pay_tips { .. } - | NftsCall::create_swap { .. } - | NftsCall::cancel_swap { .. } - | NftsCall::claim_swap { .. } - ) + | RuntimeCall::Nfts( + NftsCall::create { .. } + | NftsCall::destroy { .. } + | NftsCall::mint { .. } | NftsCall::burn { .. } + | NftsCall::transfer { .. } + | NftsCall::redeposit { .. } + | NftsCall::lock_item_transfer { .. } + | NftsCall::unlock_item_transfer { .. } + | NftsCall::lock_collection { .. } + | NftsCall::transfer_ownership { .. } + | NftsCall::set_team { .. } + | NftsCall::approve_transfer { .. } + | NftsCall::cancel_approval { .. } + | NftsCall::clear_all_transfer_approvals { .. } + | NftsCall::lock_item_properties { .. } + | NftsCall::set_attribute { .. } + | NftsCall::clear_attribute { .. } + | NftsCall::approve_item_attributes { .. } + | NftsCall::cancel_item_attributes_approval { .. } + | NftsCall::set_metadata { .. } + | NftsCall::clear_metadata { .. } + | NftsCall::set_collection_metadata { .. } + | NftsCall::clear_collection_metadata { .. } + | NftsCall::set_accept_ownership { .. } + | NftsCall::set_collection_max_supply { .. } + | NftsCall::update_mint_settings { .. } + | NftsCall::set_price { .. } + | NftsCall::buy_item { .. } + | NftsCall::pay_tips { .. } + | NftsCall::create_swap { .. } + | NftsCall::cancel_swap { .. } + | NftsCall::claim_swap { .. } + ) ) } } @@ -661,7 +630,7 @@ construct_runtime!( // Assets Nfts: pallet_nfts = 50, NftFractionalization: pallet_nft_fractionalization = 51, - TrustBackedAssets: pallet_assets:: = 52, + Assets: pallet_assets:: = 52, } ); From fd46a279073abd855c327df6de32b2e155a74840 Mon Sep 17 00:00:00 2001 From: Daanvdplas Date: Tue, 4 Jun 2024 15:49:03 +0200 Subject: [PATCH 004/112] fix: add error handling other than ModuleError --- pop-api/examples/fungibles/lib.rs | 36 +-- pop-api/src/lib.rs | 53 +++- pop-api/src/v0/assets/fungibles.rs | 60 +++- pop-api/src/v0/balances.rs | 6 +- pop-api/src/v0/contracts.rs | 286 +++++++++--------- pop-api/src/v0/cross_chain/mod.rs | 4 +- pop-api/src/v0/dispatch_error.rs | 57 ++++ pop-api/src/v0/mod.rs | 3 +- pop-api/src/v0/nfts.rs | 4 +- runtime/devnet/src/extensions/mod.rs | 11 +- .../src/extensions/tests/local_fungibles.rs | 214 ++++++++----- runtime/devnet/src/extensions/tests/mod.rs | 10 +- 12 files changed, 462 insertions(+), 282 deletions(-) create mode 100644 pop-api/src/v0/dispatch_error.rs diff --git a/pop-api/examples/fungibles/lib.rs b/pop-api/examples/fungibles/lib.rs index 9c0ae754..e44c4347 100755 --- a/pop-api/examples/fungibles/lib.rs +++ b/pop-api/examples/fungibles/lib.rs @@ -10,42 +10,42 @@ use pop_api::{ #[derive(Debug, Copy, Clone, PartialEq, Eq, scale::Encode, scale::Decode)] #[cfg_attr(feature = "std", derive(scale_info::TypeInfo))] pub enum ContractError { - // AssetsError(Error), - // /// The origin of the call doesn't have the right permission. - // BadOrigin, - // /// Custom error type for cases in which an implementation adds its own restrictions. - // Custom(String), - /// Not enough balance to fulfill a request is available. - InsufficientBalance, + /// The amount to mint is less than the existential deposit. + BelowMinimum, + /// Unspecified dispatch error, providing the index and its error index (if none `0`). + DispatchError { index: u8, error: u8 }, /// Not enough allowance to fulfill a request is available. InsufficientAllowance, - /// The asset status is not the expected status. - IncorrectStatus, + /// Not enough balance to fulfill a request is available. + InsufficientBalance, /// The asset ID is already taken. InUse, /// Minimum balance should be non-zero. MinBalanceZero, + /// Unspecified pallet error, providing pallet index and error index. + ModuleError { pallet: u8, error: u16 }, /// The signing account has no permission to do the operation. NoPermission, - // /// Safe transfer check fails (e.g. if the receiving contract does not accept tokens). - // SafeTransferCheckFailed(String), /// The given asset ID is unknown. Unknown, - /// Recipient's address is zero. - ZeroRecipientAddress, - /// Sender's address is zero. - ZeroSenderAddress, - UndefinedError, } impl From for ContractError { fn from(error: FungiblesError) -> Self { match error { - // Error::BalanceLow => Err(InsufficientBalance), + FungiblesError::BelowMinimum => ContractError::BelowMinimum, + FungiblesError::DispatchError { index, error } => { + ContractError::DispatchError { index, error } + }, + FungiblesError::InsufficientAllowance => ContractError::InsufficientAllowance, + FungiblesError::InsufficientBalance => ContractError::InsufficientBalance, FungiblesError::InUse => ContractError::InUse, FungiblesError::MinBalanceZero => ContractError::MinBalanceZero, + FungiblesError::ModuleError { pallet, error } => { + ContractError::ModuleError { pallet, error } + }, + FungiblesError::NoPermission => ContractError::NoPermission, FungiblesError::Unknown => ContractError::Unknown, - _ => ContractError::UndefinedError, } } } diff --git a/pop-api/src/lib.rs b/pop-api/src/lib.rs index 0ca4a817..014b5a29 100644 --- a/pop-api/src/lib.rs +++ b/pop-api/src/lib.rs @@ -1,14 +1,16 @@ #![cfg_attr(not(feature = "std"), no_std, no_main)] -pub mod primitives; -pub mod v0; - -use crate::PopApiError::{Assets, Balances, Contracts, Nfts, UnknownStatusCode}; +use core::convert::TryInto; use ink::{prelude::vec::Vec, ChainExtensionInstance}; use primitives::{cross_chain::*, storage_keys::*, AccountId as AccountId32}; pub use sp_runtime::{BoundedVec, MultiAddress, MultiSignature}; use v0::RuntimeCall; -pub use v0::{assets, balances, contracts, cross_chain, nfts, relay_chain_block_number, state}; +pub use v0::{ + assets, balances, contracts, cross_chain, dispatch_error, nfts, relay_chain_block_number, state, +}; + +pub mod primitives; +pub mod v0; // type AccountId = ::AccountId; type AccountId = AccountId32; @@ -19,30 +21,49 @@ type MaxTips = u32; pub type Result = core::result::Result; +struct ModuleError { + pallet: u8, + error: u16, +} + #[derive(Debug, Copy, Clone, PartialEq, Eq, scale::Encode, scale::Decode)] #[cfg_attr(feature = "std", derive(scale_info::TypeInfo))] pub enum PopApiError { - UnknownStatusCode(u32), - DecodingFailed, - SystemCallFiltered, + Assets(assets::fungibles::AssetsError), Balances(balances::Error), Contracts(contracts::Error), + DecodingFailed, Nfts(nfts::Error), - Assets(assets::fungibles::AssetsError), + SystemCallFiltered, + TokenError(dispatch_error::TokenError), + UnknownModuleStatusCode(u32), + UnknownDispatchStatusCode(u32), Xcm(cross_chain::Error), } impl ink::env::chain_extension::FromStatusCode for PopApiError { fn from_status_code(status_code: u32) -> core::result::Result<(), Self> { + use crate::PopApiError::{ + Assets, Balances, Contracts, Nfts, TokenError, UnknownDispatchStatusCode, + UnknownModuleStatusCode, + }; + match status_code { 0 => Ok(()), - // CallFiltered originates from `frame_system` with pallet-index 0. The CallFiltered error is at index 5 - 5 => Err(PopApiError::SystemCallFiltered), - 10_000..=10_999 => Err(Balances((status_code - 10_000).try_into()?)), - 40_000..=40_999 => Err(Contracts((status_code - 40_000).try_into()?)), - 50_000..=50_999 => Err(Nfts((status_code - 50_000).try_into()?)), - 52_000..=52_999 => Err(Assets((status_code - 52_000).try_into()?)), - _ => Err(UnknownStatusCode(status_code)), + 3_000_000..=3_999_999 => { + let status_code = status_code - 3_000_000; + match status_code { + // CallFiltered originates from `frame_system` with pallet-index 0. The CallFiltered error is at index 5 + 5 => Err(PopApiError::SystemCallFiltered), + 10_000..=10_999 => Err(Balances((status_code - 10_000).try_into()?)), + 40_000..=40_999 => Err(Contracts((status_code - 40_000).try_into()?)), + 50_000..=50_999 => Err(Nfts((status_code - 50_000).try_into()?)), + 52_000..=52_999 => Err(Assets((status_code - 52_000).try_into()?)), + _ => Err(UnknownModuleStatusCode(status_code)), + } + }, + 7_000_000..=7_999_999 => Err(TokenError((status_code - 7_000_000).try_into()?)), + _ => Err(UnknownDispatchStatusCode(status_code)), } } } diff --git a/pop-api/src/v0/assets/fungibles.rs b/pop-api/src/v0/assets/fungibles.rs index f2d87a0e..de624938 100644 --- a/pop-api/src/v0/assets/fungibles.rs +++ b/pop-api/src/v0/assets/fungibles.rs @@ -1,4 +1,8 @@ -use crate::{AccountId, Balance, PopApiError::UnknownStatusCode, RuntimeCall, *}; +use crate::{ + AccountId, Balance, + PopApiError::{UnknownDispatchStatusCode, UnknownModuleStatusCode}, + RuntimeCall, *, +}; use ink::prelude::vec::Vec; use primitives::AssetId; use scale::{Compact, Encode}; @@ -502,7 +506,7 @@ impl TryFrom for AssetsError { 16 => Ok(AssetNotLive), 17 => Ok(IncorrectStatus), 18 => Ok(NotFrozen), - _ => Err(UnknownStatusCode(status_code)), + _ => Err(UnknownModuleStatusCode(status_code)), } } } @@ -510,22 +514,41 @@ impl TryFrom for AssetsError { #[derive(Debug, Copy, Clone, PartialEq, Eq, Encode, scale::Decode)] #[cfg_attr(feature = "std", derive(scale_info::TypeInfo))] pub enum FungiblesError { - /// The signing account has no permission to do the operation. - NoPermission, - /// The given asset ID is unknown. - Unknown, + /// The amount to mint is less than the existential deposit. + BelowMinimum, + /// Unspecified dispatch error, providing the index and its error index (if none `0`). + DispatchError { index: u8, error: u8 }, + /// Not enough allowance to fulfill a request is available. + InsufficientAllowance, + /// Not enough balance to fulfill a request is available. InsufficientBalance, /// The asset ID is already taken. InUse, /// Minimum balance should be non-zero. MinBalanceZero, + /// Unspecified pallet error, providing pallet index and error index. + ModuleError { pallet: u8, error: u16 }, + /// The signing account has no permission to do the operation. + NoPermission, + /// The given asset ID is unknown. + Unknown, } impl From for FungiblesError { fn from(error: balances::Error) -> Self { match error { balances::Error::InsufficientBalance => FungiblesError::InsufficientBalance, - _ => panic!("Unexpected pallet assets error. This error is unknown to pallet assets"), + _ => FungiblesError::ModuleError { pallet: 40, error: error as u16 }, + } + } +} + +impl From for FungiblesError { + fn from(error: dispatch_error::TokenError) -> Self { + match error { + dispatch_error::TokenError::UnknownAsset => FungiblesError::Unknown, + dispatch_error::TokenError::BelowMinimum => FungiblesError::BelowMinimum, + _ => FungiblesError::DispatchError { index: 7, error: error as u8 }, } } } @@ -533,8 +556,12 @@ impl From for FungiblesError { impl From for FungiblesError { fn from(error: AssetsError) -> Self { match error { + AssetsError::Unapproved => FungiblesError::InsufficientAllowance, AssetsError::InUse => FungiblesError::InUse, - _ => panic!("Unexpected pallet assets error. This error is unknown to pallet assets"), + AssetsError::MinBalanceZero => FungiblesError::MinBalanceZero, + AssetsError::NoPermission => FungiblesError::NoPermission, + AssetsError::Unknown => FungiblesError::Unknown, + _ => FungiblesError::ModuleError { pallet: 40, error: error as u16 }, } } } @@ -543,12 +570,19 @@ impl From for FungiblesError { fn from(error: PopApiError) -> Self { match error { PopApiError::Assets(e) => e.into(), - // PopApiError::Balances(e) => todo!("balances: {:?}", e), PopApiError::Balances(e) => e.into(), - // PopApiError::Contracts(_e) => todo!("contracts"), - // PopApiError::SystemCallFiltered => 100, - // PopApiError::UnknownStatusCode(u) => u, - _ => panic!("Unexpected pallet assets error. This error is unknown to pallet assets"), + PopApiError::TokenError(e) => e.into(), + PopApiError::UnknownModuleStatusCode(e) => { + let pallet = (e / 1_000) as u8; + let error = (e % 1_000) as u16; + FungiblesError::ModuleError { pallet, error } + }, + PopApiError::UnknownDispatchStatusCode(e) => { + let index = (e / 1_000_000) as u8; + let error = (3 % 1_000_000) as u8; + FungiblesError::DispatchError { index, error } + }, + _ => todo!(), } } } diff --git a/pop-api/src/v0/balances.rs b/pop-api/src/v0/balances.rs index bc48711e..bc422ef4 100644 --- a/pop-api/src/v0/balances.rs +++ b/pop-api/src/v0/balances.rs @@ -1,6 +1,6 @@ use crate::{ dispatch, primitives::MultiAddress, v0::RuntimeCall, AccountId, PopApiError, - PopApiError::UnknownStatusCode, + PopApiError::UnknownModuleStatusCode, }; type Result = core::result::Result; @@ -73,7 +73,7 @@ impl TryFrom for Error { 9 => Ok(TooManyFreezes), 10 => Ok(IssuanceDeactivated), 11 => Ok(DeltaZero), - _ => Err(UnknownStatusCode(status_code)), + _ => Err(UnknownModuleStatusCode(status_code)), } } } @@ -82,7 +82,7 @@ impl From for Error { fn from(error: PopApiError) -> Self { match error { PopApiError::Balances(e) => e, - _ => panic!("expected balances error"), + _ => todo!(), } } } diff --git a/pop-api/src/v0/contracts.rs b/pop-api/src/v0/contracts.rs index d7a1a5dd..5d4a3692 100644 --- a/pop-api/src/v0/contracts.rs +++ b/pop-api/src/v0/contracts.rs @@ -1,156 +1,152 @@ -use crate::{ - PopApiError, - PopApiError::UnknownStatusCode, -}; +use crate::{PopApiError, PopApiError::UnknownModuleStatusCode}; #[derive(Debug, Copy, Clone, PartialEq, Eq, scale::Encode, scale::Decode)] #[cfg_attr(feature = "std", derive(scale_info::TypeInfo))] pub enum Error { - /// Invalid schedule supplied, e.g. with zero weight of a basic operation. - InvalidSchedule, - /// Invalid combination of flags supplied to `seal_call` or `seal_delegate_call`. - InvalidCallFlags, - /// The executed contract exhausted its gas limit. - OutOfGas, - /// The output buffer supplied to a contract API call was too small. - OutputBufferTooSmall, - /// Performing the requested transfer failed. Probably because there isn't enough - /// free balance in the sender's account. - TransferFailed, - /// Performing a call was denied because the calling depth reached the limit - /// of what is specified in the schedule. - MaxCallDepthReached, - /// No contract was found at the specified address. - ContractNotFound, - /// The code supplied to `instantiate_with_code` exceeds the limit specified in the - /// current schedule. - CodeTooLarge, - /// No code could be found at the supplied code hash. - CodeNotFound, - /// No code info could be found at the supplied code hash. - CodeInfoNotFound, - /// A buffer outside of sandbox memory was passed to a contract API function. - OutOfBounds, - /// Input passed to a contract API function failed to decode as expected type. - DecodingFailed, - /// Contract trapped during execution. - ContractTrapped, - /// The size defined in `T::MaxValueSize` was exceeded. - ValueTooLarge, - /// Termination of a contract is not allowed while the contract is already - /// on the call stack. Can be triggered by `seal_terminate`. - TerminatedWhileReentrant, - /// `seal_call` forwarded this contracts input. It therefore is no longer available. - InputForwarded, - /// The subject passed to `seal_random` exceeds the limit. - RandomSubjectTooLong, - /// The amount of topics passed to `seal_deposit_events` exceeds the limit. - TooManyTopics, - /// The chain does not provide a chain extension. Calling the chain extension results - /// in this error. Note that this usually shouldn't happen as deploying such contracts - /// is rejected. - NoChainExtension, - /// Failed to decode the XCM program. - XCMDecodeFailed, - /// A contract with the same AccountId already exists. - DuplicateContract, - /// A contract self destructed in its constructor. - /// - /// This can be triggered by a call to `seal_terminate`. - TerminatedInConstructor, - /// A call tried to invoke a contract that is flagged as non-reentrant. - /// The only other cause is that a call from a contract into the runtime tried to call back - /// into `pallet-contracts`. This would make the whole pallet reentrant with regard to - /// contract code execution which is not supported. - ReentranceDenied, - /// Origin doesn't have enough balance to pay the required storage deposits. - StorageDepositNotEnoughFunds, - /// More storage was created than allowed by the storage deposit limit. - StorageDepositLimitExhausted, - /// Code removal was denied because the code is still in use by at least one contract. - CodeInUse, - /// The contract ran to completion but decided to revert its storage changes. - /// Please note that this error is only returned from extrinsics. When called directly - /// or via RPC an `Ok` will be returned. In this case the caller needs to inspect the flags - /// to determine whether a reversion has taken place. - ContractReverted, - /// The contract's code was found to be invalid during validation. - /// - /// The most likely cause of this is that an API was used which is not supported by the - /// node. This happens if an older node is used with a new version of ink!. Try updating - /// your node to the newest available version. - /// - /// A more detailed error can be found on the node console if debug messages are enabled - /// by supplying `-lruntime::contracts=debug`. - CodeRejected, - /// An indeterministic code was used in a context where this is not permitted. - Indeterministic, - /// A pending migration needs to complete before the extrinsic can be called. - MigrationInProgress, - /// Migrate dispatch call was attempted but no migration was performed. - NoMigrationPerformed, - /// The contract has reached its maximum number of delegate dependencies. - MaxDelegateDependenciesReached, - /// The dependency was not found in the contract's delegate dependencies. - DelegateDependencyNotFound, - /// The contract already depends on the given delegate dependency. - DelegateDependencyAlreadyExists, - /// Can not add a delegate dependency to the code hash of the contract itself. - CannotAddSelfAsDelegateDependency, + /// Invalid schedule supplied, e.g. with zero weight of a basic operation. + InvalidSchedule, + /// Invalid combination of flags supplied to `seal_call` or `seal_delegate_call`. + InvalidCallFlags, + /// The executed contract exhausted its gas limit. + OutOfGas, + /// The output buffer supplied to a contract API call was too small. + OutputBufferTooSmall, + /// Performing the requested transfer failed. Probably because there isn't enough + /// free balance in the sender's account. + TransferFailed, + /// Performing a call was denied because the calling depth reached the limit + /// of what is specified in the schedule. + MaxCallDepthReached, + /// No contract was found at the specified address. + ContractNotFound, + /// The code supplied to `instantiate_with_code` exceeds the limit specified in the + /// current schedule. + CodeTooLarge, + /// No code could be found at the supplied code hash. + CodeNotFound, + /// No code info could be found at the supplied code hash. + CodeInfoNotFound, + /// A buffer outside of sandbox memory was passed to a contract API function. + OutOfBounds, + /// Input passed to a contract API function failed to decode as expected type. + DecodingFailed, + /// Contract trapped during execution. + ContractTrapped, + /// The size defined in `T::MaxValueSize` was exceeded. + ValueTooLarge, + /// Termination of a contract is not allowed while the contract is already + /// on the call stack. Can be triggered by `seal_terminate`. + TerminatedWhileReentrant, + /// `seal_call` forwarded this contracts input. It therefore is no longer available. + InputForwarded, + /// The subject passed to `seal_random` exceeds the limit. + RandomSubjectTooLong, + /// The amount of topics passed to `seal_deposit_events` exceeds the limit. + TooManyTopics, + /// The chain does not provide a chain extension. Calling the chain extension results + /// in this error. Note that this usually shouldn't happen as deploying such contracts + /// is rejected. + NoChainExtension, + /// Failed to decode the XCM program. + XCMDecodeFailed, + /// A contract with the same AccountId already exists. + DuplicateContract, + /// A contract self destructed in its constructor. + /// + /// This can be triggered by a call to `seal_terminate`. + TerminatedInConstructor, + /// A call tried to invoke a contract that is flagged as non-reentrant. + /// The only other cause is that a call from a contract into the runtime tried to call back + /// into `pallet-contracts`. This would make the whole pallet reentrant with regard to + /// contract code execution which is not supported. + ReentranceDenied, + /// Origin doesn't have enough balance to pay the required storage deposits. + StorageDepositNotEnoughFunds, + /// More storage was created than allowed by the storage deposit limit. + StorageDepositLimitExhausted, + /// Code removal was denied because the code is still in use by at least one contract. + CodeInUse, + /// The contract ran to completion but decided to revert its storage changes. + /// Please note that this error is only returned from extrinsics. When called directly + /// or via RPC an `Ok` will be returned. In this case the caller needs to inspect the flags + /// to determine whether a reversion has taken place. + ContractReverted, + /// The contract's code was found to be invalid during validation. + /// + /// The most likely cause of this is that an API was used which is not supported by the + /// node. This happens if an older node is used with a new version of ink!. Try updating + /// your node to the newest available version. + /// + /// A more detailed error can be found on the node console if debug messages are enabled + /// by supplying `-lruntime::contracts=debug`. + CodeRejected, + /// An indeterministic code was used in a context where this is not permitted. + Indeterministic, + /// A pending migration needs to complete before the extrinsic can be called. + MigrationInProgress, + /// Migrate dispatch call was attempted but no migration was performed. + NoMigrationPerformed, + /// The contract has reached its maximum number of delegate dependencies. + MaxDelegateDependenciesReached, + /// The dependency was not found in the contract's delegate dependencies. + DelegateDependencyNotFound, + /// The contract already depends on the given delegate dependency. + DelegateDependencyAlreadyExists, + /// Can not add a delegate dependency to the code hash of the contract itself. + CannotAddSelfAsDelegateDependency, } - impl TryFrom for Error { - type Error = PopApiError; + type Error = PopApiError; - fn try_from(status_code: u32) -> core::result::Result { - use Error::*; - match status_code { - 0 => Ok(InvalidSchedule), - 1 => Ok(InvalidCallFlags), - 2 => Ok(OutOfGas), - 3 => Ok(OutputBufferTooSmall), - 4 => Ok(TransferFailed), - 5 => Ok(MaxCallDepthReached), - 6 => Ok(ContractNotFound), - 7 => Ok(CodeTooLarge), - 8 => Ok(CodeNotFound), - 9 => Ok(CodeInfoNotFound), - 10 => Ok(OutOfBounds), - 11 => Ok(DecodingFailed), - 12 => Ok(ContractTrapped), - 13 => Ok(ValueTooLarge), - 14 => Ok(TerminatedWhileReentrant), - 15 => Ok(InputForwarded), - 16 => Ok(RandomSubjectTooLong), - 17 => Ok(TooManyTopics), - 18 => Ok(NoChainExtension), - 19 => Ok(XCMDecodeFailed), - 20 => Ok(DuplicateContract), - 21 => Ok(TerminatedInConstructor), - 22 => Ok(ReentranceDenied), - 23 => Ok(StorageDepositNotEnoughFunds), - 24 => Ok(StorageDepositLimitExhausted), - 25 => Ok(CodeInUse), - 26 => Ok(ContractReverted), - 27 => Ok(CodeRejected), - 28 => Ok(Indeterministic), - 29 => Ok(MigrationInProgress), - 30 => Ok(NoMigrationPerformed), - 31 => Ok(MaxDelegateDependenciesReached), - 32 => Ok(DelegateDependencyNotFound), - 33 => Ok(DelegateDependencyAlreadyExists), - 34 => Ok(CannotAddSelfAsDelegateDependency), - _ => Err(UnknownStatusCode(status_code)), - } - } + fn try_from(status_code: u32) -> core::result::Result { + use Error::*; + match status_code { + 0 => Ok(InvalidSchedule), + 1 => Ok(InvalidCallFlags), + 2 => Ok(OutOfGas), + 3 => Ok(OutputBufferTooSmall), + 4 => Ok(TransferFailed), + 5 => Ok(MaxCallDepthReached), + 6 => Ok(ContractNotFound), + 7 => Ok(CodeTooLarge), + 8 => Ok(CodeNotFound), + 9 => Ok(CodeInfoNotFound), + 10 => Ok(OutOfBounds), + 11 => Ok(DecodingFailed), + 12 => Ok(ContractTrapped), + 13 => Ok(ValueTooLarge), + 14 => Ok(TerminatedWhileReentrant), + 15 => Ok(InputForwarded), + 16 => Ok(RandomSubjectTooLong), + 17 => Ok(TooManyTopics), + 18 => Ok(NoChainExtension), + 19 => Ok(XCMDecodeFailed), + 20 => Ok(DuplicateContract), + 21 => Ok(TerminatedInConstructor), + 22 => Ok(ReentranceDenied), + 23 => Ok(StorageDepositNotEnoughFunds), + 24 => Ok(StorageDepositLimitExhausted), + 25 => Ok(CodeInUse), + 26 => Ok(ContractReverted), + 27 => Ok(CodeRejected), + 28 => Ok(Indeterministic), + 29 => Ok(MigrationInProgress), + 30 => Ok(NoMigrationPerformed), + 31 => Ok(MaxDelegateDependenciesReached), + 32 => Ok(DelegateDependencyNotFound), + 33 => Ok(DelegateDependencyAlreadyExists), + 34 => Ok(CannotAddSelfAsDelegateDependency), + _ => Err(UnknownModuleStatusCode(status_code)), + } + } } impl From for Error { - fn from(error: PopApiError) -> Self { - match error { - PopApiError::Contracts(e) => e, - _ => panic!("expected balances error"), - } - } -} \ No newline at end of file + fn from(error: PopApiError) -> Self { + match error { + PopApiError::Contracts(e) => e, + _ => panic!("expected balances error"), + } + } +} diff --git a/pop-api/src/v0/cross_chain/mod.rs b/pop-api/src/v0/cross_chain/mod.rs index 6732c119..1e5afbf5 100644 --- a/pop-api/src/v0/cross_chain/mod.rs +++ b/pop-api/src/v0/cross_chain/mod.rs @@ -1,6 +1,6 @@ pub mod coretime; -use crate::{PopApiError::UnknownStatusCode, *}; +use crate::{PopApiError::UnknownModuleStatusCode, *}; type Result = core::result::Result; @@ -92,7 +92,7 @@ impl TryFrom for Error { 21 => Ok(InvalidAssetUnknownReserve), 22 => Ok(InvalidAssetUnsupportedReserve), 23 => Ok(TooManyReserves), - _ => Err(UnknownStatusCode(status_code)), + _ => Err(UnknownModuleStatusCode(status_code)), } } } diff --git a/pop-api/src/v0/dispatch_error.rs b/pop-api/src/v0/dispatch_error.rs new file mode 100644 index 00000000..6ed40ce5 --- /dev/null +++ b/pop-api/src/v0/dispatch_error.rs @@ -0,0 +1,57 @@ +use super::*; + +#[derive(Debug, Copy, Clone, PartialEq, Eq, scale::Encode, scale::Decode)] +#[cfg_attr(feature = "std", derive(scale_info::TypeInfo))] +pub(crate) enum TokenError { + /// Funds are unavailable. + FundsUnavailable, + /// Some part of the balance gives the only provider reference to the account and thus cannot + /// be (re)moved. + OnlyProvider, + /// Account cannot exist with the funds that would be given. + BelowMinimum, + /// Account cannot be created. + CannotCreate, + /// The asset in question is unknown. + UnknownAsset, + /// Funds exist but are frozen. + Frozen, + /// Operation is not supported by the asset. + Unsupported, + /// Account cannot be created for a held balance. + CannotCreateHold, + /// Withdrawal would cause unwanted loss of account. + NotExpendable, + /// Account cannot receive the assets. + Blocked, +} + +impl TryFrom for TokenError { + type Error = crate::PopApiError; + + fn try_from(status_code: u32) -> core::result::Result { + use TokenError::*; + match status_code { + 0 => Ok(FundsUnavailable), + 1 => Ok(OnlyProvider), + 2 => Ok(BelowMinimum), + 3 => Ok(CannotCreate), + 4 => Ok(UnknownAsset), + 5 => Ok(Frozen), + 6 => Ok(Unsupported), + 7 => Ok(CannotCreateHold), + 8 => Ok(NotExpendable), + 9 => Ok(Blocked), + _ => todo!(), + } + } +} + +impl From for TokenError { + fn from(error: PopApiError) -> Self { + match error { + PopApiError::TokenError(e) => e, + _ => todo!(), + } + } +} diff --git a/pop-api/src/v0/mod.rs b/pop-api/src/v0/mod.rs index def37e55..02169c22 100644 --- a/pop-api/src/v0/mod.rs +++ b/pop-api/src/v0/mod.rs @@ -3,12 +3,13 @@ use crate::{ BlockNumber, PopApiError, }; +pub mod assets; pub mod balances; pub mod contracts; pub mod cross_chain; +pub mod dispatch_error; pub mod nfts; pub mod state; -pub mod assets; pub fn relay_chain_block_number() -> Result { state::read(RuntimeStateKeys::ParachainSystem(ParachainSystemKeys::LastRelayChainBlockNumber)) diff --git a/pop-api/src/v0/nfts.rs b/pop-api/src/v0/nfts.rs index 5a55154f..946a3eca 100644 --- a/pop-api/src/v0/nfts.rs +++ b/pop-api/src/v0/nfts.rs @@ -1,5 +1,5 @@ use super::RuntimeCall; -use crate::{PopApiError::UnknownStatusCode, *}; +use crate::{PopApiError::UnknownModuleStatusCode, *}; use ink::prelude::vec::Vec; use primitives::{ApprovalsLimit, BoundedBTreeMap, KeyLimit, MultiAddress}; pub use primitives::{CollectionId, ItemId}; @@ -660,7 +660,7 @@ impl TryFrom for Error { 42 => Ok(WrongNamespace), 43 => Ok(CollectionNotEmpty), 44 => Ok(WitnessRequired), - _ => Err(UnknownStatusCode(status_code)), + _ => Err(UnknownModuleStatusCode(status_code)), } } } diff --git a/runtime/devnet/src/extensions/mod.rs b/runtime/devnet/src/extensions/mod.rs index 096f21c9..d2129c4f 100644 --- a/runtime/devnet/src/extensions/mod.rs +++ b/runtime/devnet/src/extensions/mod.rs @@ -69,10 +69,19 @@ where Err(DispatchError::Module(error)) => { // encode status code = pallet index in runtime + error index, allowing for // 999 errors + let first = (3u32 * 1_000_000u32) + + (error.index as u32 * 1_000u32) + + u32::from_le_bytes(error.error); Ok(RetVal::Converging( - (error.index as u32 * 1_000) + u32::from_le_bytes(error.error), + // (3u32 * 1_000_000u32) + // + (error.index as u32 * 1_000u32) + // + u32::from_le_bytes(error.error), + first, )) }, + Err(DispatchError::Token(error)) => { + Ok(RetVal::Converging((7u32 * 1_000_000u32) + error as u32)) + }, Err(e) => Err(e), } }, diff --git a/runtime/devnet/src/extensions/tests/local_fungibles.rs b/runtime/devnet/src/extensions/tests/local_fungibles.rs index 2d752361..5bd7dac0 100644 --- a/runtime/devnet/src/extensions/tests/local_fungibles.rs +++ b/runtime/devnet/src/extensions/tests/local_fungibles.rs @@ -5,36 +5,32 @@ use pallet_contracts::debug::ExecResult; #[derive(Decode, Encode, Debug, Eq, PartialEq)] enum FungiblesError { - // AssetsError(Error), - // /// The origin of the call doesn't have the right permission. - // BadOrigin, - // /// Custom error type for cases in which an implementation adds its own restrictions. - // Custom(String), - /// Not enough balance to fulfill a request is available. - InsufficientBalance, + /// The amount to mint is less than the existential deposit. + BelowMinimum, + /// Unspecified dispatch error, providing the index and optionally its error index. + DispatchError { index: u8, error: Option }, /// Not enough allowance to fulfill a request is available. InsufficientAllowance, - /// The asset status is not the expected status. - IncorrectStatus, + /// Not enough balance to fulfill a request is available. + InsufficientBalance, /// The asset ID is already taken. InUse, /// Minimum balance should be non-zero. MinBalanceZero, + /// Unspecified pallet error, providing pallet index and error index. + ModuleError { pallet: u8, error: u16 }, /// The signing account has no permission to do the operation. NoPermission, - // /// Safe transfer check fails (e.g. if the receiving contract does not accept tokens). - // SafeTransferCheckFailed(String), /// The given asset ID is unknown. Unknown, - /// Recipient's address is zero. - ZeroRecipientAddress, - /// Sender's address is zero. - ZeroSenderAddress, - UndefinedError, } const ASSET_ID: u32 = 1; +fn decoded(result: ExecReturnValue) -> T { + ::decode(&mut &result.data[2..]).unwrap() +} + fn allowance( addr: AccountId32, asset_id: u32, @@ -54,10 +50,11 @@ fn balance_of(addr: AccountId32, asset_id: u32, owner: AccountId32) -> ExecRetur } // Call total_supply contract message. -fn total_supply(addr: AccountId32, asset_id: u32) -> ExecReturnValue { +fn total_supply(addr: AccountId32, asset_id: u32) -> Balance { let function = function_selector("total_supply"); let params = [function, asset_id.encode()].concat(); - do_bare_call(addr, params, 0).expect("should work") + let result = do_bare_call(addr, params, 0).expect("should work"); + decoded::(result) } fn asset_exists(addr: AccountId32, asset_id: u32) -> ExecReturnValue { @@ -70,7 +67,7 @@ fn create( addr: AccountId32, asset_id: u32, admin: AccountId32, - min_balance: u128, + min_balance: Balance, ) -> ExecReturnValue { let function = function_selector("create"); let params = [function, asset_id.encode(), admin.encode(), min_balance.encode()].concat(); @@ -95,7 +92,7 @@ fn transfer_from( asset_id: u32, _from: Option, to: Option, - value: u128, + value: Balance, _data: &[u8], ) -> ExecReturnValue { // let function = function_selector("transfer_from"); @@ -109,16 +106,21 @@ fn transfer_from( } // Create an asset and mint to owner. -fn create_asset(asset_id: u32, owner: AccountId32) { +fn create_asset(asset_id: u32, owner: AccountId32, min_balance: Balance) { assert_eq!( - Assets::create(RuntimeOrigin::signed(owner.clone()), asset_id.into(), owner.into(), 1), + Assets::create( + RuntimeOrigin::signed(owner.clone()), + asset_id.into(), + owner.into(), + min_balance + ), Ok(()) ); } // Create an asset and mint to owner. -fn create_asset_and_mint_to(asset_id: u32, owner: AccountId32, to: AccountId32, value: u128) { - create_asset(asset_id, owner.clone()); +fn create_asset_and_mint_to(asset_id: u32, owner: AccountId32, to: AccountId32, value: Balance) { + create_asset(asset_id, owner.clone(), 1); assert_eq!( Assets::mint(RuntimeOrigin::signed(owner.into()), asset_id.into(), to.into(), value,), Ok(()) @@ -130,9 +132,9 @@ fn create_asset_mint_and_approve( asset_id: u32, owner: AccountId32, to: AccountId32, - mint: u128, + mint: Balance, spender: AccountId32, - approve: u128, + approve: Balance, ) { create_asset_and_mint_to(asset_id, owner.clone(), to.clone(), mint); assert_eq!( @@ -151,18 +153,18 @@ fn create_asset_mint_and_approve( fn total_supply_works() { new_test_ext().execute_with(|| { let _ = env_logger::try_init(); - let addr = - instantiate("../../pop-api/examples/fungibles/target/ink/fungibles.wasm", INIT_VALUE); + let addr = instantiate( + "../../pop-api/examples/fungibles/target/ink/fungibles.wasm", + INIT_VALUE, + vec![], + ); // No tokens in circulation. - assert_eq!( - Assets::total_supply(ASSET_ID).encode(), - total_supply(addr.clone(), ASSET_ID).data[2..] - ); + assert_eq!(Assets::total_supply(ASSET_ID), total_supply(addr.clone(), ASSET_ID)); // Tokens in circulation. create_asset_and_mint_to(ASSET_ID, addr.clone(), BOB, 100); - assert_eq!(Assets::total_supply(ASSET_ID).encode(), total_supply(addr, ASSET_ID).data[2..]); + assert_eq!(Assets::total_supply(ASSET_ID), total_supply(addr, ASSET_ID)); }); } @@ -171,8 +173,11 @@ fn total_supply_works() { fn balance_of_works() { new_test_ext().execute_with(|| { let _ = env_logger::try_init(); - let addr = - instantiate("../../pop-api/examples/fungibles/target/ink/fungibles.wasm", INIT_VALUE); + let addr = instantiate( + "../../pop-api/examples/fungibles/target/ink/fungibles.wasm", + INIT_VALUE, + vec![], + ); // No tokens in circulation. assert_eq!( @@ -194,8 +199,11 @@ fn balance_of_works() { fn allowance_works() { new_test_ext().execute_with(|| { let _ = env_logger::try_init(); - let addr = - instantiate("../../pop-api/examples/fungibles/target/ink/fungibles.wasm", INIT_VALUE); + let addr = instantiate( + "../../pop-api/examples/fungibles/target/ink/fungibles.wasm", + INIT_VALUE, + vec![], + ); // No tokens in circulation. assert_eq!( @@ -217,8 +225,11 @@ fn allowance_works() { fn asset_exists_works() { new_test_ext().execute_with(|| { let _ = env_logger::try_init(); - let addr = - instantiate("../../pop-api/examples/fungibles/target/ink/fungibles.wasm", INIT_VALUE); + let addr = instantiate( + "../../pop-api/examples/fungibles/target/ink/fungibles.wasm", + INIT_VALUE, + vec![], + ); // No tokens in circulation. assert_eq!( @@ -227,40 +238,45 @@ fn asset_exists_works() { ); // Tokens in circulation. - create_asset(ASSET_ID, addr.clone()); + create_asset(ASSET_ID, addr.clone(), 1); assert_eq!(Assets::asset_exists(ASSET_ID).encode(), asset_exists(addr, ASSET_ID).data[2..]); }); } -fn decode_error(result: ExecReturnValue) -> FungiblesError { - FungiblesError::decode(&mut &result.data[2..]).unwrap() -} - +// Todo - errors: +// - Badorigin: contract is always signed +// - Lookup: is a valid AccountId due to the contract +// - reserve(): Overflow, LiquidityRestrictions; frozen +// - Callback +// - StorageDepositLimitExhausted #[test] #[ignore] fn create_works() { new_test_ext().execute_with(|| { let _ = env_logger::try_init(); - let addr = instantiate("../../pop-api/examples/fungibles/target/ink/fungibles.wasm", 0); let new_asset = 2; + let addr = + instantiate("../../pop-api/examples/fungibles/target/ink/fungibles.wasm", 0, vec![0]); assert_eq!( - decode_error(create(addr.clone(), new_asset, BOB, 1)), - FungiblesError::UndefinedError + decoded::(create(addr.clone(), ASSET_ID, addr.clone(), 1)), + FungiblesError::InsufficientBalance ); - // Todo: errors Badorigin, Lookup, reserve(), Callback - // create_asset(ASSET_ID, ALICE); - // // Error `InUse`. - // assert_eq!(decode_error(create(addr.clone(), ASSET_ID, BOB, 1)), FungiblesError::InUse); - // // Error `MinBalanceZero`. - // assert_eq!( - // decode_error(create(addr.clone(), new_asset, BOB, 0)), - // FungiblesError::MinBalanceZero - // ); - // assert!( - // !create(addr.clone(), new_asset, BOB, 1).did_revert(), - // "Contract should have been reverted!" - // ); + let addr = instantiate( + "../../pop-api/examples/fungibles/target/ink/fungibles.wasm", + INIT_VALUE, + vec![1], + ); + create_asset(ASSET_ID, ALICE, 1); + assert_eq!( + decoded::(create(addr.clone(), ASSET_ID, BOB, 1)), + FungiblesError::InUse + ); + assert_eq!( + decoded::(create(addr.clone(), new_asset, BOB, 0)), + FungiblesError::MinBalanceZero + ); + assert!(!create(addr.clone(), new_asset, BOB, 1).did_revert(), "Contract reverted!"); }); } @@ -269,34 +285,78 @@ fn create_works() { fn set_metadata_works() { new_test_ext().execute_with(|| { let _ = env_logger::try_init(); - let addr = - instantiate("../../pop-api/examples/fungibles/target/ink/fungibles.wasm", INIT_VALUE); + let addr = instantiate( + "../../pop-api/examples/fungibles/target/ink/fungibles.wasm", + INIT_VALUE, + vec![], + ); - create_asset(ASSET_ID, addr.clone()); + create_asset(ASSET_ID, addr.clone(), 1); let result = set_metadata(addr.clone(), ASSET_ID, vec![12], vec![12], 12); - assert!(!result.did_revert(), "Contract should have been reverted!"); + assert!(!result.did_revert(), "Contract reverted!"); }); } +// todo: errors: +// - AssetNotLive: when frozen or being destroyed +// - TokenErrors: https://github.com/paritytech/polkadot-sdk/blob/3977f389cce4a00fd7100f95262e0563622b9aa4/substrate/frame/assets/src/functions.rs#L125 #[test] #[ignore] -fn transfer_from_aka_mint_works() { +fn mint_works() { new_test_ext().execute_with(|| { let _ = env_logger::try_init(); - let addr = - instantiate("../../pop-api/examples/fungibles/target/ink/fungibles.wasm", INIT_VALUE); - - let amount: u128 = 100 * UNIT; - // Create asset with contract as owner. - create_asset(ASSET_ID, addr.clone()); - // Check Bob's asset balance before minting through contract. - let bob_balance_before = Assets::balance(ASSET_ID, &BOB); + let addr = instantiate( + "../../pop-api/examples/fungibles/target/ink/fungibles.wasm", + INIT_VALUE, + vec![], + ); + let amount: Balance = 100 * UNIT; - let result = transfer_from(addr.clone(), ASSET_ID, None, Some(BOB), 100 * UNIT, &[0u8]); + assert_eq!( + decoded::(transfer_from( + addr.clone(), + ASSET_ID, + None, + Some(BOB), + amount, + &[0u8] + )), + FungiblesError::Unknown + ); + create_asset(ASSET_ID, ALICE, 2); + assert_eq!( + decoded::(transfer_from( + addr.clone(), + ASSET_ID, + None, + Some(BOB), + amount, + &[0u8] + )), + FungiblesError::NoPermission + ); + assert_eq!( + decoded::(transfer_from( + addr.clone(), + ASSET_ID, + None, + Some(BOB), + 1, + &[0u8] + )), + FungiblesError::BelowMinimum + ); + let asset = 2; + create_asset(asset, addr.clone(), 2); + let bob_balance_before_mint = Assets::balance(asset, &BOB); + let result = transfer_from(addr.clone(), asset, None, Some(BOB), 100 * UNIT, &[0u8]); assert!(!result.did_revert(), "Contract reverted!"); - - let bob_balance_after = Assets::balance(ASSET_ID, &BOB); - assert_eq!(bob_balance_after, bob_balance_before + amount); + let bob_balance_after_mint = Assets::balance(asset, &BOB); + assert_eq!(bob_balance_after_mint, bob_balance_before_mint + amount); }); } + +#[test] +#[ignore] +fn transfer_works() {} diff --git a/runtime/devnet/src/extensions/tests/mod.rs b/runtime/devnet/src/extensions/tests/mod.rs index 30d1a924..03cda2cd 100644 --- a/runtime/devnet/src/extensions/tests/mod.rs +++ b/runtime/devnet/src/extensions/tests/mod.rs @@ -6,11 +6,13 @@ use sp_runtime::{traits::Hash, AccountId32, BuildStorage}; mod local_fungibles; +type Balance = u128; const DEBUG_OUTPUT: pallet_contracts::DebugInfo = pallet_contracts::DebugInfo::UnsafeDebug; const ALICE: AccountId32 = AccountId32::new([1_u8; 32]); const BOB: AccountId32 = AccountId32::new([2_u8; 32]); -const INIT_VALUE: u128 = 100_000_000 * UNIT; +const INIT_AMOUNT: Balance = 100_000_000 * UNIT; +const INIT_VALUE: Balance = 100 * UNIT; const GAS_LIMIT: Weight = Weight::from_parts(100_000_000_000, 3 * 1024 * 1024); fn new_test_ext() -> sp_io::TestExternalities { @@ -19,7 +21,7 @@ fn new_test_ext() -> sp_io::TestExternalities { .expect("Frame system builds valid default genesis config"); pallet_balances::GenesisConfig:: { - balances: vec![(ALICE, INIT_VALUE), (BOB, INIT_VALUE)], + balances: vec![(ALICE, INIT_AMOUNT), (BOB, INIT_AMOUNT)], } .assimilate_storage(&mut t) .expect("Pallet balances storage can be assimilated"); @@ -65,7 +67,7 @@ fn do_bare_call( } // Deploy, instantiate and return contract address. -fn instantiate(contract: &str, init_value: u128) -> AccountId32 { +fn instantiate(contract: &str, init_value: u128, salt: Vec) -> AccountId32 { let (wasm_binary, _) = load_wasm_module::(contract).expect("could not read .wasm file"); let result = Contracts::bare_instantiate( @@ -75,7 +77,7 @@ fn instantiate(contract: &str, init_value: u128) -> AccountId32 { None, Code::Upload(wasm_binary), function_selector("new"), - vec![], + salt, DEBUG_OUTPUT, CollectEvents::Skip, ) From 1022926e0d35ee56930a0757655df3c7f12b6ec4 Mon Sep 17 00:00:00 2001 From: Daanvdplas Date: Thu, 6 Jun 2024 11:48:55 +0200 Subject: [PATCH 005/112] test: add transfer --- pop-api/examples/fungibles/lib.rs | 108 +++++---- pop-api/src/lib.rs | 7 +- pop-api/src/v0/assets/fungibles.rs | 206 ++++++++++-------- pop-api/src/v0/balances.rs | 10 +- .../src/extensions/tests/local_fungibles.rs | 205 ++++++++++++----- runtime/devnet/src/extensions/tests/mod.rs | 1 + 6 files changed, 344 insertions(+), 193 deletions(-) diff --git a/pop-api/examples/fungibles/lib.rs b/pop-api/examples/fungibles/lib.rs index e44c4347..68e43865 100755 --- a/pop-api/examples/fungibles/lib.rs +++ b/pop-api/examples/fungibles/lib.rs @@ -1,6 +1,10 @@ #![cfg_attr(not(feature = "std"), no_std, no_main)] -// Fungibles wrapper contract to allow contracts to interact with local fungibles without the pop api. +/// Local Fungibles: +/// 1. PSP-22 Interface +/// 2. PSP-22 Metadata Interface +/// 3. Asset Management +/// use ink::prelude::vec::Vec; use pop_api::{ assets::fungibles::*, @@ -10,6 +14,8 @@ use pop_api::{ #[derive(Debug, Copy, Clone, PartialEq, Eq, scale::Encode, scale::Decode)] #[cfg_attr(feature = "std", derive(scale_info::TypeInfo))] pub enum ContractError { + /// The asset is not live; either frozen or being destroyed. + AssetNotLive, /// The amount to mint is less than the existential deposit. BelowMinimum, /// Unspecified dispatch error, providing the index and its error index (if none `0`). @@ -24,6 +30,8 @@ pub enum ContractError { MinBalanceZero, /// Unspecified pallet error, providing pallet index and error index. ModuleError { pallet: u8, error: u16 }, + /// The account to alter does not exist. + NoAccount, /// The signing account has no permission to do the operation. NoPermission, /// The given asset ID is unknown. @@ -33,6 +41,7 @@ pub enum ContractError { impl From for ContractError { fn from(error: FungiblesError) -> Self { match error { + FungiblesError::AssetNotLive => ContractError::AssetNotLive, FungiblesError::BelowMinimum => ContractError::BelowMinimum, FungiblesError::DispatchError { index, error } => { ContractError::DispatchError { index, error } @@ -44,6 +53,7 @@ impl From for ContractError { FungiblesError::ModuleError { pallet, error } => { ContractError::ModuleError { pallet, error } }, + FungiblesError::NoAccount => ContractError::NoAccount, FungiblesError::NoPermission => ContractError::NoPermission, FungiblesError::Unknown => ContractError::Unknown, } @@ -68,6 +78,16 @@ mod fungibles { Default::default() } + /// 1. PSP-22 Interface: + /// - total_supply + /// - balance_of + /// - allowance + /// - transfer + /// - transfer_from + /// - approve + /// - increase_allowance + /// - decrease_allowance + #[ink(message)] pub fn total_supply(&self, id: AssetId) -> Result { total_supply(id).map_err(From::from) @@ -89,13 +109,58 @@ mod fungibles { } #[ink(message)] - pub fn asset_exists(&self, id: AssetId) -> Result { - asset_exists(id).map_err(From::from) + pub fn transfer(&self, id: AssetId, to: AccountId32, value: Balance) -> Result<()> { + ink::env::debug_println!( + "PopApiAssetsExample::transfer: id: {:?}, to: {:?} value: {:?}", + id, + to, + value, + ); + + let result = transfer(id, to, value); + ink::env::debug_println!("Result: {:?}", result); + result.map_err(From::from) + } + + #[ink(message)] + pub fn transfer_from( + &self, + id: AssetId, + from: Option, + to: Option, + value: Balance, + // Size needs to be known at compile time or ink's `Vec` + data: Vec, + ) -> Result<()> { + ink::env::debug_println!( + "PopApiAssetsExample::transfer_from: id: {:?}, from: {:?}, to: {:?} value: {:?}", + id, + from, + to, + value, + ); + + let result = transfer_from(id, from, to, value, &data); + ink::env::debug_println!("Result: {:?}", result); + result.map_err(From::from) } + /// 2. PSP-22 Metadata Interface: + /// - token_name + /// - token_symbol + /// - token_decimals + + /// 3. Asset Management: + /// - create + /// - start_destroy + /// - destroy_accounts + /// - destroy_approvals + /// - finish_destroy + /// - set_metadata + /// - clear_metadata + #[ink(message)] pub fn create(&self, id: AssetId, admin: AccountId32, min_balance: Balance) -> Result<()> { - // create(id, admin, min_balance).map_err(From::from) ink::env::debug_println!( "PopApiAssetsExample::create: id: {:?} admin: {:?} min_balance: {:?}", id, @@ -115,7 +180,6 @@ mod fungibles { symbol: Vec, decimals: u8, ) -> Result<()> { - // set_metadata(id, name, symbol, decimals).map_err(From::from) ink::env::debug_println!( "PopApiAssetsExample::set_metadata: id: {:?} name: {:?} symbol: {:?}, decimals: {:?}", id, @@ -129,39 +193,9 @@ mod fungibles { } #[ink(message)] - pub fn mint(&self, id: AssetId, beneficiary: AccountId32, amount: Balance) -> Result<()> { - ink::env::debug_println!( - "PopApiAssetsExample::mint: id: {:?}, beneficiary: {:?} amount: {:?}", - id, - beneficiary, - amount, - ); - - let result = mint(id, beneficiary, amount); - ink::env::debug_println!("Result: {:?}", result); - result.map_err(From::from) + pub fn asset_exists(&self, id: AssetId) -> Result { + asset_exists(id).map_err(From::from) } - - // #[ink(message)] - // pub fn transfer_from( - // id: AssetId, - // from: Option, - // to: Option, - // value: Balance, - // data: [u8], - // ) -> Result<()> { - // ink::env::debug_println!( - // "PopApiAssetsExample::transfer_from: id: {:?}, from: {:?}, to: {:?} value: {:?}", - // id, - // from, - // to, - // value, - // ); - // - // let result = transfer_from(id, from, to, value)?; - // ink::env::debug_println!("Result: {:?}", result); - // result - // } } #[cfg(test)] diff --git a/pop-api/src/lib.rs b/pop-api/src/lib.rs index 014b5a29..be448890 100644 --- a/pop-api/src/lib.rs +++ b/pop-api/src/lib.rs @@ -21,16 +21,11 @@ type MaxTips = u32; pub type Result = core::result::Result; -struct ModuleError { - pallet: u8, - error: u16, -} - #[derive(Debug, Copy, Clone, PartialEq, Eq, scale::Encode, scale::Decode)] #[cfg_attr(feature = "std", derive(scale_info::TypeInfo))] pub enum PopApiError { Assets(assets::fungibles::AssetsError), - Balances(balances::Error), + Balances(balances::BalancesError), Contracts(contracts::Error), DecodingFailed, Nfts(nfts::Error), diff --git a/pop-api/src/v0/assets/fungibles.rs b/pop-api/src/v0/assets/fungibles.rs index de624938..df9033c7 100644 --- a/pop-api/src/v0/assets/fungibles.rs +++ b/pop-api/src/v0/assets/fungibles.rs @@ -1,7 +1,6 @@ use crate::{ - AccountId, Balance, - PopApiError::{UnknownDispatchStatusCode, UnknownModuleStatusCode}, - RuntimeCall, *, + balances::BalancesError, AccountId, Balance, PopApiError::UnknownModuleStatusCode, RuntimeCall, + *, }; use ink::prelude::vec::Vec; use primitives::AssetId; @@ -62,28 +61,6 @@ pub fn allowance(id: AssetId, owner: AccountId, spender: AccountId) -> Result>, min_balance: Balance) -> Result<()> { -pub fn create( - id: AssetId, - admin: impl Into>, - min_balance: Balance, -) -> Result<()> { - Ok(dispatch(RuntimeCall::Assets(AssetsCall::Create { - id: id.into(), - admin: admin.into(), - min_balance, - }))?) -} - /// Transfers `value` amount of tokens from the caller's account to account `to`, with additional /// `data` in unspecified format. /// @@ -94,29 +71,27 @@ pub fn create( /// /// # Returns /// Returns `Ok(())` if successful, or an error if the transfer fails. -// #[allow(unused_variables)] -// pub fn transfer( -// id: AssetId, -// to: impl Into>, -// value: Balance, -// ) -> Result<()> { -// todo!() -// // TODO: transfer or transfer_keep_alive -// // Ok(dispatch(RuntimeCall::Assets(AssetsCall::Transfer { -// // id: id.into(), -// // target: target.into(), -// // amount: Compact(amount), -// // }))?) -// // Ok(dispatch(RuntimeCall::Assets(AssetsCall::TransferKeepAlive { -// // id: id.into(), -// // target: target.into(), -// // amount: Compact(amount), -// // }))?) -// } +pub fn transfer( + id: AssetId, + to: impl Into>, + value: Balance, +) -> Result<()> { + // TODO: transfer or transfer_keep_alive + // Ok(dispatch(RuntimeCall::Assets(AssetsCall::Transfer { + // id: id.into(), + // target: target.into(), + // amount: Compact(amount), + // }))?) + Ok(dispatch(RuntimeCall::Assets(AssetsCall::TransferKeepAlive { + id: id.into(), + target: to.into(), + amount: Compact(value), + }))?) +} -/// Transfers `value` tokens on the behalf of `from` to the account `to` with additional `data` -/// in unspecified format. This can be used to allow a contract to transfer tokens on ones behalf -/// and/or to charge fees in sub-currencies, for example. +/// Transfers `value` tokens on behalf of `from` to account `to` with additional `data` +/// in unspecified format. If `from` is equal to `None`, tokens will be minted to account `to`. If +/// `to` is equal to `None`, tokens will be burned from account `from`. /// /// # Arguments /// * `id` - The ID of the asset. @@ -126,43 +101,26 @@ pub fn create( /// /// # Returns /// Returns `Ok(())` if successful, or an error if the transfer fails. -// pub fn transfer_from( -// id: AssetId, -// from: impl Into>, -// to: impl Into>, -// value: Balance, -// ) -> Result<()> { -//todo!() -// TODO: depending on `from` and `to`, decide whether to mint, burn or transfer_approved. -// Ok(dispatch(RuntimeCall::Assets(AssetsCall::Mint { -// id: id.into(), -// beneficiary: beneficiary.into(), -// amount: Compact(amount), -// }))?) -// Ok(dispatch(RuntimeCall::Assets(AssetsCall::Burn { -// id: id.into(), -// who: who.into(), -// amount: Compact(amount), -// }))?) -// Ok(dispatch(RuntimeCall::Assets(AssetsCall::TransferApproved { -// id: id.into(), -// owner: from.into(), -// destination: to.into(), -// amount: Compact(value), -// }))?) -// } - -/// Mint assets of a particular class. -pub fn mint( +pub fn transfer_from( id: AssetId, - beneficiary: impl Into>, - amount: Balance, + from: Option>>, + to: Option>>, + value: Balance, + _data: &[u8], ) -> Result<()> { - Ok(dispatch(RuntimeCall::Assets(AssetsCall::Mint { - id: id.into(), - beneficiary: beneficiary.into(), - amount: Compact(amount), - }))?) + match (from, to) { + (None, Some(to)) => mint(id, to, value), + // (Some(from), None) => burn(id, from, value), + (Some(from), Some(to)) => { + Ok(dispatch(RuntimeCall::Assets(AssetsCall::TransferApproved { + id: id.into(), + owner: from.into(), + destination: to.into(), + amount: Compact(value), + }))?) + }, + _ => Ok(()), + } } /// Approves an account to spend a specified number of tokens on behalf of the caller. @@ -277,6 +235,27 @@ pub fn mint( /// - set_metadata /// - clear_metadata +/// Create a new token with a given asset ID. +/// +/// # Arguments +/// * `id` - The ID of the asset. +/// * `admin` - The account that will administer the asset. +/// * `min_balance` - The minimum balance required for accounts holding this asset. +/// +/// # Returns +/// Returns `Ok(())` if successful, or an error if the creation fails. +pub fn create( + id: AssetId, + admin: impl Into>, + min_balance: Balance, +) -> Result<()> { + Ok(dispatch(RuntimeCall::Assets(AssetsCall::Create { + id: id.into(), + admin: admin.into(), + min_balance, + }))?) +} + /// Start the process of destroying a token with a given asset ID. /// /// # Arguments @@ -362,10 +341,22 @@ pub fn asset_exists(id: AssetId) -> Result { Ok(state::read(RuntimeStateKeys::Assets(AssetsKeys::AssetExists(id)))?) } -// Parameters to extrinsics representing an asset id (`AssetIdParameter`) and a balance amount (`Balance`) are expected -// to be compact encoded. The pop api handles that for the developer. -// -// reference: https://substrate.stackexchange.com/questions/1873/what-is-the-meaning-of-palletcompact-in-pallet-development +/// Mint assets of a particular class. +fn mint( + id: AssetId, + beneficiary: impl Into>, + amount: Balance, +) -> Result<()> { + Ok(dispatch(RuntimeCall::Assets(AssetsCall::Mint { + id: id.into(), + beneficiary: beneficiary.into(), + amount: Compact(amount), + }))?) +} + +// Parameters to extrinsics representing an asset id (`AssetIdParameter`) and a balance amount +// (`Balance`) are expected to be compact encoded. The pop api handles that for the developer. +// https://substrate.stackexchange.com/questions/1873/what-is-the-meaning-of-palletcompact-in-pallet-development // // Asset id that is compact encoded. type AssetIdParameter = Compact; @@ -423,7 +414,6 @@ pub(crate) enum AssetsCall { }, } -// TODO: remove unnecessary errors #[derive(Debug, Copy, Clone, PartialEq, Eq, Encode, scale::Decode)] #[cfg_attr(feature = "std", derive(scale_info::TypeInfo))] pub(crate) enum AssetsError { @@ -514,6 +504,8 @@ impl TryFrom for AssetsError { #[derive(Debug, Copy, Clone, PartialEq, Eq, Encode, scale::Decode)] #[cfg_attr(feature = "std", derive(scale_info::TypeInfo))] pub enum FungiblesError { + /// The asset is not live; either frozen or being destroyed. + AssetNotLive, /// The amount to mint is less than the existential deposit. BelowMinimum, /// Unspecified dispatch error, providing the index and its error index (if none `0`). @@ -528,16 +520,20 @@ pub enum FungiblesError { MinBalanceZero, /// Unspecified pallet error, providing pallet index and error index. ModuleError { pallet: u8, error: u16 }, + /// The account to alter does not exist. + NoAccount, /// The signing account has no permission to do the operation. NoPermission, /// The given asset ID is unknown. Unknown, } -impl From for FungiblesError { - fn from(error: balances::Error) -> Self { +impl From for FungiblesError { + fn from(error: BalancesError) -> Self { match error { - balances::Error::InsufficientBalance => FungiblesError::InsufficientBalance, + // TODO: this insufficient balance is different than the assets variant. This one is + // for a deposit of creating an asset, the latter is for transfer tokens. + BalancesError::InsufficientBalance => FungiblesError::InsufficientBalance, _ => FungiblesError::ModuleError { pallet: 40, error: error as u16 }, } } @@ -546,8 +542,10 @@ impl From for FungiblesError { impl From for FungiblesError { fn from(error: dispatch_error::TokenError) -> Self { match error { - dispatch_error::TokenError::UnknownAsset => FungiblesError::Unknown, dispatch_error::TokenError::BelowMinimum => FungiblesError::BelowMinimum, + // ED is not respected. + dispatch_error::TokenError::OnlyProvider => FungiblesError::InsufficientBalance, + dispatch_error::TokenError::UnknownAsset => FungiblesError::Unknown, _ => FungiblesError::DispatchError { index: 7, error: error as u8 }, } } @@ -556,12 +554,15 @@ impl From for FungiblesError { impl From for FungiblesError { fn from(error: AssetsError) -> Self { match error { + AssetsError::AssetNotLive => FungiblesError::AssetNotLive, + AssetsError::BalanceLow => FungiblesError::InsufficientBalance, AssetsError::Unapproved => FungiblesError::InsufficientAllowance, AssetsError::InUse => FungiblesError::InUse, AssetsError::MinBalanceZero => FungiblesError::MinBalanceZero, AssetsError::NoPermission => FungiblesError::NoPermission, + AssetsError::NoAccount => FungiblesError::NoAccount, AssetsError::Unknown => FungiblesError::Unknown, - _ => FungiblesError::ModuleError { pallet: 40, error: error as u16 }, + _ => FungiblesError::ModuleError { pallet: 52, error: error as u16 }, } } } @@ -586,3 +587,24 @@ impl From for FungiblesError { } } } + +// macro_rules! impl_error_conversion { +// ($pallet_index:, $pallet_error:ty, $interface_error:ty, $($variant:ident),*) => { +// impl From<$pallet_error> for $interface_error { +// fn from(error: $pallet_error) -> Self { +// match error { +// $( +// <$pallet_error>::$variant => <$interface_error>::$variant, +// )* +// _ => <$interface_error>::ModuleError { pallet: 0, error: [255, 0, 0, 0] }, // Default case +// } +// } +// } +// +// impl FromPalletError<$pallet_error> for $interface_error { +// fn from_pallet_error(error: $pallet_error) -> Self { +// Self::from(error) +// } +// } +// }; +// } diff --git a/pop-api/src/v0/balances.rs b/pop-api/src/v0/balances.rs index bc422ef4..08db0a75 100644 --- a/pop-api/src/v0/balances.rs +++ b/pop-api/src/v0/balances.rs @@ -3,7 +3,7 @@ use crate::{ PopApiError::UnknownModuleStatusCode, }; -type Result = core::result::Result; +type Result = core::result::Result; pub fn transfer_keep_alive( dest: impl Into>, @@ -28,7 +28,7 @@ pub(crate) enum BalancesCall { #[derive(Debug, Copy, Clone, PartialEq, Eq, scale::Encode, scale::Decode)] #[cfg_attr(feature = "std", derive(scale_info::TypeInfo))] -pub(crate) enum Error { +pub(crate) enum BalancesError { /// Vesting balance too high to send value. VestingBalance, /// Account liquidity restrictions prevent withdrawal. @@ -55,11 +55,11 @@ pub(crate) enum Error { DeltaZero, } -impl TryFrom for Error { +impl TryFrom for BalancesError { type Error = PopApiError; fn try_from(status_code: u32) -> core::result::Result { - use Error::*; + use BalancesError::*; match status_code { 0 => Ok(VestingBalance), 1 => Ok(LiquidityRestrictions), @@ -78,7 +78,7 @@ impl TryFrom for Error { } } -impl From for Error { +impl From for BalancesError { fn from(error: PopApiError) -> Self { match error { PopApiError::Balances(e) => e, diff --git a/runtime/devnet/src/extensions/tests/local_fungibles.rs b/runtime/devnet/src/extensions/tests/local_fungibles.rs index 5bd7dac0..5de162c9 100644 --- a/runtime/devnet/src/extensions/tests/local_fungibles.rs +++ b/runtime/devnet/src/extensions/tests/local_fungibles.rs @@ -1,10 +1,11 @@ #![cfg(test)] use super::*; -use pallet_contracts::debug::ExecResult; #[derive(Decode, Encode, Debug, Eq, PartialEq)] enum FungiblesError { + /// The asset is not live; either frozen or being destroyed. + AssetNotLive, /// The amount to mint is less than the existential deposit. BelowMinimum, /// Unspecified dispatch error, providing the index and optionally its error index. @@ -19,13 +20,15 @@ enum FungiblesError { MinBalanceZero, /// Unspecified pallet error, providing pallet index and error index. ModuleError { pallet: u8, error: u16 }, + /// The account to alter does not exist. + NoAccount, /// The signing account has no permission to do the operation. NoPermission, /// The given asset ID is unknown. Unknown, } -const ASSET_ID: u32 = 1; +const ASSET_ID: AssetId = 1; fn decoded(result: ExecReturnValue) -> T { ::decode(&mut &result.data[2..]).unwrap() @@ -33,39 +36,42 @@ fn decoded(result: ExecReturnValue) -> T { fn allowance( addr: AccountId32, - asset_id: u32, + asset_id: AssetId, owner: AccountId32, spender: AccountId32, -) -> ExecReturnValue { +) -> Balance { let function = function_selector("allowance"); let params = [function, asset_id.encode(), owner.encode(), spender.encode()].concat(); - do_bare_call(addr, params, 0).expect("should work") + let result = do_bare_call(addr, params, 0).expect("should work"); + decoded::(result) } // Call balance_of contract message. -fn balance_of(addr: AccountId32, asset_id: u32, owner: AccountId32) -> ExecReturnValue { +fn balance_of(addr: AccountId32, asset_id: AssetId, owner: AccountId32) -> Balance { let function = function_selector("balance_of"); let params = [function, asset_id.encode(), owner.encode()].concat(); - do_bare_call(addr, params, 0).expect("should work") + let result = do_bare_call(addr, params, 0).expect("should work"); + decoded::(result) } // Call total_supply contract message. -fn total_supply(addr: AccountId32, asset_id: u32) -> Balance { +fn total_supply(addr: AccountId32, asset_id: AssetId) -> Balance { let function = function_selector("total_supply"); let params = [function, asset_id.encode()].concat(); let result = do_bare_call(addr, params, 0).expect("should work"); decoded::(result) } -fn asset_exists(addr: AccountId32, asset_id: u32) -> ExecReturnValue { +fn asset_exists(addr: AccountId32, asset_id: AssetId) -> bool { let function = function_selector("asset_exists"); let params = [function, asset_id.encode()].concat(); - do_bare_call(addr, params, 0).expect("should work") + let result = do_bare_call(addr, params, 0).expect("should work"); + decoded::(result) } fn create( addr: AccountId32, - asset_id: u32, + asset_id: AssetId, admin: AccountId32, min_balance: Balance, ) -> ExecReturnValue { @@ -76,7 +82,7 @@ fn create( fn set_metadata( addr: AccountId32, - asset_id: u32, + asset_id: AssetId, name: Vec, symbol: Vec, decimals: u8, @@ -87,26 +93,34 @@ fn set_metadata( do_bare_call(addr, params, 0).expect("should work") } +fn transfer( + addr: AccountId32, + asset_id: AssetId, + to: AccountId32, + value: Balance, +) -> ExecReturnValue { + let function = function_selector("transfer"); + let params = [function, asset_id.encode(), to.encode(), value.encode()].concat(); + do_bare_call(addr, params, 0).expect("should work") +} + fn transfer_from( addr: AccountId32, - asset_id: u32, - _from: Option, + asset_id: AssetId, + from: Option, to: Option, value: Balance, - _data: &[u8], + data: &[u8], ) -> ExecReturnValue { - // let function = function_selector("transfer_from"); - // let params = - // [function, asset_id.encode(), from.encode(), to.encode(), value.encode(), data.encode()] - // .concat(); - // do_bare_call(addr, params, 0) - let function = function_selector("mint"); - let params = [function, asset_id.encode(), to.unwrap().encode(), value.encode()].concat(); + let function = function_selector("transfer_from"); + let params = + [function, asset_id.encode(), from.encode(), to.encode(), value.encode(), data.encode()] + .concat(); do_bare_call(addr, params, 0).expect("should work") } // Create an asset and mint to owner. -fn create_asset(asset_id: u32, owner: AccountId32, min_balance: Balance) { +fn create_asset(asset_id: AssetId, owner: AccountId32, min_balance: Balance) -> AssetId { assert_eq!( Assets::create( RuntimeOrigin::signed(owner.clone()), @@ -116,20 +130,27 @@ fn create_asset(asset_id: u32, owner: AccountId32, min_balance: Balance) { ), Ok(()) ); + asset_id } // Create an asset and mint to owner. -fn create_asset_and_mint_to(asset_id: u32, owner: AccountId32, to: AccountId32, value: Balance) { +fn create_asset_and_mint_to( + asset_id: AssetId, + owner: AccountId32, + to: AccountId32, + value: Balance, +) -> AssetId { create_asset(asset_id, owner.clone(), 1); assert_eq!( Assets::mint(RuntimeOrigin::signed(owner.into()), asset_id.into(), to.into(), value,), Ok(()) ); + asset_id } // Create an asset, mints to, and approves spender. fn create_asset_mint_and_approve( - asset_id: u32, + asset_id: AssetId, owner: AccountId32, to: AccountId32, mint: Balance, @@ -148,6 +169,21 @@ fn create_asset_mint_and_approve( ); } +// Freeze an asset. +fn freeze_asset(asset_id: AssetId, owner: AccountId32) { + assert_eq!(Assets::freeze_asset(RuntimeOrigin::signed(owner.into()), asset_id.into()), Ok(())); +} + +// Thaw an asset. +fn thaw_asset(asset_id: AssetId, owner: AccountId32) { + assert_eq!(Assets::thaw_asset(RuntimeOrigin::signed(owner.into()), asset_id.into()), Ok(())); +} + +// Start destroying an asset. +fn start_destroy_asset(asset_id: AssetId, owner: AccountId32) { + assert_eq!(Assets::start_destroy(RuntimeOrigin::signed(owner.into()), asset_id.into()), Ok(())); +} + #[test] #[ignore] fn total_supply_works() { @@ -180,17 +216,11 @@ fn balance_of_works() { ); // No tokens in circulation. - assert_eq!( - Assets::balance(ASSET_ID, BOB).encode(), - balance_of(addr.clone(), ASSET_ID, BOB).data[2..] - ); + assert_eq!(Assets::balance(ASSET_ID, BOB), balance_of(addr.clone(), ASSET_ID, BOB)); // Tokens in circulation. create_asset_and_mint_to(ASSET_ID, addr.clone(), BOB, 100); - assert_eq!( - Assets::balance(ASSET_ID, BOB).encode(), - balance_of(addr, ASSET_ID, BOB).data[2..] - ); + assert_eq!(Assets::balance(ASSET_ID, BOB), balance_of(addr, ASSET_ID, BOB)); }); } @@ -207,15 +237,15 @@ fn allowance_works() { // No tokens in circulation. assert_eq!( - Assets::allowance(ASSET_ID, &BOB, &ALICE).encode(), - allowance(addr.clone(), ASSET_ID, BOB, ALICE).data[2..] + Assets::allowance(ASSET_ID, &BOB, &ALICE), + allowance(addr.clone(), ASSET_ID, BOB, ALICE) ); // Tokens in circulation. create_asset_mint_and_approve(ASSET_ID, addr.clone(), BOB, 100, ALICE, 50); assert_eq!( - Assets::allowance(ASSET_ID, &BOB, &ALICE).encode(), - allowance(addr, ASSET_ID, BOB, ALICE).data[2..] + Assets::allowance(ASSET_ID, &BOB, &ALICE), + allowance(addr, ASSET_ID, BOB, ALICE) ); }); } @@ -232,14 +262,11 @@ fn asset_exists_works() { ); // No tokens in circulation. - assert_eq!( - Assets::asset_exists(ASSET_ID).encode(), - asset_exists(addr.clone(), ASSET_ID).data[2..] - ); + assert_eq!(Assets::asset_exists(ASSET_ID), asset_exists(addr.clone(), ASSET_ID)); // Tokens in circulation. create_asset(ASSET_ID, addr.clone(), 1); - assert_eq!(Assets::asset_exists(ASSET_ID).encode(), asset_exists(addr, ASSET_ID).data[2..]); + assert_eq!(Assets::asset_exists(ASSET_ID), asset_exists(addr, ASSET_ID)); }); } @@ -299,11 +326,12 @@ fn set_metadata_works() { } // todo: errors: -// - AssetNotLive: when frozen or being destroyed -// - TokenErrors: https://github.com/paritytech/polkadot-sdk/blob/3977f389cce4a00fd7100f95262e0563622b9aa4/substrate/frame/assets/src/functions.rs#L125 +// - TokenErrors +// - Arithmetic +// - https://github.com/paritytech/polkadot-sdk/blob/3977f389cce4a00fd7100f95262e0563622b9aa4/substrate/frame/assets/src/functions.rs#L125 #[test] #[ignore] -fn mint_works() { +fn transfer_from_mint_works() { new_test_ext().execute_with(|| { let _ = env_logger::try_init(); let addr = instantiate( @@ -316,7 +344,7 @@ fn mint_works() { assert_eq!( decoded::(transfer_from( addr.clone(), - ASSET_ID, + 1, None, Some(BOB), amount, @@ -324,11 +352,11 @@ fn mint_works() { )), FungiblesError::Unknown ); - create_asset(ASSET_ID, ALICE, 2); + let asset = create_asset(1, ALICE, 2); assert_eq!( decoded::(transfer_from( addr.clone(), - ASSET_ID, + asset, None, Some(BOB), amount, @@ -339,7 +367,7 @@ fn mint_works() { assert_eq!( decoded::(transfer_from( addr.clone(), - ASSET_ID, + asset, None, Some(BOB), 1, @@ -347,16 +375,87 @@ fn mint_works() { )), FungiblesError::BelowMinimum ); - let asset = 2; - create_asset(asset, addr.clone(), 2); + let asset = create_asset(2, addr.clone(), 2); + freeze_asset(asset, addr.clone()); + assert_eq!( + decoded::(transfer_from( + addr.clone(), + asset, + None, + Some(BOB), + amount, + &[0u8] + )), + FungiblesError::AssetNotLive + ); + thaw_asset(asset, addr.clone()); let bob_balance_before_mint = Assets::balance(asset, &BOB); - let result = transfer_from(addr.clone(), asset, None, Some(BOB), 100 * UNIT, &[0u8]); + let result = transfer_from(addr.clone(), asset, None, Some(BOB), amount, &[0u8]); assert!(!result.did_revert(), "Contract reverted!"); let bob_balance_after_mint = Assets::balance(asset, &BOB); assert_eq!(bob_balance_after_mint, bob_balance_before_mint + amount); + start_destroy_asset(asset, addr.clone()); + assert_eq!( + decoded::(transfer_from( + addr.clone(), + asset, + None, + Some(BOB), + amount, + &[0u8] + )), + FungiblesError::AssetNotLive + ); }); } +// Todo: error: +// - Frozen: account is frozen, who do you freeze an account? +// - https://github.com/paritytech/polkadot-sdk/blob/2460cddf57660a88844d201f769eb17a7accce5a/substrate/frame/assets/src/functions.rs#L161 +// - ArithmeticError: Underflow, Overflow +// - https://github.com/paritytech/polkadot-sdk/blob/master/substrate/frame/assets/src/functions.rs#L125 +// - #[test] #[ignore] -fn transfer_works() {} +fn transfer_works() { + new_test_ext().execute_with(|| { + let _ = env_logger::try_init(); + let addr = instantiate( + "../../pop-api/examples/fungibles/target/ink/fungibles.wasm", + INIT_VALUE, + vec![], + ); + let amount: Balance = 100 * UNIT; + + assert_eq!( + decoded::(transfer(addr.clone(), 1, BOB, amount,)), + FungiblesError::Unknown + ); + let asset = create_asset_and_mint_to(1, ALICE, addr.clone(), amount); + freeze_asset(asset, ALICE); + assert_eq!( + decoded::(transfer(addr.clone(), asset, BOB, amount,)), + FungiblesError::AssetNotLive + ); + thaw_asset(asset, ALICE); + assert_eq!( + decoded::(transfer(addr.clone(), asset, BOB, amount + 1 * UNIT)), + FungiblesError::InsufficientBalance + ); + // Errors due to ED. Could be Belowminimum + assert_eq!( + decoded::(transfer(addr.clone(), asset, BOB, amount)), + FungiblesError::InsufficientBalance + ); + let bob_balance_before_mint = Assets::balance(asset, &BOB); + let result = transfer(addr.clone(), asset, BOB, amount / 2); + assert!(!result.did_revert(), "Contract reverted!"); + let bob_balance_after_mint = Assets::balance(asset, &BOB); + assert_eq!(bob_balance_after_mint, bob_balance_before_mint + amount / 2); + start_destroy_asset(asset, ALICE); + assert_eq!( + decoded::(transfer(addr.clone(), asset, BOB, amount / 4)), + FungiblesError::AssetNotLive + ); + }); +} diff --git a/runtime/devnet/src/extensions/tests/mod.rs b/runtime/devnet/src/extensions/tests/mod.rs index 03cda2cd..cbd13d62 100644 --- a/runtime/devnet/src/extensions/tests/mod.rs +++ b/runtime/devnet/src/extensions/tests/mod.rs @@ -7,6 +7,7 @@ use sp_runtime::{traits::Hash, AccountId32, BuildStorage}; mod local_fungibles; type Balance = u128; +type AssetId = u32; const DEBUG_OUTPUT: pallet_contracts::DebugInfo = pallet_contracts::DebugInfo::UnsafeDebug; const ALICE: AccountId32 = AccountId32::new([1_u8; 32]); From ecc82e266d772bbe6d57b3feb9049e3228152f8a Mon Sep 17 00:00:00 2001 From: Daanvdplas Date: Thu, 6 Jun 2024 11:51:10 +0200 Subject: [PATCH 006/112] chore: remove polkadot launch --- polkadot-launch/config.json | 39 ------------------------------------- 1 file changed, 39 deletions(-) delete mode 100644 polkadot-launch/config.json diff --git a/polkadot-launch/config.json b/polkadot-launch/config.json deleted file mode 100644 index f03f983a..00000000 --- a/polkadot-launch/config.json +++ /dev/null @@ -1,39 +0,0 @@ -{ - "relaychain": { - "bin": "../../polkadot/target/release/polkadot", - "chain": "rococo-local", - "nodes": [ - { - "name": "alice", - "wsPort": 9944, - "port": 30444 - }, - { - "name": "bob", - "wsPort": 9955, - "port": 30555 - } - ] - }, - "parachains": [ - { - "bin": "../target/release/polkadot-parachain", - "id": "200", - "balance": "1000000000000000000000", - "nodes": [ - { - "wsPort": 9988, - "name": "alice", - "port": 31200, - "flags": [ - "--force-authoring", - "--", - "--execution=wasm" - ] - } - ] - } - ], - "types": { - } -} From e81f78a957ff3773bc45e93a61f8bf3c17538bc0 Mon Sep 17 00:00:00 2001 From: Daanvdplas Date: Thu, 6 Jun 2024 14:04:31 +0200 Subject: [PATCH 007/112] # This is a combination of 8 commits. # This is the 1st commit message: refactor: general # This is the commit message #2: init # This is the commit message #3: begin refactor # This is the commit message #4: refactor: error handling # This is the commit message #5: tests: add error handling tests # This is the commit message #6: WIP # This is the commit message #7: finalise error handling # This is the commit message #8: refactor: easier review --- Cargo.lock | 2723 ++++++++++------ pop-api/examples/fungibles/expanded.rs | 2766 ----------------- pop-api/examples/fungibles/lib.rs | 94 +- pop-api/src/error.rs | 255 ++ pop-api/src/lib.rs | 58 +- pop-api/src/v0/assets/fungibles.rs | 610 ---- pop-api/src/v0/assets/mod.rs | 3 +- pop-api/src/v0/assets/pallets/assets.rs | 491 +++ pop-api/src/v0/assets/pallets/mod.rs | 1 + pop-api/src/v0/assets/use_cases/fungibles.rs | 372 +++ pop-api/src/v0/assets/use_cases/mod.rs | 1 + pop-api/src/v0/balances.rs | 21 +- pop-api/src/v0/contracts.rs | 152 - pop-api/src/v0/cross_chain/mod.rs | 15 +- pop-api/src/v0/dispatch_error.rs | 57 - pop-api/src/v0/mod.rs | 4 +- pop-api/src/v0/nfts.rs | 15 +- primitives/src/storage_keys.rs | 3 - runtime/devnet/Cargo.toml | 2 + .../src/{extensions/mod.rs => extensions.rs} | 45 +- runtime/devnet/src/extensions/tests/mod.rs | 89 - runtime/devnet/src/lib.rs | 2 + .../{extensions => }/tests/local_fungibles.rs | 199 +- runtime/devnet/src/tests/mod.rs | 262 ++ 24 files changed, 3335 insertions(+), 4905 deletions(-) delete mode 100644 pop-api/examples/fungibles/expanded.rs create mode 100644 pop-api/src/error.rs delete mode 100644 pop-api/src/v0/assets/fungibles.rs create mode 100644 pop-api/src/v0/assets/pallets/assets.rs create mode 100644 pop-api/src/v0/assets/pallets/mod.rs create mode 100644 pop-api/src/v0/assets/use_cases/fungibles.rs create mode 100644 pop-api/src/v0/assets/use_cases/mod.rs delete mode 100644 pop-api/src/v0/contracts.rs delete mode 100644 pop-api/src/v0/dispatch_error.rs rename runtime/devnet/src/{extensions/mod.rs => extensions.rs} (97%) delete mode 100644 runtime/devnet/src/extensions/tests/mod.rs rename runtime/devnet/src/{extensions => }/tests/local_fungibles.rs (70%) create mode 100644 runtime/devnet/src/tests/mod.rs diff --git a/Cargo.lock b/Cargo.lock index 17cc70e5..77c563fb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -343,7 +343,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94893f1e0c6eeab764ade8dc4c0db24caf4fe7cbbaafc0eba0a9030f447b5185" dependencies = [ "num-traits", - "rand", + "rand 0.8.5", ] [[package]] @@ -358,6 +358,12 @@ version = "6.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6f840fb7195bcfc5e17ea40c26e5ce6d5b9ce5d584466e17703209657e459ae0" +[[package]] +name = "array-init" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d62b7694a562cdf5a74227903507c56ab2cc8bdd1f781ed5cb4cf9c9f810bfc" + [[package]] name = "arrayref" version = "0.3.7" @@ -373,6 +379,12 @@ dependencies = [ "nodrop", ] +[[package]] +name = "arrayvec" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" + [[package]] name = "arrayvec" version = "0.7.4" @@ -404,7 +416,7 @@ dependencies = [ "proc-macro2", "quote", "syn 1.0.109", - "synstructure", + "synstructure 0.12.6", ] [[package]] @@ -486,17 +498,17 @@ dependencies = [ "sp-api", "sp-block-builder", "sp-consensus-aura", - "sp-core", + "sp-core 29.0.0", "sp-genesis-builder", "sp-inherents", "sp-offchain", - "sp-runtime", + "sp-runtime 32.0.0", "sp-session", - "sp-std", - "sp-storage", + "sp-std 14.0.0", + "sp-storage 20.0.0", "sp-transaction-pool", "sp-version", - "sp-weights", + "sp-weights 28.0.0", "staging-parachain-info", "staging-xcm", "staging-xcm-builder", @@ -525,9 +537,9 @@ dependencies = [ "parachains-common", "parachains-runtimes-test-utils", "parity-scale-codec", - "sp-io", - "sp-runtime", - "sp-std", + "sp-io 31.0.0", + "sp-runtime 32.0.0", + "sp-std 14.0.0", "staging-parachain-info", "staging-xcm", "staging-xcm-builder", @@ -551,8 +563,8 @@ dependencies = [ "parity-scale-codec", "scale-info", "sp-api", - "sp-runtime", - "sp-std", + "sp-runtime 32.0.0", + "sp-std 14.0.0", "staging-xcm", "staging-xcm-builder", "staging-xcm-executor", @@ -909,7 +921,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "93f2635620bf0b9d4576eb7bb9a38a55df78bd1205d26fa994b25911a69f212f" dependencies = [ "bitcoin_hashes", - "rand", + "rand 0.8.5", "rand_core 0.6.4", "serde", "unicode-normalization", @@ -1012,6 +1024,18 @@ dependencies = [ "constant_time_eq 0.3.0", ] +[[package]] +name = "block-buffer" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0940dc441f31689269e10ac70eb1002a3a1d3ad1390e030043662eb7fe4688b" +dependencies = [ + "block-padding", + "byte-tools", + "byteorder", + "generic-array 0.12.4", +] + [[package]] name = "block-buffer" version = "0.9.0" @@ -1030,6 +1054,15 @@ dependencies = [ "generic-array 0.14.7", ] +[[package]] +name = "block-padding" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa79dedbb091f449f1f39e53edf88d5dbe95f895dae6135a8d7b881fb5af73f5" +dependencies = [ + "byte-tools", +] + [[package]] name = "blocking" version = "1.5.1" @@ -1116,7 +1149,7 @@ dependencies = [ "frame-system", "polkadot-primitives", "sp-api", - "sp-std", + "sp-std 14.0.0", ] [[package]] @@ -1130,8 +1163,8 @@ dependencies = [ "bp-runtime", "frame-support", "sp-api", - "sp-runtime", - "sp-std", + "sp-runtime 32.0.0", + "sp-std 14.0.0", ] [[package]] @@ -1145,8 +1178,8 @@ dependencies = [ "bp-runtime", "frame-support", "sp-api", - "sp-runtime", - "sp-std", + "sp-runtime 32.0.0", + "sp-std 14.0.0", ] [[package]] @@ -1162,9 +1195,9 @@ dependencies = [ "scale-info", "serde", "sp-consensus-grandpa", - "sp-core", - "sp-runtime", - "sp-std", + "sp-core 29.0.0", + "sp-runtime 32.0.0", + "sp-std 14.0.0", ] [[package]] @@ -1179,8 +1212,8 @@ dependencies = [ "parity-scale-codec", "scale-info", "serde", - "sp-core", - "sp-std", + "sp-core 29.0.0", + "sp-std 14.0.0", ] [[package]] @@ -1196,9 +1229,9 @@ dependencies = [ "impl-trait-for-tuples", "parity-scale-codec", "scale-info", - "sp-core", - "sp-runtime", - "sp-std", + "sp-core 29.0.0", + "sp-runtime 32.0.0", + "sp-std 14.0.0", ] [[package]] @@ -1215,9 +1248,9 @@ dependencies = [ "parity-util-mem", "scale-info", "serde", - "sp-core", - "sp-runtime", - "sp-std", + "sp-core 29.0.0", + "sp-runtime 32.0.0", + "sp-std 14.0.0", ] [[package]] @@ -1231,8 +1264,8 @@ dependencies = [ "frame-support", "parity-scale-codec", "scale-info", - "sp-runtime", - "sp-std", + "sp-runtime 32.0.0", + "sp-std 14.0.0", ] [[package]] @@ -1250,13 +1283,13 @@ dependencies = [ "parity-scale-codec", "scale-info", "serde", - "sp-core", - "sp-io", - "sp-runtime", - "sp-state-machine", - "sp-std", - "sp-trie", - "trie-db", + "sp-core 29.0.0", + "sp-io 31.0.0", + "sp-runtime 32.0.0", + "sp-state-machine 0.36.0", + "sp-std 14.0.0", + "sp-trie 30.0.0", + "trie-db 0.28.0", ] [[package]] @@ -1269,15 +1302,15 @@ dependencies = [ "bp-parachains", "bp-polkadot-core", "bp-runtime", - "ed25519-dalek", + "ed25519-dalek 2.1.1", "finality-grandpa", "parity-scale-codec", - "sp-application-crypto", + "sp-application-crypto 31.0.0", "sp-consensus-grandpa", - "sp-core", - "sp-runtime", - "sp-std", - "sp-trie", + "sp-core 29.0.0", + "sp-runtime 32.0.0", + "sp-std 14.0.0", + "sp-trie 30.0.0", ] [[package]] @@ -1286,7 +1319,7 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6663e0179d475e30cfcf28cf597cdc8f4bb1c2c39a557b4cbe0057db0657fb67" dependencies = [ - "sp-std", + "sp-std 14.0.0", ] [[package]] @@ -1297,8 +1330,8 @@ checksum = "86ff4abe93be7bc1663adc41817b1aa3476fbec953ce361537419924310d5dd4" dependencies = [ "parity-scale-codec", "scale-info", - "sp-core", - "sp-runtime", + "sp-core 29.0.0", + "sp-runtime 32.0.0", ] [[package]] @@ -1328,11 +1361,11 @@ dependencies = [ "parity-scale-codec", "scale-info", "sp-api", - "sp-core", - "sp-io", - "sp-runtime", - "sp-std", - "sp-trie", + "sp-core 29.0.0", + "sp-io 31.0.0", + "sp-runtime 32.0.0", + "sp-std 14.0.0", + "sp-trie 30.0.0", "staging-xcm", "staging-xcm-builder", ] @@ -1745,6 +1778,26 @@ dependencies = [ "tiny-keccak", ] +[[package]] +name = "const_env" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e9e4f72c6e3398ca6da372abd9affd8f89781fe728869bbf986206e9af9627e" +dependencies = [ + "const_env_impl", +] + +[[package]] +name = "const_env_impl" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a4f51209740b5e1589e702b3044cdd4562cef41b6da404904192ffffb852d62" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "constant_time_eq" version = "0.1.5" @@ -2044,8 +2097,8 @@ dependencies = [ "sc-client-api", "sc-service", "sp-blockchain", - "sp-core", - "sp-runtime", + "sp-core 29.0.0", + "sp-runtime 32.0.0", "url", ] @@ -2068,8 +2121,8 @@ dependencies = [ "sc-client-api", "sp-api", "sp-consensus", - "sp-core", - "sp-runtime", + "sp-core 29.0.0", + "sp-runtime 32.0.0", "tracing", ] @@ -2101,16 +2154,16 @@ dependencies = [ "sc-telemetry", "schnellru", "sp-api", - "sp-application-crypto", + "sp-application-crypto 31.0.0", "sp-block-builder", "sp-blockchain", "sp-consensus", "sp-consensus-aura", - "sp-core", + "sp-core 29.0.0", "sp-inherents", - "sp-keystore", - "sp-runtime", - "sp-state-machine", + "sp-keystore 0.35.0", + "sp-runtime 32.0.0", + "sp-state-machine 0.36.0", "sp-timestamp", "substrate-prometheus-endpoint", "tracing", @@ -2138,10 +2191,10 @@ dependencies = [ "sp-blockchain", "sp-consensus", "sp-consensus-slots", - "sp-core", - "sp-runtime", + "sp-core 29.0.0", + "sp-runtime 32.0.0", "sp-timestamp", - "sp-trie", + "sp-trie 30.0.0", "substrate-prometheus-endpoint", "tracing", ] @@ -2157,8 +2210,8 @@ dependencies = [ "cumulus-primitives-parachain-inherent", "sp-consensus", "sp-inherents", - "sp-runtime", - "sp-state-machine", + "sp-runtime 32.0.0", + "sp-state-machine 0.36.0", "thiserror", ] @@ -2180,9 +2233,9 @@ dependencies = [ "sc-client-api", "sp-blockchain", "sp-consensus", - "sp-core", - "sp-runtime", - "sp-state-machine", + "sp-core 29.0.0", + "sp-runtime 32.0.0", + "sp-state-machine 0.36.0", "tracing", ] @@ -2203,11 +2256,11 @@ dependencies = [ "sp-api", "sp-crypto-hashing", "sp-inherents", - "sp-runtime", - "sp-state-machine", - "sp-std", - "sp-storage", - "sp-trie", + "sp-runtime 32.0.0", + "sp-state-machine 0.36.0", + "sp-std 14.0.0", + "sp-storage 20.0.0", + "sp-trie 30.0.0", "tracing", ] @@ -2227,12 +2280,12 @@ dependencies = [ "polkadot-node-subsystem", "polkadot-overseer", "polkadot-primitives", - "rand", + "rand 0.8.5", "sc-client-api", "sc-consensus", "sp-consensus", "sp-maybe-compressed-blob", - "sp-runtime", + "sp-runtime 32.0.0", "tracing", ] @@ -2268,8 +2321,8 @@ dependencies = [ "sp-api", "sp-blockchain", "sp-consensus", - "sp-core", - "sp-runtime", + "sp-core 29.0.0", + "sp-runtime 32.0.0", "sp-transaction-pool", ] @@ -2286,10 +2339,10 @@ dependencies = [ "pallet-timestamp", "parity-scale-codec", "scale-info", - "sp-application-crypto", + "sp-application-crypto 31.0.0", "sp-consensus-aura", - "sp-runtime", - "sp-std", + "sp-runtime 32.0.0", + "sp-std 14.0.0", ] [[package]] @@ -2315,17 +2368,17 @@ dependencies = [ "polkadot-runtime-common", "polkadot-runtime-parachains", "scale-info", - "sp-core", - "sp-externalities", + "sp-core 29.0.0", + "sp-externalities 0.26.0", "sp-inherents", - "sp-io", - "sp-runtime", - "sp-state-machine", - "sp-std", - "sp-trie", + "sp-io 31.0.0", + "sp-runtime 32.0.0", + "sp-state-machine 0.36.0", + "sp-std 14.0.0", + "sp-trie 30.0.0", "sp-version", "staging-xcm", - "trie-db", + "trie-db 0.28.0", ] [[package]] @@ -2351,8 +2404,8 @@ dependencies = [ "frame-system", "pallet-session", "parity-scale-codec", - "sp-runtime", - "sp-std", + "sp-runtime 32.0.0", + "sp-std 14.0.0", ] [[package]] @@ -2366,9 +2419,9 @@ dependencies = [ "frame-system", "parity-scale-codec", "scale-info", - "sp-io", - "sp-runtime", - "sp-std", + "sp-io 31.0.0", + "sp-runtime 32.0.0", + "sp-std 14.0.0", "staging-xcm", ] @@ -2390,10 +2443,10 @@ dependencies = [ "polkadot-runtime-common", "polkadot-runtime-parachains", "scale-info", - "sp-core", - "sp-io", - "sp-runtime", - "sp-std", + "sp-core 29.0.0", + "sp-io 31.0.0", + "sp-runtime 32.0.0", + "sp-std 14.0.0", "staging-xcm", "staging-xcm-executor", ] @@ -2409,8 +2462,8 @@ dependencies = [ "polkadot-primitives", "sp-api", "sp-consensus-aura", - "sp-runtime", - "sp-std", + "sp-runtime 32.0.0", + "sp-std 14.0.0", ] [[package]] @@ -2425,9 +2478,9 @@ dependencies = [ "polkadot-primitives", "scale-info", "sp-api", - "sp-runtime", - "sp-std", - "sp-trie", + "sp-runtime 32.0.0", + "sp-std 14.0.0", + "sp-trie 30.0.0", "staging-xcm", ] @@ -2441,10 +2494,10 @@ dependencies = [ "cumulus-primitives-core", "parity-scale-codec", "scale-info", - "sp-core", + "sp-core 29.0.0", "sp-inherents", - "sp-std", - "sp-trie", + "sp-std 14.0.0", + "sp-trie 30.0.0", ] [[package]] @@ -2453,9 +2506,9 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c1b74f9141190b9f4bf96a947ade46da64097b77f1ebfa8d611c81724250e119" dependencies = [ - "sp-externalities", - "sp-runtime-interface", - "sp-trie", + "sp-externalities 0.26.0", + "sp-runtime-interface 25.0.0", + "sp-trie 30.0.0", ] [[package]] @@ -2471,9 +2524,9 @@ dependencies = [ "parity-scale-codec", "polkadot-runtime-common", "polkadot-runtime-parachains", - "sp-io", - "sp-runtime", - "sp-std", + "sp-io 31.0.0", + "sp-runtime 32.0.0", + "sp-std 14.0.0", "staging-xcm", "staging-xcm-builder", "staging-xcm-executor", @@ -2499,9 +2552,9 @@ dependencies = [ "sc-tracing", "sp-api", "sp-consensus", - "sp-core", - "sp-runtime", - "sp-state-machine", + "sp-core 29.0.0", + "sp-runtime 32.0.0", + "sp-state-machine 0.36.0", ] [[package]] @@ -2519,7 +2572,7 @@ dependencies = [ "sc-client-api", "sp-api", "sp-blockchain", - "sp-state-machine", + "sp-state-machine 0.36.0", "thiserror", ] @@ -2559,7 +2612,7 @@ dependencies = [ "sp-blockchain", "sp-consensus", "sp-consensus-babe", - "sp-runtime", + "sp-runtime 32.0.0", "substrate-prometheus-endpoint", "tokio", "tracing", @@ -2581,7 +2634,7 @@ dependencies = [ "parity-scale-codec", "pin-project", "polkadot-overseer", - "rand", + "rand 0.8.5", "sc-client-api", "sc-rpc-api", "sc-service", @@ -2593,10 +2646,10 @@ dependencies = [ "sp-api", "sp-authority-discovery", "sp-consensus-babe", - "sp-core", - "sp-runtime", - "sp-state-machine", - "sp-storage", + "sp-core 29.0.0", + "sp-runtime 32.0.0", + "sp-state-machine 0.36.0", + "sp-storage 20.0.0", "sp-version", "thiserror", "tokio", @@ -2614,10 +2667,23 @@ dependencies = [ "cumulus-primitives-core", "parity-scale-codec", "polkadot-primitives", - "sp-runtime", - "sp-state-machine", - "sp-std", - "sp-trie", + "sp-runtime 32.0.0", + "sp-state-machine 0.36.0", + "sp-std 14.0.0", + "sp-trie 30.0.0", +] + +[[package]] +name = "curve25519-dalek" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a9b85542f99a2dfa2a1b8e192662741c9859a846b296bef1c92ef9b58b5a216" +dependencies = [ + "byteorder", + "digest 0.8.1", + "rand_core 0.5.1", + "subtle 2.5.0", + "zeroize", ] [[package]] @@ -3064,10 +3130,19 @@ dependencies = [ "digest 0.10.7", "elliptic-curve", "rfc6979", - "signature", + "signature 2.2.0", "spki", ] +[[package]] +name = "ed25519" +version = "1.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91cff35c70bba8a626e3185d8cd48cc11b5437e1a5bcd15b9b5fa3c64b6dfee7" +dependencies = [ + "signature 1.6.4", +] + [[package]] name = "ed25519" version = "2.2.3" @@ -3075,7 +3150,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "115531babc129696a58c64a4fef0a8bf9e9698629fb97e9e40767d235cfbcd53" dependencies = [ "pkcs8", - "signature", + "signature 2.2.0", +] + +[[package]] +name = "ed25519-dalek" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c762bae6dcaf24c4c84667b8579785430908723d5c889f469d76a41d59cc7a9d" +dependencies = [ + "curve25519-dalek 3.2.0", + "ed25519 1.5.3", + "sha2 0.9.9", + "zeroize", ] [[package]] @@ -3085,7 +3172,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4a3daa8e81a3963a60642bcc1f90a670680bd4a77535faa384e9d1c79d620871" dependencies = [ "curve25519-dalek 4.1.2", - "ed25519", + "ed25519 2.2.3", "rand_core 0.6.4", "serde", "sha2 0.10.8", @@ -3114,7 +3201,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7d9ce6874da5d4415896cd45ffbc4d1cfc0c4f9c079427bd870742c30f2f65a9" dependencies = [ "curve25519-dalek 4.1.2", - "ed25519", + "ed25519 2.2.3", "hashbrown 0.14.3", "hex", "rand_core 0.6.4", @@ -3174,8 +3261,8 @@ dependencies = [ "sc-consensus-grandpa", "sp-authority-discovery", "sp-consensus-babe", - "sp-core", - "sp-runtime", + "sp-core 29.0.0", + "sp-runtime 32.0.0", "staging-xcm", "xcm-emulator", ] @@ -3422,6 +3509,12 @@ dependencies = [ "syn 2.0.58", ] +[[package]] +name = "fake-simd" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed" + [[package]] name = "fallible-iterator" version = "0.2.0" @@ -3539,7 +3632,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "835c052cb0c08c1acf6ffd71c022172e18723949c8282f2b9f27efbc51e64534" dependencies = [ "byteorder", - "rand", + "rand 0.8.5", "rustc-hex", "static_assertions", ] @@ -3616,13 +3709,13 @@ dependencies = [ "scale-info", "serde", "sp-api", - "sp-application-crypto", - "sp-core", - "sp-io", - "sp-runtime", - "sp-runtime-interface", - "sp-std", - "sp-storage", + "sp-application-crypto 31.0.0", + "sp-core 29.0.0", + "sp-io 31.0.0", + "sp-runtime 32.0.0", + "sp-runtime-interface 25.0.0", + "sp-std 14.0.0", + "sp-storage 20.0.0", "static_assertions", ] @@ -3647,7 +3740,7 @@ dependencies = [ "linked-hash-map", "log", "parity-scale-codec", - "rand", + "rand 0.8.5", "rand_pcg", "sc-block-builder", "sc-cli", @@ -3660,17 +3753,17 @@ dependencies = [ "serde_json", "sp-api", "sp-blockchain", - "sp-core", + "sp-core 29.0.0", "sp-database", - "sp-externalities", + "sp-externalities 0.26.0", "sp-inherents", - "sp-io", - "sp-keystore", - "sp-runtime", - "sp-state-machine", - "sp-storage", - "sp-trie", - "sp-wasm-interface", + "sp-io 31.0.0", + "sp-keystore 0.35.0", + "sp-runtime 32.0.0", + "sp-state-machine 0.36.0", + "sp-storage 20.0.0", + "sp-trie 30.0.0", + "sp-wasm-interface 20.0.0", "thiserror", "thousands", ] @@ -3698,11 +3791,11 @@ dependencies = [ "frame-system", "parity-scale-codec", "scale-info", - "sp-arithmetic", - "sp-core", + "sp-arithmetic 24.0.0", + "sp-core 29.0.0", "sp-npos-elections", - "sp-runtime", - "sp-std", + "sp-runtime 32.0.0", + "sp-std 14.0.0", ] [[package]] @@ -3717,11 +3810,11 @@ dependencies = [ "log", "parity-scale-codec", "scale-info", - "sp-core", - "sp-io", - "sp-runtime", - "sp-std", - "sp-tracing", + "sp-core 29.0.0", + "sp-io 31.0.0", + "sp-runtime 32.0.0", + "sp-std 14.0.0", + "sp-tracing 16.0.0", ] [[package]] @@ -3759,11 +3852,11 @@ dependencies = [ "log", "parity-scale-codec", "serde", - "sp-core", + "sp-core 29.0.0", "sp-crypto-hashing", - "sp-io", - "sp-runtime", - "sp-state-machine", + "sp-io 31.0.0", + "sp-runtime 32.0.0", + "sp-state-machine 0.36.0", "spinners", "substrate-rpc-client", "tokio", @@ -3794,20 +3887,20 @@ dependencies = [ "serde_json", "smallvec", "sp-api", - "sp-arithmetic", - "sp-core", + "sp-arithmetic 24.0.0", + "sp-core 29.0.0", "sp-crypto-hashing-proc-macro", - "sp-debug-derive", + "sp-debug-derive 14.0.0", "sp-genesis-builder", "sp-inherents", - "sp-io", + "sp-io 31.0.0", "sp-metadata-ir", - "sp-runtime", + "sp-runtime 32.0.0", "sp-staking", - "sp-state-machine", - "sp-std", - "sp-tracing", - "sp-weights", + "sp-state-machine 0.36.0", + "sp-std 14.0.0", + "sp-tracing 16.0.0", + "sp-weights 28.0.0", "static_assertions", "tt-call", ] @@ -3869,12 +3962,12 @@ dependencies = [ "parity-scale-codec", "scale-info", "serde", - "sp-core", - "sp-io", - "sp-runtime", - "sp-std", + "sp-core 29.0.0", + "sp-io 31.0.0", + "sp-runtime 32.0.0", + "sp-std 14.0.0", "sp-version", - "sp-weights", + "sp-weights 28.0.0", ] [[package]] @@ -3888,9 +3981,9 @@ dependencies = [ "frame-system", "parity-scale-codec", "scale-info", - "sp-core", - "sp-runtime", - "sp-std", + "sp-core 29.0.0", + "sp-runtime 32.0.0", + "sp-std 14.0.0", ] [[package]] @@ -3912,8 +4005,8 @@ dependencies = [ "frame-support", "parity-scale-codec", "sp-api", - "sp-runtime", - "sp-std", + "sp-runtime 32.0.0", + "sp-std 14.0.0", ] [[package]] @@ -4163,7 +4256,7 @@ version = "0.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6ea1015b5a70616b688dc230cfe50c8af89d972cb132d5a622814d29773b10b9" dependencies = [ - "rand", + "rand 0.8.5", "rand_core 0.6.4", ] @@ -4669,6 +4762,206 @@ dependencies = [ "unicode-width", ] +[[package]] +name = "ink" +version = "5.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d4a862aedbfda93175ddf75c9aaa2ae4c4b39ee5cee06c16d50bccce05bf5c7" +dependencies = [ + "derive_more", + "ink_env", + "ink_macro", + "ink_metadata", + "ink_prelude", + "ink_primitives", + "ink_storage", + "pallet-contracts-uapi-next", + "parity-scale-codec", + "scale-info", +] + +[[package]] +name = "ink_allocator" +version = "5.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5cee56055bac6d928d425e944c5f3b69baa33c9635822fd1c00cd4afc70fde3e" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "ink_codegen" +version = "5.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70a1f8473fa09e0f9b6f3cb3f8d18c07c14ebf9ea1f7cdfee270f009d45ee8e9" +dependencies = [ + "blake2 0.10.6", + "derive_more", + "either", + "heck 0.4.1", + "impl-serde", + "ink_ir", + "ink_primitives", + "itertools 0.12.1", + "parity-scale-codec", + "proc-macro2", + "quote", + "serde", + "serde_json", + "syn 2.0.58", +] + +[[package]] +name = "ink_engine" +version = "5.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f357e2e867f4e222ffc4015a6e61d1073548de89f70a4e36a8b0385562777fa" +dependencies = [ + "blake2 0.10.6", + "derive_more", + "ink_primitives", + "pallet-contracts-uapi-next", + "parity-scale-codec", + "secp256k1 0.28.2", + "sha2 0.10.8", + "sha3", +] + +[[package]] +name = "ink_env" +version = "5.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42cec50b7e4f8406aab25801b015d3802a52d76cfbe48ce11cfb4200fa88e296" +dependencies = [ + "blake2 0.10.6", + "cfg-if", + "const_env", + "derive_more", + "ink_allocator", + "ink_engine", + "ink_prelude", + "ink_primitives", + "ink_storage_traits", + "num-traits", + "pallet-contracts-uapi-next", + "parity-scale-codec", + "paste", + "rlibc", + "scale-decode", + "scale-encode", + "scale-info", + "schnorrkel 0.11.4", + "secp256k1 0.28.2", + "sha2 0.10.8", + "sha3", + "static_assertions", +] + +[[package]] +name = "ink_ir" +version = "5.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b1ad2975551c4ed800af971289ed6d2c68ac41ffc03a42010b3e01d7360dfb2" +dependencies = [ + "blake2 0.10.6", + "either", + "impl-serde", + "ink_prelude", + "itertools 0.12.1", + "proc-macro2", + "quote", + "syn 2.0.58", +] + +[[package]] +name = "ink_macro" +version = "5.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aee1a546f37eae3b3cd223832d31702033c5369dcfa3405899587c110a7908d3" +dependencies = [ + "ink_codegen", + "ink_ir", + "ink_primitives", + "parity-scale-codec", + "proc-macro2", + "quote", + "syn 2.0.58", + "synstructure 0.13.1", +] + +[[package]] +name = "ink_metadata" +version = "5.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a98fcc0ff9292ff68c7ee7b84c93533c9ff13859ec3b148faa822e2da9954fe6" +dependencies = [ + "derive_more", + "impl-serde", + "ink_prelude", + "ink_primitives", + "linkme", + "parity-scale-codec", + "scale-info", + "schemars", + "serde", +] + +[[package]] +name = "ink_prelude" +version = "5.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea1734d058c80aa72e59c8ae75624fd8a51791efba21469f273156c0f4cad5c9" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "ink_primitives" +version = "5.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11ec35ef7f45e67a53b6142d7e7f18e6d9292d76c3a2a1da14cf8423e481813d" +dependencies = [ + "derive_more", + "ink_prelude", + "parity-scale-codec", + "scale-decode", + "scale-encode", + "scale-info", + "xxhash-rust", +] + +[[package]] +name = "ink_storage" +version = "5.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbdb04cad74df858c05bc9cb6f30bbf12da33c3e2cb7ca211749c001fa761aa9" +dependencies = [ + "array-init", + "cfg-if", + "derive_more", + "ink_env", + "ink_metadata", + "ink_prelude", + "ink_primitives", + "ink_storage_traits", + "pallet-contracts-uapi-next", + "parity-scale-codec", + "scale-info", +] + +[[package]] +name = "ink_storage_traits" +version = "5.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83ce49e3d2935fc1ec3e73117119712b187d3123339f6a31624e92f75fa2293d" +dependencies = [ + "ink_metadata", + "ink_prelude", + "ink_primitives", + "parity-scale-codec", + "scale-info", +] + [[package]] name = "inout" version = "0.1.3" @@ -4726,8 +5019,8 @@ dependencies = [ "sp-consensus-babe", "sp-consensus-beefy", "sp-consensus-grandpa", - "sp-core", - "sp-runtime", + "sp-core 29.0.0", + "sp-runtime 32.0.0", "staging-xcm", "staging-xcm-executor", "tracing-subscriber 0.3.18", @@ -4923,7 +5216,7 @@ dependencies = [ "hyper", "jsonrpsee-types 0.20.3", "parking_lot 0.12.1", - "rand", + "rand 0.8.5", "rustc-hash", "serde", "serde_json", @@ -5256,7 +5549,7 @@ dependencies = [ "parking_lot 0.12.1", "pin-project", "quick-protobuf", - "rand", + "rand 0.8.5", "rw-stream-sink", "smallvec", "thiserror", @@ -5307,12 +5600,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "276bb57e7af15d8f100d3c11cbdd32c6752b7eef4ba7a18ecf464972c07abcce" dependencies = [ "bs58 0.4.0", - "ed25519-dalek", + "ed25519-dalek 2.1.1", "log", "multiaddr", "multihash 0.17.0", "quick-protobuf", - "rand", + "rand 0.8.5", "sha2 0.10.8", "thiserror", "zeroize", @@ -5337,7 +5630,7 @@ dependencies = [ "libp2p-swarm", "log", "quick-protobuf", - "rand", + "rand 0.8.5", "sha2 0.10.8", "smallvec", "thiserror", @@ -5359,7 +5652,7 @@ dependencies = [ "libp2p-identity", "libp2p-swarm", "log", - "rand", + "rand 0.8.5", "smallvec", "socket2 0.4.10", "tokio", @@ -5395,7 +5688,7 @@ dependencies = [ "log", "once_cell", "quick-protobuf", - "rand", + "rand 0.8.5", "sha2 0.10.8", "snow", "static_assertions", @@ -5417,7 +5710,7 @@ dependencies = [ "libp2p-core", "libp2p-swarm", "log", - "rand", + "rand 0.8.5", "void", ] @@ -5437,7 +5730,7 @@ dependencies = [ "log", "parking_lot 0.12.1", "quinn-proto", - "rand", + "rand 0.8.5", "rustls 0.20.9", "thiserror", "tokio", @@ -5455,7 +5748,7 @@ dependencies = [ "libp2p-core", "libp2p-identity", "libp2p-swarm", - "rand", + "rand 0.8.5", "smallvec", ] @@ -5474,7 +5767,7 @@ dependencies = [ "libp2p-identity", "libp2p-swarm-derive", "log", - "rand", + "rand 0.8.5", "smallvec", "tokio", "void", @@ -5610,7 +5903,7 @@ dependencies = [ "libsecp256k1-core", "libsecp256k1-gen-ecmult", "libsecp256k1-gen-genmult", - "rand", + "rand 0.8.5", "serde", "sha2 0.9.9", "typenum", @@ -5680,6 +5973,26 @@ dependencies = [ "linked-hash-map", ] +[[package]] +name = "linkme" +version = "0.3.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccb76662d78edc9f9bf56360d6919bdacc8b7761227727e5082f128eeb90bbf5" +dependencies = [ + "linkme-impl", +] + +[[package]] +name = "linkme-impl" +version = "0.3.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dccda732e04fa3baf2e17cf835bfe2601c7c2edafd64417c627dabae3a8cda" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.58", +] + [[package]] name = "linregress" version = "0.5.3" @@ -5951,6 +6264,18 @@ dependencies = [ "hash-db", ] +[[package]] +name = "merlin" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e261cf0f8b3c42ded9f7d2bb59dea03aa52bc8a1cbc7482f9fc3fd1229d3b42" +dependencies = [ + "byteorder", + "keccak", + "rand_core 0.5.1", + "zeroize", +] + [[package]] name = "merlin" version = "3.0.0" @@ -5970,7 +6295,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "69672161530e8aeca1d1400fbf3f1a1747ff60ea604265a4e906c2442df20532" dependencies = [ "futures", - "rand", + "rand 0.8.5", "thrift", ] @@ -6017,7 +6342,7 @@ dependencies = [ "lioness", "log", "parking_lot 0.12.1", - "rand", + "rand 0.8.5", "rand_chacha 0.3.1", "rand_distr", "subtle 2.5.0", @@ -6040,9 +6365,9 @@ dependencies = [ "sp-blockchain", "sp-consensus", "sp-consensus-beefy", - "sp-core", + "sp-core 29.0.0", "sp-mmr-primitives", - "sp-runtime", + "sp-runtime 32.0.0", ] [[package]] @@ -6056,9 +6381,9 @@ dependencies = [ "serde", "sp-api", "sp-blockchain", - "sp-core", + "sp-core 29.0.0", "sp-mmr-primitives", - "sp-runtime", + "sp-runtime 32.0.0", ] [[package]] @@ -6189,7 +6514,7 @@ dependencies = [ "proc-macro2", "quote", "syn 1.0.109", - "synstructure", + "synstructure 0.12.6", ] [[package]] @@ -6214,7 +6539,7 @@ dependencies = [ "proc-macro2", "quote", "syn 1.0.109", - "synstructure", + "synstructure 0.12.6", ] [[package]] @@ -6270,7 +6595,7 @@ version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7bddcd3bf5144b6392de80e04c347cd7fab2508f6df16a85fc496ecd5cec39bc" dependencies = [ - "rand", + "rand 0.8.5", ] [[package]] @@ -6598,11 +6923,11 @@ dependencies = [ "parity-scale-codec", "scale-info", "sp-api", - "sp-arithmetic", - "sp-core", - "sp-io", - "sp-runtime", - "sp-std", + "sp-arithmetic 24.0.0", + "sp-core 29.0.0", + "sp-io 31.0.0", + "sp-runtime 32.0.0", + "sp-std 14.0.0", ] [[package]] @@ -6617,8 +6942,8 @@ dependencies = [ "pallet-transaction-payment", "parity-scale-codec", "scale-info", - "sp-runtime", - "sp-std", + "sp-runtime 32.0.0", + "sp-std 14.0.0", ] [[package]] @@ -6632,9 +6957,9 @@ dependencies = [ "frame-system", "parity-scale-codec", "scale-info", - "sp-core", - "sp-runtime", - "sp-std", + "sp-core 29.0.0", + "sp-runtime 32.0.0", + "sp-std 14.0.0", ] [[package]] @@ -6650,10 +6975,10 @@ dependencies = [ "parity-scale-codec", "scale-info", "serde", - "sp-core", - "sp-io", - "sp-runtime", - "sp-std", + "sp-core 29.0.0", + "sp-io 31.0.0", + "sp-runtime 32.0.0", + "sp-std 14.0.0", ] [[package]] @@ -6668,9 +6993,9 @@ dependencies = [ "log", "parity-scale-codec", "scale-info", - "sp-core", - "sp-runtime", - "sp-std", + "sp-core 29.0.0", + "sp-runtime 32.0.0", + "sp-std 14.0.0", ] [[package]] @@ -6685,10 +7010,10 @@ dependencies = [ "pallet-timestamp", "parity-scale-codec", "scale-info", - "sp-application-crypto", + "sp-application-crypto 31.0.0", "sp-consensus-aura", - "sp-runtime", - "sp-std", + "sp-runtime 32.0.0", + "sp-std 14.0.0", ] [[package]] @@ -6702,10 +7027,10 @@ dependencies = [ "pallet-session", "parity-scale-codec", "scale-info", - "sp-application-crypto", + "sp-application-crypto 31.0.0", "sp-authority-discovery", - "sp-runtime", - "sp-std", + "sp-runtime 32.0.0", + "sp-std 14.0.0", ] [[package]] @@ -6719,8 +7044,8 @@ dependencies = [ "impl-trait-for-tuples", "parity-scale-codec", "scale-info", - "sp-runtime", - "sp-std", + "sp-runtime 32.0.0", + "sp-std 14.0.0", ] [[package]] @@ -6738,14 +7063,14 @@ dependencies = [ "pallet-timestamp", "parity-scale-codec", "scale-info", - "sp-application-crypto", + "sp-application-crypto 31.0.0", "sp-consensus-babe", - "sp-core", - "sp-io", - "sp-runtime", + "sp-core 29.0.0", + "sp-io 31.0.0", + "sp-runtime 32.0.0", "sp-session", "sp-staking", - "sp-std", + "sp-std 14.0.0", ] [[package]] @@ -6764,11 +7089,11 @@ dependencies = [ "pallet-balances", "parity-scale-codec", "scale-info", - "sp-core", - "sp-io", - "sp-runtime", - "sp-std", - "sp-tracing", + "sp-core 29.0.0", + "sp-io 31.0.0", + "sp-runtime 32.0.0", + "sp-std 14.0.0", + "sp-tracing 16.0.0", ] [[package]] @@ -6784,8 +7109,8 @@ dependencies = [ "log", "parity-scale-codec", "scale-info", - "sp-runtime", - "sp-std", + "sp-runtime 32.0.0", + "sp-std 14.0.0", ] [[package]] @@ -6803,10 +7128,10 @@ dependencies = [ "scale-info", "serde", "sp-consensus-beefy", - "sp-runtime", + "sp-runtime 32.0.0", "sp-session", "sp-staking", - "sp-std", + "sp-std 14.0.0", ] [[package]] @@ -6828,11 +7153,11 @@ dependencies = [ "serde", "sp-api", "sp-consensus-beefy", - "sp-core", - "sp-io", - "sp-runtime", - "sp-state-machine", - "sp-std", + "sp-core 29.0.0", + "sp-io 31.0.0", + "sp-runtime 32.0.0", + "sp-state-machine 0.36.0", + "sp-std 14.0.0", ] [[package]] @@ -6848,10 +7173,10 @@ dependencies = [ "pallet-treasury", "parity-scale-codec", "scale-info", - "sp-core", - "sp-io", - "sp-runtime", - "sp-std", + "sp-core 29.0.0", + "sp-io 31.0.0", + "sp-runtime 32.0.0", + "sp-std 14.0.0", ] [[package]] @@ -6871,9 +7196,9 @@ dependencies = [ "parity-scale-codec", "scale-info", "sp-consensus-grandpa", - "sp-runtime", - "sp-std", - "sp-trie", + "sp-runtime 32.0.0", + "sp-std 14.0.0", + "sp-trie 30.0.0", ] [[package]] @@ -6891,8 +7216,8 @@ dependencies = [ "num-traits", "parity-scale-codec", "scale-info", - "sp-runtime", - "sp-std", + "sp-runtime 32.0.0", + "sp-std 14.0.0", ] [[package]] @@ -6912,9 +7237,9 @@ dependencies = [ "pallet-bridge-grandpa", "parity-scale-codec", "scale-info", - "sp-runtime", - "sp-std", - "sp-trie", + "sp-runtime 32.0.0", + "sp-std 14.0.0", + "sp-trie 30.0.0", ] [[package]] @@ -6933,9 +7258,9 @@ dependencies = [ "pallet-bridge-messages", "parity-scale-codec", "scale-info", - "sp-arithmetic", - "sp-runtime", - "sp-std", + "sp-arithmetic 24.0.0", + "sp-runtime 32.0.0", + "sp-std 14.0.0", ] [[package]] @@ -6950,10 +7275,10 @@ dependencies = [ "frame-system", "parity-scale-codec", "scale-info", - "sp-arithmetic", - "sp-core", - "sp-runtime", - "sp-std", + "sp-arithmetic 24.0.0", + "sp-core 29.0.0", + "sp-runtime 32.0.0", + "sp-std 14.0.0", ] [[package]] @@ -6970,10 +7295,10 @@ dependencies = [ "pallet-treasury", "parity-scale-codec", "scale-info", - "sp-core", - "sp-io", - "sp-runtime", - "sp-std", + "sp-core 29.0.0", + "sp-io 31.0.0", + "sp-runtime 32.0.0", + "sp-std 14.0.0", ] [[package]] @@ -6989,11 +7314,11 @@ dependencies = [ "pallet-authorship", "pallet-session", "parity-scale-codec", - "rand", + "rand 0.8.5", "scale-info", - "sp-runtime", + "sp-runtime 32.0.0", "sp-staking", - "sp-std", + "sp-std 14.0.0", ] [[package]] @@ -7008,10 +7333,10 @@ dependencies = [ "log", "parity-scale-codec", "scale-info", - "sp-core", - "sp-io", - "sp-runtime", - "sp-std", + "sp-core 29.0.0", + "sp-io 31.0.0", + "sp-runtime 32.0.0", + "sp-std 14.0.0", ] [[package]] @@ -7031,16 +7356,16 @@ dependencies = [ "pallet-contracts-proc-macro", "pallet-contracts-uapi", "parity-scale-codec", - "rand", + "rand 0.8.5", "rand_pcg", "scale-info", "serde", "smallvec", "sp-api", - "sp-core", - "sp-io", - "sp-runtime", - "sp-std", + "sp-core 29.0.0", + "sp-io 31.0.0", + "sp-runtime 32.0.0", + "sp-std 14.0.0", "staging-xcm", "staging-xcm-builder", "wasm-instrument", @@ -7071,6 +7396,17 @@ dependencies = [ "scale-info", ] +[[package]] +name = "pallet-contracts-uapi-next" +version = "6.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd549c16296ea5b2eb7c65c56aba548b286c1be4d7675b424ff6ccb8319c97a9" +dependencies = [ + "bitflags 1.3.2", + "paste", + "polkavm-derive", +] + [[package]] name = "pallet-conviction-voting" version = "29.0.0" @@ -7084,9 +7420,9 @@ dependencies = [ "parity-scale-codec", "scale-info", "serde", - "sp-io", - "sp-runtime", - "sp-std", + "sp-io 31.0.0", + "sp-runtime 32.0.0", + "sp-std 14.0.0", ] [[package]] @@ -7102,10 +7438,10 @@ dependencies = [ "parity-scale-codec", "scale-info", "serde", - "sp-core", - "sp-io", - "sp-runtime", - "sp-std", + "sp-core 29.0.0", + "sp-io 31.0.0", + "sp-runtime 32.0.0", + "sp-std 14.0.0", ] [[package]] @@ -7121,14 +7457,14 @@ dependencies = [ "log", "pallet-election-provider-support-benchmarking", "parity-scale-codec", - "rand", + "rand 0.8.5", "scale-info", - "sp-arithmetic", - "sp-core", - "sp-io", + "sp-arithmetic 24.0.0", + "sp-core 29.0.0", + "sp-io 31.0.0", "sp-npos-elections", - "sp-runtime", - "sp-std", + "sp-runtime 32.0.0", + "sp-std 14.0.0", "strum 0.24.1", ] @@ -7143,8 +7479,8 @@ dependencies = [ "frame-system", "parity-scale-codec", "sp-npos-elections", - "sp-runtime", - "sp-std", + "sp-runtime 32.0.0", + "sp-std 14.0.0", ] [[package]] @@ -7159,12 +7495,12 @@ dependencies = [ "log", "parity-scale-codec", "scale-info", - "sp-core", - "sp-io", + "sp-core 29.0.0", + "sp-io 31.0.0", "sp-npos-elections", - "sp-runtime", + "sp-runtime 32.0.0", "sp-staking", - "sp-std", + "sp-std 14.0.0", ] [[package]] @@ -7181,10 +7517,10 @@ dependencies = [ "log", "parity-scale-codec", "scale-info", - "sp-io", - "sp-runtime", + "sp-io 31.0.0", + "sp-runtime 32.0.0", "sp-staking", - "sp-std", + "sp-std 14.0.0", ] [[package]] @@ -7201,14 +7537,14 @@ dependencies = [ "pallet-session", "parity-scale-codec", "scale-info", - "sp-application-crypto", + "sp-application-crypto 31.0.0", "sp-consensus-grandpa", - "sp-core", - "sp-io", - "sp-runtime", + "sp-core 29.0.0", + "sp-io 31.0.0", + "sp-runtime 32.0.0", "sp-session", "sp-staking", - "sp-std", + "sp-std 14.0.0", ] [[package]] @@ -7224,9 +7560,9 @@ dependencies = [ "log", "parity-scale-codec", "scale-info", - "sp-io", - "sp-runtime", - "sp-std", + "sp-io 31.0.0", + "sp-runtime 32.0.0", + "sp-std 14.0.0", ] [[package]] @@ -7242,12 +7578,12 @@ dependencies = [ "pallet-authorship", "parity-scale-codec", "scale-info", - "sp-application-crypto", - "sp-core", - "sp-io", - "sp-runtime", + "sp-application-crypto 31.0.0", + "sp-core 29.0.0", + "sp-io 31.0.0", + "sp-runtime 32.0.0", "sp-staking", - "sp-std", + "sp-std 14.0.0", ] [[package]] @@ -7261,11 +7597,11 @@ dependencies = [ "frame-system", "parity-scale-codec", "scale-info", - "sp-core", - "sp-io", + "sp-core 29.0.0", + "sp-io 31.0.0", "sp-keyring", - "sp-runtime", - "sp-std", + "sp-runtime 32.0.0", + "sp-std 14.0.0", ] [[package]] @@ -7280,10 +7616,10 @@ dependencies = [ "log", "parity-scale-codec", "scale-info", - "sp-core", - "sp-io", - "sp-runtime", - "sp-std", + "sp-core 29.0.0", + "sp-io 31.0.0", + "sp-runtime 32.0.0", + "sp-std 14.0.0", ] [[package]] @@ -7299,12 +7635,12 @@ dependencies = [ "log", "parity-scale-codec", "scale-info", - "sp-arithmetic", - "sp-core", - "sp-io", - "sp-runtime", - "sp-std", - "sp-weights", + "sp-arithmetic 24.0.0", + "sp-core 29.0.0", + "sp-io 31.0.0", + "sp-runtime 32.0.0", + "sp-std 14.0.0", + "sp-weights 28.0.0", ] [[package]] @@ -7319,11 +7655,11 @@ dependencies = [ "log", "parity-scale-codec", "scale-info", - "sp-core", - "sp-io", + "sp-core 29.0.0", + "sp-io 31.0.0", "sp-mmr-primitives", - "sp-runtime", - "sp-std", + "sp-runtime 32.0.0", + "sp-std 14.0.0", ] [[package]] @@ -7338,9 +7674,9 @@ dependencies = [ "log", "parity-scale-codec", "scale-info", - "sp-io", - "sp-runtime", - "sp-std", + "sp-io 31.0.0", + "sp-runtime 32.0.0", + "sp-std 14.0.0", ] [[package]] @@ -7357,8 +7693,8 @@ dependencies = [ "pallet-nfts", "parity-scale-codec", "scale-info", - "sp-runtime", - "sp-std", + "sp-runtime 32.0.0", + "sp-std 14.0.0", ] [[package]] @@ -7374,10 +7710,10 @@ dependencies = [ "log", "parity-scale-codec", "scale-info", - "sp-core", - "sp-io", - "sp-runtime", - "sp-std", + "sp-core 29.0.0", + "sp-io 31.0.0", + "sp-runtime 32.0.0", + "sp-std 14.0.0", ] [[package]] @@ -7389,7 +7725,7 @@ dependencies = [ "pallet-nfts", "parity-scale-codec", "sp-api", - "sp-std", + "sp-std 14.0.0", ] [[package]] @@ -7403,10 +7739,10 @@ dependencies = [ "frame-system", "parity-scale-codec", "scale-info", - "sp-arithmetic", - "sp-core", - "sp-runtime", - "sp-std", + "sp-arithmetic 24.0.0", + "sp-core 29.0.0", + "sp-runtime 32.0.0", + "sp-std 14.0.0", ] [[package]] @@ -7421,12 +7757,12 @@ dependencies = [ "pallet-balances", "parity-scale-codec", "scale-info", - "sp-core", - "sp-io", - "sp-runtime", + "sp-core 29.0.0", + "sp-io 31.0.0", + "sp-runtime 32.0.0", "sp-staking", - "sp-std", - "sp-tracing", + "sp-std 14.0.0", + "sp-tracing 16.0.0", ] [[package]] @@ -7444,10 +7780,10 @@ dependencies = [ "pallet-staking", "parity-scale-codec", "scale-info", - "sp-runtime", - "sp-runtime-interface", + "sp-runtime 32.0.0", + "sp-runtime-interface 25.0.0", "sp-staking", - "sp-std", + "sp-std 14.0.0", ] [[package]] @@ -7459,7 +7795,7 @@ dependencies = [ "pallet-nomination-pools", "parity-scale-codec", "sp-api", - "sp-std", + "sp-std 14.0.0", ] [[package]] @@ -7475,9 +7811,9 @@ dependencies = [ "parity-scale-codec", "scale-info", "serde", - "sp-runtime", + "sp-runtime 32.0.0", "sp-staking", - "sp-std", + "sp-std 14.0.0", ] [[package]] @@ -7500,9 +7836,9 @@ dependencies = [ "pallet-staking", "parity-scale-codec", "scale-info", - "sp-runtime", + "sp-runtime 32.0.0", "sp-staking", - "sp-std", + "sp-std 14.0.0", ] [[package]] @@ -7517,10 +7853,10 @@ dependencies = [ "log", "parity-scale-codec", "scale-info", - "sp-core", - "sp-io", - "sp-runtime", - "sp-std", + "sp-core 29.0.0", + "sp-io 31.0.0", + "sp-runtime 32.0.0", + "sp-std 14.0.0", ] [[package]] @@ -7534,9 +7870,9 @@ dependencies = [ "frame-system", "parity-scale-codec", "scale-info", - "sp-io", - "sp-runtime", - "sp-std", + "sp-io 31.0.0", + "sp-runtime 32.0.0", + "sp-std 14.0.0", ] [[package]] @@ -7552,11 +7888,11 @@ dependencies = [ "log", "parity-scale-codec", "scale-info", - "sp-arithmetic", - "sp-core", - "sp-io", - "sp-runtime", - "sp-std", + "sp-arithmetic 24.0.0", + "sp-core 29.0.0", + "sp-io 31.0.0", + "sp-runtime 32.0.0", + "sp-std 14.0.0", ] [[package]] @@ -7570,9 +7906,9 @@ dependencies = [ "frame-system", "parity-scale-codec", "scale-info", - "sp-io", - "sp-runtime", - "sp-std", + "sp-io 31.0.0", + "sp-runtime 32.0.0", + "sp-std 14.0.0", ] [[package]] @@ -7589,10 +7925,10 @@ dependencies = [ "parity-scale-codec", "scale-info", "serde", - "sp-arithmetic", - "sp-io", - "sp-runtime", - "sp-std", + "sp-arithmetic 24.0.0", + "sp-io 31.0.0", + "sp-runtime 32.0.0", + "sp-std 14.0.0", ] [[package]] @@ -7605,10 +7941,10 @@ dependencies = [ "frame-system", "parity-scale-codec", "scale-info", - "sp-core", - "sp-io", - "sp-runtime", - "sp-std", + "sp-core 29.0.0", + "sp-io 31.0.0", + "sp-runtime 32.0.0", + "sp-std 14.0.0", ] [[package]] @@ -7624,10 +7960,10 @@ dependencies = [ "log", "parity-scale-codec", "scale-info", - "sp-io", - "sp-runtime", - "sp-std", - "sp-weights", + "sp-io 31.0.0", + "sp-runtime 32.0.0", + "sp-std 14.0.0", + "sp-weights 28.0.0", ] [[package]] @@ -7643,14 +7979,14 @@ dependencies = [ "pallet-timestamp", "parity-scale-codec", "scale-info", - "sp-core", - "sp-io", - "sp-runtime", + "sp-core 29.0.0", + "sp-io 31.0.0", + "sp-runtime 32.0.0", "sp-session", "sp-staking", - "sp-state-machine", - "sp-std", - "sp-trie", + "sp-state-machine 0.36.0", + "sp-std 14.0.0", + "sp-trie 30.0.0", ] [[package]] @@ -7665,10 +8001,10 @@ dependencies = [ "pallet-session", "pallet-staking", "parity-scale-codec", - "rand", - "sp-runtime", + "rand 0.8.5", + "sp-runtime 32.0.0", "sp-session", - "sp-std", + "sp-std 14.0.0", ] [[package]] @@ -7684,10 +8020,10 @@ dependencies = [ "parity-scale-codec", "rand_chacha 0.2.2", "scale-info", - "sp-arithmetic", - "sp-io", - "sp-runtime", - "sp-std", + "sp-arithmetic 24.0.0", + "sp-io 31.0.0", + "sp-runtime 32.0.0", + "sp-std 14.0.0", ] [[package]] @@ -7707,11 +8043,11 @@ dependencies = [ "rand_chacha 0.2.2", "scale-info", "serde", - "sp-application-crypto", - "sp-io", - "sp-runtime", + "sp-application-crypto 31.0.0", + "sp-io 31.0.0", + "sp-runtime 32.0.0", "sp-staking", - "sp-std", + "sp-std 14.0.0", ] [[package]] @@ -7733,7 +8069,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "505d45e08bad052f55fb51f00a6b6244d23ee46ffdc8091f6cddf4e3a880319d" dependencies = [ "log", - "sp-arithmetic", + "sp-arithmetic 24.0.0", ] [[package]] @@ -7759,10 +8095,10 @@ dependencies = [ "log", "parity-scale-codec", "scale-info", - "sp-core", - "sp-io", - "sp-runtime", - "sp-std", + "sp-core 29.0.0", + "sp-io 31.0.0", + "sp-runtime 32.0.0", + "sp-std 14.0.0", ] [[package]] @@ -7777,9 +8113,9 @@ dependencies = [ "frame-system", "parity-scale-codec", "scale-info", - "sp-io", - "sp-runtime", - "sp-std", + "sp-io 31.0.0", + "sp-runtime 32.0.0", + "sp-std 14.0.0", ] [[package]] @@ -7796,10 +8132,10 @@ dependencies = [ "parity-scale-codec", "scale-info", "sp-inherents", - "sp-io", - "sp-runtime", - "sp-std", - "sp-storage", + "sp-io 31.0.0", + "sp-runtime 32.0.0", + "sp-std 14.0.0", + "sp-storage 20.0.0", "sp-timestamp", ] @@ -7817,10 +8153,10 @@ dependencies = [ "parity-scale-codec", "scale-info", "serde", - "sp-core", - "sp-io", - "sp-runtime", - "sp-std", + "sp-core 29.0.0", + "sp-io 31.0.0", + "sp-runtime 32.0.0", + "sp-std 14.0.0", ] [[package]] @@ -7834,10 +8170,10 @@ dependencies = [ "parity-scale-codec", "scale-info", "serde", - "sp-core", - "sp-io", - "sp-runtime", - "sp-std", + "sp-core 29.0.0", + "sp-io 31.0.0", + "sp-runtime 32.0.0", + "sp-std 14.0.0", ] [[package]] @@ -7851,10 +8187,10 @@ dependencies = [ "parity-scale-codec", "sp-api", "sp-blockchain", - "sp-core", + "sp-core 29.0.0", "sp-rpc", - "sp-runtime", - "sp-weights", + "sp-runtime 32.0.0", + "sp-weights 28.0.0", ] [[package]] @@ -7866,8 +8202,8 @@ dependencies = [ "pallet-transaction-payment", "parity-scale-codec", "sp-api", - "sp-runtime", - "sp-weights", + "sp-runtime 32.0.0", + "sp-weights 28.0.0", ] [[package]] @@ -7885,9 +8221,9 @@ dependencies = [ "parity-scale-codec", "scale-info", "serde", - "sp-core", - "sp-runtime", - "sp-std", + "sp-core 29.0.0", + "sp-runtime 32.0.0", + "sp-std 14.0.0", ] [[package]] @@ -7902,8 +8238,8 @@ dependencies = [ "log", "parity-scale-codec", "scale-info", - "sp-runtime", - "sp-std", + "sp-runtime 32.0.0", + "sp-std 14.0.0", ] [[package]] @@ -7917,10 +8253,10 @@ dependencies = [ "frame-system", "parity-scale-codec", "scale-info", - "sp-core", - "sp-io", - "sp-runtime", - "sp-std", + "sp-core 29.0.0", + "sp-io 31.0.0", + "sp-runtime 32.0.0", + "sp-std 14.0.0", ] [[package]] @@ -7935,8 +8271,8 @@ dependencies = [ "log", "parity-scale-codec", "scale-info", - "sp-runtime", - "sp-std", + "sp-runtime 32.0.0", + "sp-std 14.0.0", ] [[package]] @@ -7951,8 +8287,8 @@ dependencies = [ "parity-scale-codec", "scale-info", "sp-api", - "sp-runtime", - "sp-std", + "sp-runtime 32.0.0", + "sp-std 14.0.0", ] [[package]] @@ -7970,10 +8306,10 @@ dependencies = [ "parity-scale-codec", "scale-info", "serde", - "sp-core", - "sp-io", - "sp-runtime", - "sp-std", + "sp-core 29.0.0", + "sp-io 31.0.0", + "sp-runtime 32.0.0", + "sp-std 14.0.0", "staging-xcm", "staging-xcm-builder", "staging-xcm-executor", @@ -7991,9 +8327,9 @@ dependencies = [ "log", "parity-scale-codec", "scale-info", - "sp-io", - "sp-runtime", - "sp-std", + "sp-io 31.0.0", + "sp-runtime 32.0.0", + "sp-std 14.0.0", "staging-xcm", "staging-xcm-builder", "staging-xcm-executor", @@ -8012,9 +8348,9 @@ dependencies = [ "log", "parity-scale-codec", "scale-info", - "sp-core", - "sp-runtime", - "sp-std", + "sp-core 29.0.0", + "sp-runtime 32.0.0", + "sp-std 14.0.0", "staging-xcm", "staging-xcm-builder", ] @@ -8041,10 +8377,10 @@ dependencies = [ "polkadot-primitives", "scale-info", "sp-consensus-aura", - "sp-core", - "sp-io", - "sp-runtime", - "sp-std", + "sp-core 29.0.0", + "sp-io 31.0.0", + "sp-runtime 32.0.0", + "sp-std 14.0.0", "staging-parachain-info", "staging-xcm", "staging-xcm-executor", @@ -8071,11 +8407,11 @@ dependencies = [ "parity-scale-codec", "polkadot-parachain-primitives", "sp-consensus-aura", - "sp-core", - "sp-io", - "sp-runtime", - "sp-std", - "sp-tracing", + "sp-core 29.0.0", + "sp-io 31.0.0", + "sp-runtime 32.0.0", + "sp-std 14.0.0", + "sp-tracing 16.0.0", "staging-parachain-info", "staging-xcm", "staging-xcm-executor", @@ -8103,7 +8439,7 @@ dependencies = [ "lz4", "memmap2 0.5.10", "parking_lot 0.12.1", - "rand", + "rand 0.8.5", "siphasher 0.3.11", "snap", "winapi", @@ -8168,7 +8504,7 @@ checksum = "f557c32c6d268a07c921471619c0295f5efad3a0e76d4f97a05c091a51d110b2" dependencies = [ "proc-macro2", "syn 1.0.109", - "synstructure", + "synstructure 0.12.6", ] [[package]] @@ -8252,6 +8588,15 @@ dependencies = [ "crypto-mac 0.11.0", ] +[[package]] +name = "pbkdf2" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83a0692ec44e4cf1ef28ca317f14f8f07da2d95ec3fa01f86e4467b725e60917" +dependencies = [ + "digest 0.10.7", +] + [[package]] name = "pbkdf2" version = "0.12.2" @@ -8425,7 +8770,7 @@ dependencies = [ "polkadot-node-subsystem", "polkadot-node-subsystem-util", "polkadot-primitives", - "rand", + "rand 0.8.5", "tracing-gum", ] @@ -8442,7 +8787,7 @@ dependencies = [ "polkadot-node-subsystem", "polkadot-node-subsystem-util", "polkadot-primitives", - "rand", + "rand 0.8.5", "tracing-gum", ] @@ -8462,10 +8807,10 @@ dependencies = [ "polkadot-node-subsystem", "polkadot-node-subsystem-util", "polkadot-primitives", - "rand", + "rand 0.8.5", "schnellru", - "sp-core", - "sp-keystore", + "sp-core 29.0.0", + "sp-keystore 0.35.0", "thiserror", "tracing-gum", ] @@ -8486,7 +8831,7 @@ dependencies = [ "polkadot-node-subsystem", "polkadot-node-subsystem-util", "polkadot-primitives", - "rand", + "rand 0.8.5", "sc-network", "schnellru", "thiserror", @@ -8514,8 +8859,8 @@ dependencies = [ "sc-storage-monitor", "sc-sysinfo", "sc-tracing", - "sp-core", - "sp-io", + "sp-core 29.0.0", + "sp-io 31.0.0", "sp-keyring", "sp-maybe-compressed-blob", "substrate-build-script-utils", @@ -8538,9 +8883,9 @@ dependencies = [ "polkadot-node-subsystem", "polkadot-node-subsystem-util", "polkadot-primitives", - "sp-core", - "sp-keystore", - "sp-runtime", + "sp-core 29.0.0", + "sp-keystore 0.35.0", + "sp-runtime 32.0.0", "thiserror", "tokio-util", "tracing-gum", @@ -8554,9 +8899,9 @@ checksum = "b6a08e4e014c853b252ecbbe3ccd67b2d33d78e46988d309b8cccf4ac06e25ef" dependencies = [ "parity-scale-codec", "scale-info", - "sp-core", - "sp-runtime", - "sp-std", + "sp-core 29.0.0", + "sp-runtime 32.0.0", + "sp-std 14.0.0", ] [[package]] @@ -8579,8 +8924,8 @@ dependencies = [ "polkadot-primitives", "sc-network", "schnellru", - "sp-application-crypto", - "sp-keystore", + "sp-application-crypto 31.0.0", + "sp-keystore 0.35.0", "thiserror", "tracing-gum", ] @@ -8595,8 +8940,8 @@ dependencies = [ "polkadot-node-primitives", "polkadot-primitives", "reed-solomon-novelpoly", - "sp-core", - "sp-trie", + "sp-core 29.0.0", + "sp-trie 30.0.0", "thiserror", ] @@ -8612,14 +8957,14 @@ dependencies = [ "polkadot-node-subsystem", "polkadot-node-subsystem-util", "polkadot-primitives", - "rand", + "rand 0.8.5", "rand_chacha 0.3.1", "sc-network", "sc-network-common", - "sp-application-crypto", - "sp-core", + "sp-application-crypto 31.0.0", + "sp-core 29.0.0", "sp-crypto-hashing", - "sp-keystore", + "sp-keystore 0.35.0", "tracing-gum", ] @@ -8660,7 +9005,7 @@ dependencies = [ "polkadot-node-subsystem", "polkadot-node-subsystem-util", "polkadot-primitives", - "sp-core", + "sp-core 29.0.0", "sp-maybe-compressed-blob", "thiserror", "tracing-gum", @@ -8678,7 +9023,7 @@ dependencies = [ "futures-timer", "itertools 0.10.5", "kvdb", - "merlin", + "merlin 3.0.0", "parity-scale-codec", "polkadot-node-jaeger", "polkadot-node-primitives", @@ -8686,16 +9031,16 @@ dependencies = [ "polkadot-node-subsystem-util", "polkadot-overseer", "polkadot-primitives", - "rand", + "rand 0.8.5", "rand_chacha 0.3.1", "rand_core 0.6.4", "sc-keystore", "schnellru", "schnorrkel 0.11.4", - "sp-application-crypto", + "sp-application-crypto 31.0.0", "sp-consensus", "sp-consensus-slots", - "sp-runtime", + "sp-runtime 32.0.0", "thiserror", "tracing-gum", ] @@ -8739,7 +9084,7 @@ dependencies = [ "polkadot-primitives", "polkadot-statement-table", "schnellru", - "sp-keystore", + "sp-keystore 0.35.0", "thiserror", "tracing-gum", ] @@ -8754,7 +9099,7 @@ dependencies = [ "polkadot-node-subsystem", "polkadot-node-subsystem-util", "polkadot-primitives", - "sp-keystore", + "sp-keystore 0.35.0", "thiserror", "tracing-gum", "wasm-timer", @@ -8912,11 +9257,11 @@ dependencies = [ "polkadot-node-subsystem", "polkadot-parachain-primitives", "polkadot-primitives", - "rand", + "rand 0.8.5", "slotmap", - "sp-core", + "sp-core 29.0.0", "sp-maybe-compressed-blob", - "sp-wasm-interface", + "sp-wasm-interface 20.0.0", "tempfile", "thiserror", "tokio", @@ -8935,7 +9280,7 @@ dependencies = [ "polkadot-node-subsystem-util", "polkadot-overseer", "polkadot-primitives", - "sp-keystore", + "sp-keystore 0.35.0", "thiserror", "tracing-gum", ] @@ -8959,11 +9304,11 @@ dependencies = [ "sc-executor-common", "sc-executor-wasmtime", "seccompiler", - "sp-core", + "sp-core 29.0.0", "sp-crypto-hashing", - "sp-externalities", - "sp-io", - "sp-tracing", + "sp-externalities 0.26.0", + "sp-io 31.0.0", + "sp-tracing 16.0.0", "thiserror", "tracing-gum", ] @@ -8998,7 +9343,7 @@ dependencies = [ "polkadot-node-primitives", "polkadot-primitives", "sc-network", - "sp-core", + "sp-core 29.0.0", "thiserror", "tokio", ] @@ -9040,7 +9385,7 @@ dependencies = [ "polkadot-node-jaeger", "polkadot-node-primitives", "polkadot-primitives", - "rand", + "rand 0.8.5", "sc-authority-discovery", "sc-network", "strum 0.24.1", @@ -9062,12 +9407,12 @@ dependencies = [ "polkadot-primitives", "schnorrkel 0.11.4", "serde", - "sp-application-crypto", + "sp-application-crypto 31.0.0", "sp-consensus-babe", - "sp-core", - "sp-keystore", + "sp-core 29.0.0", + "sp-keystore 0.35.0", "sp-maybe-compressed-blob", - "sp-runtime", + "sp-runtime 32.0.0", "thiserror", "zstd 0.12.4", ] @@ -9107,7 +9452,7 @@ dependencies = [ "sp-authority-discovery", "sp-blockchain", "sp-consensus-babe", - "sp-runtime", + "sp-runtime 32.0.0", "substrate-prometheus-endpoint", "thiserror", ] @@ -9138,12 +9483,12 @@ dependencies = [ "polkadot-overseer", "polkadot-primitives", "prioritized-metered-channel", - "rand", + "rand 0.8.5", "sc-client-api", "schnellru", - "sp-application-crypto", - "sp-core", - "sp-keystore", + "sp-application-crypto 31.0.0", + "sp-core 29.0.0", + "sp-keystore 0.35.0", "thiserror", "tracing-gum", ] @@ -9166,7 +9511,7 @@ dependencies = [ "polkadot-primitives", "sc-client-api", "sp-api", - "sp-core", + "sp-core 29.0.0", "tikv-jemalloc-ctl", "tracing-gum", ] @@ -9183,10 +9528,10 @@ dependencies = [ "polkadot-core-primitives", "scale-info", "serde", - "sp-core", - "sp-runtime", - "sp-std", - "sp-weights", + "sp-core 29.0.0", + "sp-runtime 32.0.0", + "sp-std 14.0.0", + "sp-weights 28.0.0", ] [[package]] @@ -9204,17 +9549,17 @@ dependencies = [ "scale-info", "serde", "sp-api", - "sp-application-crypto", - "sp-arithmetic", + "sp-application-crypto 31.0.0", + "sp-arithmetic 24.0.0", "sp-authority-discovery", "sp-consensus-slots", - "sp-core", + "sp-core 29.0.0", "sp-inherents", - "sp-io", - "sp-keystore", - "sp-runtime", + "sp-io 31.0.0", + "sp-keystore 0.35.0", + "sp-runtime 32.0.0", "sp-staking", - "sp-std", + "sp-std 14.0.0", ] [[package]] @@ -9245,8 +9590,8 @@ dependencies = [ "sp-blockchain", "sp-consensus", "sp-consensus-babe", - "sp-keystore", - "sp-runtime", + "sp-keystore 0.35.0", + "sp-runtime 32.0.0", "substrate-frame-rpc-system", "substrate-state-trie-migration-rpc", ] @@ -9289,14 +9634,14 @@ dependencies = [ "serde_derive", "slot-range-helper", "sp-api", - "sp-core", + "sp-core 29.0.0", "sp-inherents", - "sp-io", + "sp-io 31.0.0", "sp-npos-elections", - "sp-runtime", + "sp-runtime 32.0.0", "sp-session", "sp-staking", - "sp-std", + "sp-std 14.0.0", "staging-xcm", "staging-xcm-builder", "staging-xcm-executor", @@ -9313,8 +9658,8 @@ dependencies = [ "frame-benchmarking", "parity-scale-codec", "polkadot-primitives", - "sp-std", - "sp-tracing", + "sp-std 14.0.0", + "sp-tracing 16.0.0", ] [[package]] @@ -9346,22 +9691,22 @@ dependencies = [ "polkadot-parachain-primitives", "polkadot-primitives", "polkadot-runtime-metrics", - "rand", + "rand 0.8.5", "rand_chacha 0.3.1", "rustc-hex", "scale-info", "serde", "sp-api", - "sp-application-crypto", - "sp-arithmetic", - "sp-core", + "sp-application-crypto 31.0.0", + "sp-arithmetic 24.0.0", + "sp-core 29.0.0", "sp-inherents", - "sp-io", - "sp-keystore", - "sp-runtime", + "sp-io 31.0.0", + "sp-keystore 0.35.0", + "sp-runtime 32.0.0", "sp-session", "sp-staking", - "sp-std", + "sp-std 14.0.0", "staging-xcm", "staging-xcm-executor", "static_assertions", @@ -9464,21 +9809,21 @@ dependencies = [ "sp-consensus-babe", "sp-consensus-beefy", "sp-consensus-grandpa", - "sp-core", + "sp-core 29.0.0", "sp-inherents", - "sp-io", + "sp-io 31.0.0", "sp-keyring", - "sp-keystore", + "sp-keystore 0.35.0", "sp-mmr-primitives", "sp-offchain", - "sp-runtime", + "sp-runtime 32.0.0", "sp-session", - "sp-state-machine", - "sp-storage", + "sp-state-machine 0.36.0", + "sp-storage 20.0.0", "sp-timestamp", "sp-transaction-pool", "sp-version", - "sp-weights", + "sp-weights 28.0.0", "substrate-prometheus-endpoint", "thiserror", "tracing-gum", @@ -9503,7 +9848,7 @@ dependencies = [ "polkadot-node-subsystem", "polkadot-node-subsystem-util", "polkadot-primitives", - "sp-keystore", + "sp-keystore 0.35.0", "sp-staking", "thiserror", "tracing-gum", @@ -9517,7 +9862,7 @@ checksum = "de5e010da3c6a65d8f263d0f825a04d995ffc8a37f886f674fcbbc73bf158d01" dependencies = [ "parity-scale-codec", "polkadot-primitives", - "sp-core", + "sp-core 29.0.0", "tracing-gum", ] @@ -9603,6 +9948,19 @@ dependencies = [ "universal-hash", ] +[[package]] +name = "pop-api" +version = "0.0.0" +dependencies = [ + "enumflags2", + "ink", + "parity-scale-codec", + "pop-primitives", + "scale-info", + "sp-io 23.0.0", + "sp-runtime 24.0.0", +] + [[package]] name = "pop-node" version = "0.1.0-alpha" @@ -9653,11 +10011,11 @@ dependencies = [ "sp-block-builder", "sp-blockchain", "sp-consensus-aura", - "sp-core", - "sp-io", - "sp-keystore", + "sp-core 29.0.0", + "sp-io 31.0.0", + "sp-keystore 0.35.0", "sp-offchain", - "sp-runtime", + "sp-runtime 32.0.0", "sp-session", "sp-timestamp", "sp-transaction-pool", @@ -9687,8 +10045,8 @@ dependencies = [ "parity-scale-codec", "polkadot-primitives", "scale-info", - "sp-runtime", - "sp-std", + "sp-runtime 32.0.0", + "sp-std 14.0.0", ] [[package]] @@ -9740,6 +10098,7 @@ dependencies = [ "parity-scale-codec", "polkadot-parachain-primitives", "polkadot-runtime-common", + "pop-api", "pop-primitives", "pop-runtime-common", "scale-info", @@ -9747,14 +10106,14 @@ dependencies = [ "sp-api", "sp-block-builder", "sp-consensus-aura", - "sp-core", + "sp-core 29.0.0", "sp-genesis-builder", "sp-inherents", - "sp-io", + "sp-io 31.0.0", "sp-offchain", - "sp-runtime", + "sp-runtime 32.0.0", "sp-session", - "sp-std", + "sp-std 14.0.0", "sp-transaction-pool", "sp-version", "staging-parachain-info", @@ -9820,14 +10179,14 @@ dependencies = [ "sp-api", "sp-block-builder", "sp-consensus-aura", - "sp-core", + "sp-core 29.0.0", "sp-genesis-builder", "sp-inherents", - "sp-io", + "sp-io 31.0.0", "sp-offchain", - "sp-runtime", + "sp-runtime 32.0.0", "sp-session", - "sp-std", + "sp-std 14.0.0", "sp-transaction-pool", "sp-version", "staging-parachain-info", @@ -10187,7 +10546,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94b0b33c13a79f669c85defaf4c275dc86a0c0372807d0ca3d78e0bb87274863" dependencies = [ "bytes", - "rand", + "rand 0.8.5", "ring 0.16.20", "rustc-hash", "rustls 0.20.9", @@ -10215,7 +10574,20 @@ checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" [[package]] name = "rand" -version = "0.8.5" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" +dependencies = [ + "getrandom 0.1.16", + "libc", + "rand_chacha 0.2.2", + "rand_core 0.5.1", + "rand_hc", +] + +[[package]] +name = "rand" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ @@ -10269,7 +10641,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32cb0b9bc82b0a0876c2dd994a7e7a2683d3e7390ca40e6886785ef0c7e3ee31" dependencies = [ "num-traits", - "rand", + "rand 0.8.5", +] + +[[package]] +name = "rand_hc" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" +dependencies = [ + "rand_core 0.5.1", ] [[package]] @@ -10495,6 +10876,12 @@ dependencies = [ "digest 0.10.7", ] +[[package]] +name = "rlibc" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc874b127765f014d792f16763a81245ab80500e2ad921ed4ee9e82481ee08fe" + [[package]] name = "rlp" version = "0.5.2" @@ -10587,22 +10974,22 @@ dependencies = [ "serde_derive", "smallvec", "sp-api", - "sp-arithmetic", + "sp-arithmetic 24.0.0", "sp-authority-discovery", "sp-block-builder", "sp-consensus-babe", "sp-consensus-beefy", - "sp-core", + "sp-core 29.0.0", "sp-genesis-builder", "sp-inherents", - "sp-io", + "sp-io 31.0.0", "sp-mmr-primitives", "sp-offchain", - "sp-runtime", + "sp-runtime 32.0.0", "sp-session", "sp-staking", - "sp-std", - "sp-storage", + "sp-std 14.0.0", + "sp-storage 20.0.0", "sp-transaction-pool", "sp-version", "staging-xcm", @@ -10622,9 +11009,9 @@ dependencies = [ "polkadot-primitives", "polkadot-runtime-common", "smallvec", - "sp-core", - "sp-runtime", - "sp-weights", + "sp-core 29.0.0", + "sp-runtime 32.0.0", + "sp-weights 28.0.0", "staging-xcm", "staging-xcm-builder", ] @@ -10927,8 +11314,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "357127c91373ed6d1ae582f6e3300ab5b13bcde43bbf270a891f44194ef48b70" dependencies = [ "log", - "sp-core", - "sp-wasm-interface", + "sp-core 29.0.0", + "sp-wasm-interface 20.0.0", "thiserror", ] @@ -10949,15 +11336,15 @@ dependencies = [ "parity-scale-codec", "prost 0.12.3", "prost-build", - "rand", + "rand 0.8.5", "sc-client-api", "sc-network", "sp-api", "sp-authority-discovery", "sp-blockchain", - "sp-core", - "sp-keystore", - "sp-runtime", + "sp-core 29.0.0", + "sp-keystore 0.35.0", + "sp-runtime 32.0.0", "substrate-prometheus-endpoint", "thiserror", ] @@ -10979,9 +11366,9 @@ dependencies = [ "sp-api", "sp-blockchain", "sp-consensus", - "sp-core", + "sp-core 29.0.0", "sp-inherents", - "sp-runtime", + "sp-runtime 32.0.0", "substrate-prometheus-endpoint", ] @@ -10995,10 +11382,10 @@ dependencies = [ "sp-api", "sp-block-builder", "sp-blockchain", - "sp-core", + "sp-core 29.0.0", "sp-inherents", - "sp-runtime", - "sp-trie", + "sp-runtime 32.0.0", + "sp-trie 30.0.0", ] [[package]] @@ -11020,12 +11407,12 @@ dependencies = [ "serde", "serde_json", "sp-blockchain", - "sp-core", + "sp-core 29.0.0", "sp-crypto-hashing", "sp-genesis-builder", - "sp-io", - "sp-runtime", - "sp-state-machine", + "sp-io 31.0.0", + "sp-runtime 32.0.0", + "sp-state-machine 0.36.0", ] [[package]] @@ -11057,7 +11444,7 @@ dependencies = [ "log", "names", "parity-scale-codec", - "rand", + "rand 0.8.5", "regex", "rpassword", "sc-client-api", @@ -11072,11 +11459,11 @@ dependencies = [ "serde", "serde_json", "sp-blockchain", - "sp-core", + "sp-core 29.0.0", "sp-keyring", - "sp-keystore", - "sp-panic-handler", - "sp-runtime", + "sp-keystore 0.35.0", + "sp-panic-handler 13.0.0", + "sp-runtime 32.0.0", "sp-version", "thiserror", "tokio", @@ -11099,14 +11486,14 @@ dependencies = [ "sp-api", "sp-blockchain", "sp-consensus", - "sp-core", + "sp-core 29.0.0", "sp-database", - "sp-externalities", - "sp-runtime", - "sp-state-machine", + "sp-externalities 0.26.0", + "sp-runtime 32.0.0", + "sp-state-machine 0.36.0", "sp-statement-store", - "sp-storage", - "sp-trie", + "sp-storage 20.0.0", + "sp-trie 30.0.0", "substrate-prometheus-endpoint", ] @@ -11128,13 +11515,13 @@ dependencies = [ "sc-client-api", "sc-state-db", "schnellru", - "sp-arithmetic", + "sp-arithmetic 24.0.0", "sp-blockchain", - "sp-core", + "sp-core 29.0.0", "sp-database", - "sp-runtime", - "sp-state-machine", - "sp-trie", + "sp-runtime 32.0.0", + "sp-state-machine 0.36.0", + "sp-trie 30.0.0", ] [[package]] @@ -11156,9 +11543,9 @@ dependencies = [ "sp-api", "sp-blockchain", "sp-consensus", - "sp-core", - "sp-runtime", - "sp-state-machine", + "sp-core 29.0.0", + "sp-runtime 32.0.0", + "sp-state-machine 0.36.0", "substrate-prometheus-endpoint", "thiserror", ] @@ -11179,16 +11566,16 @@ dependencies = [ "sc-consensus-slots", "sc-telemetry", "sp-api", - "sp-application-crypto", + "sp-application-crypto 31.0.0", "sp-block-builder", "sp-blockchain", "sp-consensus", "sp-consensus-aura", "sp-consensus-slots", - "sp-core", + "sp-core 29.0.0", "sp-inherents", - "sp-keystore", - "sp-runtime", + "sp-keystore 0.35.0", + "sp-runtime 32.0.0", "substrate-prometheus-endpoint", "thiserror", ] @@ -11215,17 +11602,17 @@ dependencies = [ "sc-telemetry", "sc-transaction-pool-api", "sp-api", - "sp-application-crypto", + "sp-application-crypto 31.0.0", "sp-block-builder", "sp-blockchain", "sp-consensus", "sp-consensus-babe", "sp-consensus-slots", - "sp-core", + "sp-core 29.0.0", "sp-crypto-hashing", "sp-inherents", - "sp-keystore", - "sp-runtime", + "sp-keystore 0.35.0", + "sp-runtime 32.0.0", "substrate-prometheus-endpoint", "thiserror", ] @@ -11243,13 +11630,13 @@ dependencies = [ "sc-rpc-api", "serde", "sp-api", - "sp-application-crypto", + "sp-application-crypto 31.0.0", "sp-blockchain", "sp-consensus", "sp-consensus-babe", - "sp-core", - "sp-keystore", - "sp-runtime", + "sp-core 29.0.0", + "sp-keystore 0.35.0", + "sp-runtime 32.0.0", "thiserror", ] @@ -11274,16 +11661,16 @@ dependencies = [ "sc-network-sync", "sc-utils", "sp-api", - "sp-application-crypto", - "sp-arithmetic", + "sp-application-crypto 31.0.0", + "sp-arithmetic 24.0.0", "sp-blockchain", "sp-consensus", "sp-consensus-beefy", - "sp-core", + "sp-core 29.0.0", "sp-crypto-hashing", - "sp-keystore", + "sp-keystore 0.35.0", "sp-mmr-primitives", - "sp-runtime", + "sp-runtime 32.0.0", "substrate-prometheus-endpoint", "thiserror", "tokio", @@ -11305,8 +11692,8 @@ dependencies = [ "sc-rpc", "serde", "sp-consensus-beefy", - "sp-core", - "sp-runtime", + "sp-core 29.0.0", + "sp-runtime 32.0.0", "thiserror", ] @@ -11321,7 +11708,7 @@ dependencies = [ "sc-client-api", "sc-consensus", "sp-blockchain", - "sp-runtime", + "sp-runtime 32.0.0", ] [[package]] @@ -11341,7 +11728,7 @@ dependencies = [ "log", "parity-scale-codec", "parking_lot 0.12.1", - "rand", + "rand 0.8.5", "sc-block-builder", "sc-chain-spec", "sc-client-api", @@ -11355,15 +11742,15 @@ dependencies = [ "sc-utils", "serde_json", "sp-api", - "sp-application-crypto", - "sp-arithmetic", + "sp-application-crypto 31.0.0", + "sp-arithmetic 24.0.0", "sp-blockchain", "sp-consensus", "sp-consensus-grandpa", - "sp-core", + "sp-core 29.0.0", "sp-crypto-hashing", - "sp-keystore", - "sp-runtime", + "sp-keystore 0.35.0", + "sp-runtime 32.0.0", "substrate-prometheus-endpoint", "thiserror", ] @@ -11384,8 +11771,8 @@ dependencies = [ "sc-rpc", "serde", "sp-blockchain", - "sp-core", - "sp-runtime", + "sp-core 29.0.0", + "sp-runtime 32.0.0", "thiserror", ] @@ -11403,14 +11790,14 @@ dependencies = [ "sc-client-api", "sc-consensus", "sc-telemetry", - "sp-arithmetic", + "sp-arithmetic 24.0.0", "sp-blockchain", "sp-consensus", "sp-consensus-slots", - "sp-core", + "sp-core 29.0.0", "sp-inherents", - "sp-runtime", - "sp-state-machine", + "sp-runtime 32.0.0", + "sp-state-machine 0.36.0", ] [[package]] @@ -11425,14 +11812,14 @@ dependencies = [ "sc-executor-wasmtime", "schnellru", "sp-api", - "sp-core", - "sp-externalities", - "sp-io", - "sp-panic-handler", - "sp-runtime-interface", - "sp-trie", + "sp-core 29.0.0", + "sp-externalities 0.26.0", + "sp-io 31.0.0", + "sp-panic-handler 13.0.0", + "sp-runtime-interface 25.0.0", + "sp-trie 30.0.0", "sp-version", - "sp-wasm-interface", + "sp-wasm-interface 20.0.0", "tracing", ] @@ -11444,7 +11831,7 @@ checksum = "07498138dee3ddf2c71299ca372d8449880bb3a8a8a299a483094e9c26b0823e" dependencies = [ "sc-allocator", "sp-maybe-compressed-blob", - "sp-wasm-interface", + "sp-wasm-interface 20.0.0", "thiserror", "wasm-instrument", ] @@ -11463,8 +11850,8 @@ dependencies = [ "rustix 0.36.17", "sc-allocator", "sc-executor-common", - "sp-runtime-interface", - "sp-wasm-interface", + "sp-runtime-interface 25.0.0", + "sp-wasm-interface 20.0.0", "wasmtime", ] @@ -11483,7 +11870,7 @@ dependencies = [ "sc-network-common", "sc-network-sync", "sp-blockchain", - "sp-runtime", + "sp-runtime 32.0.0", ] [[package]] @@ -11495,9 +11882,9 @@ dependencies = [ "array-bytes 6.2.2", "parking_lot 0.12.1", "serde_json", - "sp-application-crypto", - "sp-core", - "sp-keystore", + "sp-application-crypto 31.0.0", + "sp-core 29.0.0", + "sp-keystore 0.35.0", "thiserror", ] @@ -11524,10 +11911,10 @@ dependencies = [ "sc-transaction-pool-api", "sp-api", "sp-consensus", - "sp-core", - "sp-keystore", + "sp-core 29.0.0", + "sp-keystore 0.35.0", "sp-mixnet", - "sp-runtime", + "sp-runtime 32.0.0", "thiserror", ] @@ -11555,17 +11942,17 @@ dependencies = [ "parking_lot 0.12.1", "partial_sort", "pin-project", - "rand", + "rand 0.8.5", "sc-client-api", "sc-network-common", "sc-utils", "serde", "serde_json", "smallvec", - "sp-arithmetic", + "sp-arithmetic 24.0.0", "sp-blockchain", - "sp-core", - "sp-runtime", + "sp-core 29.0.0", + "sp-runtime 32.0.0", "substrate-prometheus-endpoint", "thiserror", "tokio", @@ -11591,7 +11978,7 @@ dependencies = [ "sc-client-api", "sc-network", "sp-blockchain", - "sp-runtime", + "sp-runtime 32.0.0", "thiserror", "unsigned-varint", ] @@ -11611,7 +11998,7 @@ dependencies = [ "sc-consensus", "sp-consensus", "sp-consensus-grandpa", - "sp-runtime", + "sp-runtime 32.0.0", ] [[package]] @@ -11629,7 +12016,7 @@ dependencies = [ "sc-network-common", "sc-network-sync", "schnellru", - "sp-runtime", + "sp-runtime 32.0.0", "substrate-prometheus-endpoint", "tracing", ] @@ -11651,8 +12038,8 @@ dependencies = [ "sc-client-api", "sc-network", "sp-blockchain", - "sp-core", - "sp-runtime", + "sp-core 29.0.0", + "sp-runtime 32.0.0", "thiserror", ] @@ -11681,12 +12068,12 @@ dependencies = [ "sc-utils", "schnellru", "smallvec", - "sp-arithmetic", + "sp-arithmetic 24.0.0", "sp-blockchain", "sp-consensus", "sp-consensus-grandpa", - "sp-core", - "sp-runtime", + "sp-core 29.0.0", + "sp-runtime 32.0.0", "substrate-prometheus-endpoint", "thiserror", "tokio", @@ -11709,7 +12096,7 @@ dependencies = [ "sc-network-sync", "sc-utils", "sp-consensus", - "sp-runtime", + "sp-runtime 32.0.0", "substrate-prometheus-endpoint", ] @@ -11732,18 +12119,18 @@ dependencies = [ "once_cell", "parity-scale-codec", "parking_lot 0.12.1", - "rand", + "rand 0.8.5", "sc-client-api", "sc-network", "sc-network-common", "sc-transaction-pool-api", "sc-utils", "sp-api", - "sp-core", - "sp-externalities", - "sp-keystore", + "sp-core 29.0.0", + "sp-externalities 0.26.0", + "sp-keystore 0.35.0", "sp-offchain", - "sp-runtime", + "sp-runtime 32.0.0", "threadpool", "tracing", ] @@ -11780,11 +12167,11 @@ dependencies = [ "serde_json", "sp-api", "sp-blockchain", - "sp-core", - "sp-keystore", + "sp-core 29.0.0", + "sp-keystore 0.35.0", "sp-offchain", "sp-rpc", - "sp-runtime", + "sp-runtime 32.0.0", "sp-session", "sp-statement-store", "sp-version", @@ -11805,9 +12192,9 @@ dependencies = [ "scale-info", "serde", "serde_json", - "sp-core", + "sp-core 29.0.0", "sp-rpc", - "sp-runtime", + "sp-runtime 32.0.0", "sp-version", "thiserror", ] @@ -11850,9 +12237,9 @@ dependencies = [ "serde", "sp-api", "sp-blockchain", - "sp-core", + "sp-core 29.0.0", "sp-rpc", - "sp-runtime", + "sp-runtime 32.0.0", "sp-version", "thiserror", "tokio", @@ -11875,7 +12262,7 @@ dependencies = [ "parity-scale-codec", "parking_lot 0.12.1", "pin-project", - "rand", + "rand 0.8.5", "sc-chain-spec", "sc-client-api", "sc-client-db", @@ -11903,16 +12290,16 @@ dependencies = [ "sp-api", "sp-blockchain", "sp-consensus", - "sp-core", - "sp-externalities", - "sp-keystore", - "sp-runtime", + "sp-core 29.0.0", + "sp-externalities 0.26.0", + "sp-keystore 0.35.0", + "sp-runtime 32.0.0", "sp-session", - "sp-state-machine", - "sp-storage", + "sp-state-machine 0.36.0", + "sp-storage 20.0.0", "sp-transaction-pool", "sp-transaction-storage-proof", - "sp-trie", + "sp-trie 30.0.0", "sp-version", "static_init", "substrate-prometheus-endpoint", @@ -11932,7 +12319,7 @@ dependencies = [ "log", "parity-scale-codec", "parking_lot 0.12.1", - "sp-core", + "sp-core 29.0.0", ] [[package]] @@ -11944,7 +12331,7 @@ dependencies = [ "clap", "fs4", "log", - "sp-core", + "sp-core 29.0.0", "thiserror", "tokio", ] @@ -11965,7 +12352,7 @@ dependencies = [ "serde", "serde_json", "sp-blockchain", - "sp-runtime", + "sp-runtime 32.0.0", "thiserror", ] @@ -11979,16 +12366,16 @@ dependencies = [ "futures", "libc", "log", - "rand", + "rand 0.8.5", "rand_pcg", "regex", "sc-telemetry", "serde", "serde_json", - "sp-core", + "sp-core 29.0.0", "sp-crypto-hashing", - "sp-io", - "sp-std", + "sp-io 31.0.0", + "sp-std 14.0.0", ] [[package]] @@ -12003,7 +12390,7 @@ dependencies = [ "log", "parking_lot 0.12.1", "pin-project", - "rand", + "rand 0.8.5", "sc-utils", "serde", "serde_json", @@ -12032,10 +12419,10 @@ dependencies = [ "serde", "sp-api", "sp-blockchain", - "sp-core", + "sp-core 29.0.0", "sp-rpc", - "sp-runtime", - "sp-tracing", + "sp-runtime 32.0.0", + "sp-tracing 16.0.0", "thiserror", "tracing", "tracing-log 0.1.4", @@ -12073,10 +12460,10 @@ dependencies = [ "serde", "sp-api", "sp-blockchain", - "sp-core", + "sp-core 29.0.0", "sp-crypto-hashing", - "sp-runtime", - "sp-tracing", + "sp-runtime 32.0.0", + "sp-tracing 16.0.0", "sp-transaction-pool", "substrate-prometheus-endpoint", "thiserror", @@ -12094,8 +12481,8 @@ dependencies = [ "parity-scale-codec", "serde", "sp-blockchain", - "sp-core", - "sp-runtime", + "sp-core 29.0.0", + "sp-runtime 32.0.0", "thiserror", ] @@ -12112,7 +12499,7 @@ dependencies = [ "log", "parking_lot 0.12.1", "prometheus", - "sp-arithmetic", + "sp-arithmetic 24.0.0", ] [[package]] @@ -12193,6 +12580,7 @@ dependencies = [ "derive_more", "parity-scale-codec", "scale-info-derive", + "schemars", "serde", ] @@ -12250,6 +12638,30 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "schemars" +version = "0.8.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09c024468a378b7e36765cd36702b7a90cc3cba11654f6685c8f233408e89e92" +dependencies = [ + "dyn-clone", + "schemars_derive", + "serde", + "serde_json", +] + +[[package]] +name = "schemars_derive" +version = "0.8.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1eee588578aff73f856ab961cd2f79e36bc45d7ded33a7562adba4667aecc0e" +dependencies = [ + "proc-macro2", + "quote", + "serde_derive_internals", + "syn 2.0.58", +] + [[package]] name = "schnellru" version = "0.2.1" @@ -12261,6 +12673,24 @@ dependencies = [ "hashbrown 0.13.2", ] +[[package]] +name = "schnorrkel" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "021b403afe70d81eea68f6ea12f6b3c9588e5d536a94c3bf80f15e7faa267862" +dependencies = [ + "arrayref", + "arrayvec 0.5.2", + "curve25519-dalek 2.1.3", + "getrandom 0.1.16", + "merlin 2.0.1", + "rand 0.7.3", + "rand_core 0.5.1", + "sha2 0.8.2", + "subtle 2.5.0", + "zeroize", +] + [[package]] name = "schnorrkel" version = "0.10.2" @@ -12270,7 +12700,7 @@ dependencies = [ "arrayref", "arrayvec 0.7.4", "curve25519-dalek-ng", - "merlin", + "merlin 3.0.0", "rand_core 0.6.4", "sha2 0.9.9", "subtle-ng", @@ -12288,7 +12718,7 @@ dependencies = [ "arrayvec 0.7.4", "curve25519-dalek 4.1.2", "getrandom_or_panic", - "merlin", + "merlin 3.0.0", "rand_core 0.6.4", "serde_bytes", "sha2 0.10.8", @@ -12341,13 +12771,31 @@ dependencies = [ "libc", ] +[[package]] +name = "secp256k1" +version = "0.24.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b1629c9c557ef9b293568b338dddfc8208c98a18c59d722a9d53f859d9c9b62" +dependencies = [ + "secp256k1-sys 0.6.1", +] + [[package]] name = "secp256k1" version = "0.28.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d24b59d129cdadea20aea4fb2352fa053712e5d713eee47d700cd4b2bc002f10" dependencies = [ - "secp256k1-sys", + "secp256k1-sys 0.9.2", +] + +[[package]] +name = "secp256k1-sys" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83080e2c2fc1006e625be82e5d1eb6a43b7fd9578b617fcc55814daf286bba4b" +dependencies = [ + "cc", ] [[package]] @@ -12453,6 +12901,17 @@ dependencies = [ "syn 2.0.58", ] +[[package]] +name = "serde_derive_internals" +version = "0.29.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18d26a20a969b9e3fdf2fc2d9f21eda6c40e2de84c9408bb5d3b05d499aae711" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.58", +] + [[package]] name = "serde_json" version = "1.0.115" @@ -12497,6 +12956,18 @@ dependencies = [ "digest 0.10.7", ] +[[package]] +name = "sha2" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a256f46ea78a0c0d9ff00077504903ac881a1dafdc20da66545699e7776b3e69" +dependencies = [ + "block-buffer 0.7.3", + "digest 0.8.1", + "fake-simd", + "opaque-debug 0.2.3", +] + [[package]] name = "sha2" version = "0.9.9" @@ -12555,6 +13026,12 @@ dependencies = [ "libc", ] +[[package]] +name = "signature" +version = "1.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" + [[package]] name = "signature" version = "2.2.0" @@ -12620,8 +13097,8 @@ dependencies = [ "enumn", "parity-scale-codec", "paste", - "sp-runtime", - "sp-std", + "sp-runtime 32.0.0", + "sp-std 14.0.0", ] [[package]] @@ -12700,7 +13177,7 @@ dependencies = [ "hmac 0.12.1", "itertools 0.11.0", "libsecp256k1", - "merlin", + "merlin 3.0.0", "no-std-net", "nom", "num-bigint", @@ -12709,7 +13186,7 @@ dependencies = [ "pbkdf2 0.12.2", "pin-project", "poly1305", - "rand", + "rand 0.8.5", "rand_chacha 0.3.1", "ruzstd 0.4.0", "schnorrkel 0.10.2", @@ -12755,7 +13232,7 @@ dependencies = [ "itertools 0.12.1", "libm", "libsecp256k1", - "merlin", + "merlin 3.0.0", "no-std-net", "nom", "num-bigint", @@ -12764,7 +13241,7 @@ dependencies = [ "pbkdf2 0.12.2", "pin-project", "poly1305", - "rand", + "rand 0.8.5", "rand_chacha 0.3.1", "ruzstd 0.5.0", "schnorrkel 0.11.4", @@ -12807,7 +13284,7 @@ dependencies = [ "no-std-net", "parking_lot 0.12.1", "pin-project", - "rand", + "rand 0.8.5", "rand_chacha 0.3.1", "serde", "serde_json", @@ -12843,7 +13320,7 @@ dependencies = [ "no-std-net", "parking_lot 0.12.1", "pin-project", - "rand", + "rand 0.8.5", "rand_chacha 0.3.1", "serde", "serde_json", @@ -12903,10 +13380,10 @@ dependencies = [ "serde", "snowbridge-ethereum", "snowbridge-milagro-bls", - "sp-core", - "sp-io", - "sp-runtime", - "sp-std", + "sp-core 29.0.0", + "sp-io 31.0.0", + "sp-runtime 32.0.0", + "sp-std 14.0.0", "ssz_rs", "ssz_rs_derive", "static_assertions", @@ -12927,11 +13404,11 @@ dependencies = [ "scale-info", "serde", "snowbridge-beacon-primitives", - "sp-arithmetic", - "sp-core", - "sp-io", - "sp-runtime", - "sp-std", + "sp-arithmetic 24.0.0", + "sp-core 29.0.0", + "sp-io 31.0.0", + "sp-runtime 32.0.0", + "sp-std 14.0.0", "staging-xcm", "staging-xcm-builder", ] @@ -12953,10 +13430,10 @@ dependencies = [ "scale-info", "serde", "serde-big-array", - "sp-core", - "sp-io", - "sp-runtime", - "sp-std", + "sp-core 29.0.0", + "sp-io 31.0.0", + "sp-runtime 32.0.0", + "sp-std 14.0.0", ] [[package]] @@ -12968,7 +13445,7 @@ dependencies = [ "hex", "lazy_static", "parity-scale-codec", - "rand", + "rand 0.8.5", "scale-info", "snowbridge-amcl", "zeroize", @@ -12989,10 +13466,10 @@ dependencies = [ "scale-info", "serde", "snowbridge-core", - "sp-core", - "sp-io", - "sp-runtime", - "sp-std", + "sp-core 29.0.0", + "sp-io 31.0.0", + "sp-runtime 32.0.0", + "sp-std 14.0.0", "staging-xcm", "staging-xcm-builder", "staging-xcm-executor", @@ -13031,7 +13508,7 @@ dependencies = [ "http", "httparse", "log", - "rand", + "rand 0.8.5", "sha-1", ] @@ -13046,13 +13523,13 @@ dependencies = [ "parity-scale-codec", "scale-info", "sp-api-proc-macro", - "sp-core", - "sp-externalities", + "sp-core 29.0.0", + "sp-externalities 0.26.0", "sp-metadata-ir", - "sp-runtime", - "sp-state-machine", - "sp-std", - "sp-trie", + "sp-runtime 32.0.0", + "sp-state-machine 0.36.0", + "sp-std 14.0.0", + "sp-trie 30.0.0", "sp-version", "thiserror", ] @@ -13072,6 +13549,20 @@ dependencies = [ "syn 2.0.58", ] +[[package]] +name = "sp-application-crypto" +version = "23.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "899492ea547816d5dfe9a5a2ecc32f65a7110805af6da3380aa4902371b31dc2" +dependencies = [ + "parity-scale-codec", + "scale-info", + "serde", + "sp-core 21.0.0", + "sp-io 23.0.0", + "sp-std 8.0.0", +] + [[package]] name = "sp-application-crypto" version = "31.0.0" @@ -13081,9 +13572,24 @@ dependencies = [ "parity-scale-codec", "scale-info", "serde", - "sp-core", - "sp-io", - "sp-std", + "sp-core 29.0.0", + "sp-io 31.0.0", + "sp-std 14.0.0", +] + +[[package]] +name = "sp-arithmetic" +version = "16.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb6020576e544c6824a51d651bc8df8e6ab67cd59f1c9ac09868bb81a5199ded" +dependencies = [ + "integer-sqrt", + "num-traits", + "parity-scale-codec", + "scale-info", + "serde", + "sp-std 8.0.0", + "static_assertions", ] [[package]] @@ -13097,7 +13603,7 @@ dependencies = [ "parity-scale-codec", "scale-info", "serde", - "sp-std", + "sp-std 14.0.0", "static_assertions", ] @@ -13110,9 +13616,9 @@ dependencies = [ "parity-scale-codec", "scale-info", "sp-api", - "sp-application-crypto", - "sp-runtime", - "sp-std", + "sp-application-crypto 31.0.0", + "sp-runtime 32.0.0", + "sp-std 14.0.0", ] [[package]] @@ -13123,8 +13629,8 @@ checksum = "1b36ce171caa7eb2bbe682c089f755fdefa71d3702e4fb1ba30d10146aef99d5" dependencies = [ "sp-api", "sp-inherents", - "sp-runtime", - "sp-std", + "sp-runtime 32.0.0", + "sp-std 14.0.0", ] [[package]] @@ -13141,8 +13647,8 @@ dependencies = [ "sp-api", "sp-consensus", "sp-database", - "sp-runtime", - "sp-state-machine", + "sp-runtime 32.0.0", + "sp-state-machine 0.36.0", "thiserror", ] @@ -13155,10 +13661,10 @@ dependencies = [ "async-trait", "futures", "log", - "sp-core", + "sp-core 29.0.0", "sp-inherents", - "sp-runtime", - "sp-state-machine", + "sp-runtime 32.0.0", + "sp-state-machine 0.36.0", "thiserror", ] @@ -13172,11 +13678,11 @@ dependencies = [ "parity-scale-codec", "scale-info", "sp-api", - "sp-application-crypto", + "sp-application-crypto 31.0.0", "sp-consensus-slots", "sp-inherents", - "sp-runtime", - "sp-std", + "sp-runtime 32.0.0", + "sp-std 14.0.0", "sp-timestamp", ] @@ -13191,12 +13697,12 @@ dependencies = [ "scale-info", "serde", "sp-api", - "sp-application-crypto", + "sp-application-crypto 31.0.0", "sp-consensus-slots", - "sp-core", + "sp-core 29.0.0", "sp-inherents", - "sp-runtime", - "sp-std", + "sp-runtime 32.0.0", + "sp-std 14.0.0", "sp-timestamp", ] @@ -13211,13 +13717,13 @@ dependencies = [ "scale-info", "serde", "sp-api", - "sp-application-crypto", - "sp-core", + "sp-application-crypto 31.0.0", + "sp-core 29.0.0", "sp-crypto-hashing", - "sp-io", + "sp-io 31.0.0", "sp-mmr-primitives", - "sp-runtime", - "sp-std", + "sp-runtime 32.0.0", + "sp-std 14.0.0", "strum 0.24.1", ] @@ -13233,11 +13739,11 @@ dependencies = [ "scale-info", "serde", "sp-api", - "sp-application-crypto", - "sp-core", - "sp-keystore", - "sp-runtime", - "sp-std", + "sp-application-crypto 31.0.0", + "sp-core 29.0.0", + "sp-keystore 0.35.0", + "sp-runtime 32.0.0", + "sp-std 14.0.0", ] [[package]] @@ -13249,10 +13755,55 @@ dependencies = [ "parity-scale-codec", "scale-info", "serde", - "sp-std", + "sp-std 14.0.0", "sp-timestamp", ] +[[package]] +name = "sp-core" +version = "21.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f18d9e2f67d8661f9729f35347069ac29d92758b59135176799db966947a7336" +dependencies = [ + "array-bytes 4.2.0", + "bitflags 1.3.2", + "blake2 0.10.6", + "bounded-collections 0.1.9", + "bs58 0.4.0", + "dyn-clonable", + "ed25519-zebra 3.1.0", + "futures", + "hash-db", + "hash256-std-hasher", + "impl-serde", + "lazy_static", + "libsecp256k1", + "log", + "merlin 2.0.1", + "parity-scale-codec", + "parking_lot 0.12.1", + "paste", + "primitive-types", + "rand 0.8.5", + "regex", + "scale-info", + "schnorrkel 0.9.1", + "secp256k1 0.24.3", + "secrecy", + "serde", + "sp-core-hashing 9.0.0", + "sp-debug-derive 8.0.0", + "sp-externalities 0.19.0", + "sp-runtime-interface 17.0.0", + "sp-std 8.0.0", + "sp-storage 13.0.0", + "ss58-registry", + "substrate-bip39", + "thiserror", + "tiny-bip39", + "zeroize", +] + [[package]] name = "sp-core" version = "29.0.0" @@ -13274,23 +13825,23 @@ dependencies = [ "itertools 0.10.5", "libsecp256k1", "log", - "merlin", + "merlin 3.0.0", "parity-scale-codec", "parking_lot 0.12.1", "paste", "primitive-types", - "rand", + "rand 0.8.5", "scale-info", "schnorrkel 0.11.4", - "secp256k1", + "secp256k1 0.28.2", "secrecy", "serde", "sp-crypto-hashing", - "sp-debug-derive", - "sp-externalities", - "sp-runtime-interface", - "sp-std", - "sp-storage", + "sp-debug-derive 14.0.0", + "sp-externalities 0.26.0", + "sp-runtime-interface 25.0.0", + "sp-std 14.0.0", + "sp-storage 20.0.0", "ss58-registry", "substrate-bip39", "thiserror", @@ -13299,6 +13850,21 @@ dependencies = [ "zeroize", ] +[[package]] +name = "sp-core-hashing" +version = "9.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ee599a8399448e65197f9a6cee338ad192e9023e35e31f22382964c3c174c68" +dependencies = [ + "blake2b_simd", + "byteorder", + "digest 0.10.7", + "sha2 0.10.8", + "sha3", + "sp-std 8.0.0", + "twox-hash", +] + [[package]] name = "sp-core-hashing" version = "15.0.0" @@ -13348,6 +13914,17 @@ dependencies = [ "parking_lot 0.12.1", ] +[[package]] +name = "sp-debug-derive" +version = "8.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7f531814d2f16995144c74428830ccf7d94ff4a7749632b83ad8199b181140c" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.58", +] + [[package]] name = "sp-debug-derive" version = "14.0.0" @@ -13359,6 +13936,18 @@ dependencies = [ "syn 2.0.58", ] +[[package]] +name = "sp-externalities" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0f71c671e01a8ca60da925d43a1b351b69626e268b8837f8371e320cf1dd100" +dependencies = [ + "environmental", + "parity-scale-codec", + "sp-std 8.0.0", + "sp-storage 13.0.0", +] + [[package]] name = "sp-externalities" version = "0.26.0" @@ -13367,8 +13956,8 @@ checksum = "e7096ed024cec397804864898b093b51e14c7299f1d00c67dd5800330e02bb82" dependencies = [ "environmental", "parity-scale-codec", - "sp-std", - "sp-storage", + "sp-std 14.0.0", + "sp-storage 20.0.0", ] [[package]] @@ -13379,8 +13968,8 @@ checksum = "fd865540ec19479c7349b584ccd78cc34c3f3a628a2a69dbb6365ceec36295ee" dependencies = [ "serde_json", "sp-api", - "sp-runtime", - "sp-std", + "sp-runtime 32.0.0", + "sp-std 14.0.0", ] [[package]] @@ -13393,11 +13982,38 @@ dependencies = [ "impl-trait-for-tuples", "parity-scale-codec", "scale-info", - "sp-runtime", - "sp-std", + "sp-runtime 32.0.0", + "sp-std 14.0.0", "thiserror", ] +[[package]] +name = "sp-io" +version = "23.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d597e35a9628fe7454b08965b2442e3ec0f264b0a90d41328e87422cec02e99" +dependencies = [ + "bytes", + "ed25519 1.5.3", + "ed25519-dalek 1.0.1", + "futures", + "libsecp256k1", + "log", + "parity-scale-codec", + "rustversion", + "secp256k1 0.24.3", + "sp-core 21.0.0", + "sp-externalities 0.19.0", + "sp-keystore 0.27.0", + "sp-runtime-interface 17.0.0", + "sp-state-machine 0.28.0", + "sp-std 8.0.0", + "sp-tracing 10.0.0", + "sp-trie 22.0.0", + "tracing", + "tracing-core", +] + [[package]] name = "sp-io" version = "31.0.0" @@ -13405,21 +14021,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec43aa073eab35fcb920d7592474d5427ea3be2bf938706a3ad955d7ba54fd8d" dependencies = [ "bytes", - "ed25519-dalek", + "ed25519-dalek 2.1.1", "libsecp256k1", "log", "parity-scale-codec", "rustversion", - "secp256k1", - "sp-core", + "secp256k1 0.28.2", + "sp-core 29.0.0", "sp-crypto-hashing", - "sp-externalities", - "sp-keystore", - "sp-runtime-interface", - "sp-state-machine", - "sp-std", - "sp-tracing", - "sp-trie", + "sp-externalities 0.26.0", + "sp-keystore 0.35.0", + "sp-runtime-interface 25.0.0", + "sp-state-machine 0.36.0", + "sp-std 14.0.0", + "sp-tracing 16.0.0", + "sp-trie 30.0.0", "tracing", "tracing-core", ] @@ -13430,11 +14046,25 @@ version = "32.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "69cf0a2f881958466fc92bc9b39bbc2c0d815ded4a21f8f953372b0ac2e11b02" dependencies = [ - "sp-core", - "sp-runtime", + "sp-core 29.0.0", + "sp-runtime 32.0.0", "strum 0.24.1", ] +[[package]] +name = "sp-keystore" +version = "0.27.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9be3cdd67cc1d9c1db17c5cbc4ec4924054a8437009d167f21f6590797e4aa45" +dependencies = [ + "futures", + "parity-scale-codec", + "parking_lot 0.12.1", + "sp-core 21.0.0", + "sp-externalities 0.19.0", + "thiserror", +] + [[package]] name = "sp-keystore" version = "0.35.0" @@ -13443,8 +14073,8 @@ checksum = "444f2d53968b1ce5e908882710ff1f3873fcf3e95f59d57432daf685bbacb959" dependencies = [ "parity-scale-codec", "parking_lot 0.12.1", - "sp-core", - "sp-externalities", + "sp-core 29.0.0", + "sp-externalities 0.26.0", "thiserror", ] @@ -13467,7 +14097,7 @@ dependencies = [ "frame-metadata 16.0.0", "parity-scale-codec", "scale-info", - "sp-std", + "sp-std 14.0.0", ] [[package]] @@ -13479,8 +14109,8 @@ dependencies = [ "parity-scale-codec", "scale-info", "sp-api", - "sp-application-crypto", - "sp-std", + "sp-application-crypto 31.0.0", + "sp-std 14.0.0", ] [[package]] @@ -13495,10 +14125,10 @@ dependencies = [ "scale-info", "serde", "sp-api", - "sp-core", - "sp-debug-derive", - "sp-runtime", - "sp-std", + "sp-core 29.0.0", + "sp-debug-derive 14.0.0", + "sp-runtime 32.0.0", + "sp-std 14.0.0", "thiserror", ] @@ -13511,10 +14141,10 @@ dependencies = [ "parity-scale-codec", "scale-info", "serde", - "sp-arithmetic", - "sp-core", - "sp-runtime", - "sp-std", + "sp-arithmetic 24.0.0", + "sp-core 29.0.0", + "sp-runtime 32.0.0", + "sp-std 14.0.0", ] [[package]] @@ -13524,8 +14154,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4d83b955dce0b6d143bec3f60571311168f362b1c16cf044da7037a407b66c19" dependencies = [ "sp-api", - "sp-core", - "sp-runtime", + "sp-core 29.0.0", + "sp-runtime 32.0.0", +] + +[[package]] +name = "sp-panic-handler" +version = "8.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebd2de46003fa8212426838ca71cd42ee36a26480ba9ffea983506ce03131033" +dependencies = [ + "backtrace", + "lazy_static", + "regex", ] [[package]] @@ -13547,7 +14188,30 @@ checksum = "9af4b73fe7ddd88b1641cca90048c4e525e721763199e6fd29c4f590884f4d16" dependencies = [ "rustc-hash", "serde", - "sp-core", + "sp-core 29.0.0", +] + +[[package]] +name = "sp-runtime" +version = "24.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21c5bfc764a1a8259d7e8f7cfd22c84006275a512c958d3ff966c92151e134d5" +dependencies = [ + "either", + "hash256-std-hasher", + "impl-trait-for-tuples", + "log", + "parity-scale-codec", + "paste", + "rand 0.8.5", + "scale-info", + "serde", + "sp-application-crypto 23.0.0", + "sp-arithmetic 16.0.0", + "sp-core 21.0.0", + "sp-io 23.0.0", + "sp-std 8.0.0", + "sp-weights 20.0.0", ] [[package]] @@ -13563,16 +14227,35 @@ dependencies = [ "log", "parity-scale-codec", "paste", - "rand", + "rand 0.8.5", "scale-info", "serde", "simple-mermaid", - "sp-application-crypto", - "sp-arithmetic", - "sp-core", - "sp-io", - "sp-std", - "sp-weights", + "sp-application-crypto 31.0.0", + "sp-arithmetic 24.0.0", + "sp-core 29.0.0", + "sp-io 31.0.0", + "sp-std 14.0.0", + "sp-weights 28.0.0", +] + +[[package]] +name = "sp-runtime-interface" +version = "17.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e676128182f90015e916f806cba635c8141e341e7abbc45d25525472e1bbce8" +dependencies = [ + "bytes", + "impl-trait-for-tuples", + "parity-scale-codec", + "primitive-types", + "sp-externalities 0.19.0", + "sp-runtime-interface-proc-macro 11.0.0", + "sp-std 8.0.0", + "sp-storage 13.0.0", + "sp-tracing 10.0.0", + "sp-wasm-interface 14.0.0", + "static_assertions", ] [[package]] @@ -13585,15 +14268,28 @@ dependencies = [ "impl-trait-for-tuples", "parity-scale-codec", "primitive-types", - "sp-externalities", - "sp-runtime-interface-proc-macro", - "sp-std", - "sp-storage", - "sp-tracing", - "sp-wasm-interface", + "sp-externalities 0.26.0", + "sp-runtime-interface-proc-macro 17.0.0", + "sp-std 14.0.0", + "sp-storage 20.0.0", + "sp-tracing 16.0.0", + "sp-wasm-interface 20.0.0", "static_assertions", ] +[[package]] +name = "sp-runtime-interface-proc-macro" +version = "11.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5d5bd5566fe5633ec48dfa35ab152fd29f8a577c21971e1c6db9f28afb9bbb9" +dependencies = [ + "Inflector", + "proc-macro-crate 1.3.1", + "proc-macro2", + "quote", + "syn 2.0.58", +] + [[package]] name = "sp-runtime-interface-proc-macro" version = "17.0.0" @@ -13617,11 +14313,11 @@ dependencies = [ "parity-scale-codec", "scale-info", "sp-api", - "sp-core", - "sp-keystore", - "sp-runtime", + "sp-core 29.0.0", + "sp-keystore 0.35.0", + "sp-runtime 32.0.0", "sp-staking", - "sp-std", + "sp-std 14.0.0", ] [[package]] @@ -13634,9 +14330,30 @@ dependencies = [ "parity-scale-codec", "scale-info", "serde", - "sp-core", - "sp-runtime", - "sp-std", + "sp-core 29.0.0", + "sp-runtime 32.0.0", + "sp-std 14.0.0", +] + +[[package]] +name = "sp-state-machine" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ef45d31f9e7ac648f8899a0cd038a3608f8499028bff55b6c799702592325b6" +dependencies = [ + "hash-db", + "log", + "parity-scale-codec", + "parking_lot 0.12.1", + "rand 0.8.5", + "smallvec", + "sp-core 21.0.0", + "sp-externalities 0.19.0", + "sp-panic-handler 8.0.0", + "sp-std 8.0.0", + "sp-trie 22.0.0", + "thiserror", + "tracing", ] [[package]] @@ -13649,16 +14366,16 @@ dependencies = [ "log", "parity-scale-codec", "parking_lot 0.12.1", - "rand", + "rand 0.8.5", "smallvec", - "sp-core", - "sp-externalities", - "sp-panic-handler", - "sp-std", - "sp-trie", + "sp-core 29.0.0", + "sp-externalities 0.26.0", + "sp-panic-handler 13.0.0", + "sp-std 14.0.0", + "sp-trie 30.0.0", "thiserror", "tracing", - "trie-db", + "trie-db 0.28.0", ] [[package]] @@ -13669,30 +14386,50 @@ checksum = "309a9ae4e8134bbed8ffc510cf4d461a4a651f9250b556de782cedd876abe1ff" dependencies = [ "aes-gcm", "curve25519-dalek 4.1.2", - "ed25519-dalek", + "ed25519-dalek 2.1.1", "hkdf", "parity-scale-codec", - "rand", + "rand 0.8.5", "scale-info", "sha2 0.10.8", "sp-api", - "sp-application-crypto", - "sp-core", + "sp-application-crypto 31.0.0", + "sp-core 29.0.0", "sp-crypto-hashing", - "sp-externalities", - "sp-runtime", - "sp-runtime-interface", - "sp-std", + "sp-externalities 0.26.0", + "sp-runtime 32.0.0", + "sp-runtime-interface 25.0.0", + "sp-std 14.0.0", "thiserror", "x25519-dalek 2.0.1", ] +[[package]] +name = "sp-std" +version = "8.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53458e3c57df53698b3401ec0934bea8e8cfce034816873c0b0abbd83d7bac0d" + [[package]] name = "sp-std" version = "14.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "12f8ee986414b0a9ad741776762f4083cd3a5128449b982a3919c4df36874834" +[[package]] +name = "sp-storage" +version = "13.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94294be83f11d4958cfea89ed5798f0b6605f5defc3a996948848458abbcc18e" +dependencies = [ + "impl-serde", + "parity-scale-codec", + "ref-cast", + "serde", + "sp-debug-derive 8.0.0", + "sp-std 8.0.0", +] + [[package]] name = "sp-storage" version = "20.0.0" @@ -13703,8 +14440,8 @@ dependencies = [ "parity-scale-codec", "ref-cast", "serde", - "sp-debug-derive", - "sp-std", + "sp-debug-derive 14.0.0", + "sp-std 14.0.0", ] [[package]] @@ -13716,11 +14453,24 @@ dependencies = [ "async-trait", "parity-scale-codec", "sp-inherents", - "sp-runtime", - "sp-std", + "sp-runtime 32.0.0", + "sp-std 14.0.0", "thiserror", ] +[[package]] +name = "sp-tracing" +version = "10.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "357f7591980dd58305956d32f8f6646d0a8ea9ea0e7e868e46f53b68ddf00cec" +dependencies = [ + "parity-scale-codec", + "sp-std 8.0.0", + "tracing", + "tracing-core", + "tracing-subscriber 0.2.25", +] + [[package]] name = "sp-tracing" version = "16.0.0" @@ -13728,7 +14478,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0351810b9d074df71c4514c5228ed05c250607cba131c1c9d1526760ab69c05c" dependencies = [ "parity-scale-codec", - "sp-std", + "sp-std 14.0.0", "tracing", "tracing-core", "tracing-subscriber 0.2.25", @@ -13741,7 +14491,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9742861c5330bdcb42856a6eed3d3745b58ee1c92ca4c9260032ff4e6c387165" dependencies = [ "sp-api", - "sp-runtime", + "sp-runtime 32.0.0", ] [[package]] @@ -13753,11 +14503,35 @@ dependencies = [ "async-trait", "parity-scale-codec", "scale-info", - "sp-core", + "sp-core 29.0.0", "sp-inherents", - "sp-runtime", - "sp-std", - "sp-trie", + "sp-runtime 32.0.0", + "sp-std 14.0.0", + "sp-trie 30.0.0", +] + +[[package]] +name = "sp-trie" +version = "22.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48e4eeb7ef23f79eba8609db79ef9cef242f994f1f87a3c0387b4b5f177fda74" +dependencies = [ + "ahash 0.8.11", + "hash-db", + "hashbrown 0.13.2", + "lazy_static", + "memory-db", + "nohash-hasher", + "parity-scale-codec", + "parking_lot 0.12.1", + "scale-info", + "schnellru", + "sp-core 21.0.0", + "sp-std 8.0.0", + "thiserror", + "tracing", + "trie-db 0.27.1", + "trie-root", ] [[package]] @@ -13773,15 +14547,15 @@ dependencies = [ "nohash-hasher", "parity-scale-codec", "parking_lot 0.12.1", - "rand", + "rand 0.8.5", "scale-info", "schnellru", - "sp-core", - "sp-externalities", - "sp-std", + "sp-core 29.0.0", + "sp-externalities 0.26.0", + "sp-std 14.0.0", "thiserror", "tracing", - "trie-db", + "trie-db 0.28.0", "trie-root", ] @@ -13797,8 +14571,8 @@ dependencies = [ "scale-info", "serde", "sp-crypto-hashing-proc-macro", - "sp-runtime", - "sp-std", + "sp-runtime 32.0.0", + "sp-std 14.0.0", "sp-version-proc-macro", "thiserror", ] @@ -13815,6 +14589,20 @@ dependencies = [ "syn 2.0.58", ] +[[package]] +name = "sp-wasm-interface" +version = "14.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a19c122609ca5d8246be6386888596320d03c7bc880959eaa2c36bcd5acd6846" +dependencies = [ + "anyhow", + "impl-trait-for-tuples", + "log", + "parity-scale-codec", + "sp-std 8.0.0", + "wasmtime", +] + [[package]] name = "sp-wasm-interface" version = "20.0.0" @@ -13825,10 +14613,26 @@ dependencies = [ "impl-trait-for-tuples", "log", "parity-scale-codec", - "sp-std", + "sp-std 14.0.0", "wasmtime", ] +[[package]] +name = "sp-weights" +version = "20.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45d084c735544f70625b821c3acdbc7a2fc1893ca98b85f1942631284692c75b" +dependencies = [ + "parity-scale-codec", + "scale-info", + "serde", + "smallvec", + "sp-arithmetic 16.0.0", + "sp-core 21.0.0", + "sp-debug-derive 8.0.0", + "sp-std 8.0.0", +] + [[package]] name = "sp-weights" version = "28.0.0" @@ -13840,9 +14644,9 @@ dependencies = [ "scale-info", "serde", "smallvec", - "sp-arithmetic", - "sp-debug-derive", - "sp-std", + "sp-arithmetic 24.0.0", + "sp-debug-derive 14.0.0", + "sp-std 14.0.0", ] [[package]] @@ -13933,8 +14737,8 @@ dependencies = [ "frame-system", "parity-scale-codec", "scale-info", - "sp-runtime", - "sp-std", + "sp-runtime 32.0.0", + "sp-std 14.0.0", ] [[package]] @@ -13952,7 +14756,7 @@ dependencies = [ "parity-scale-codec", "scale-info", "serde", - "sp-weights", + "sp-weights 28.0.0", "xcm-procedural", ] @@ -13970,11 +14774,11 @@ dependencies = [ "parity-scale-codec", "polkadot-parachain-primitives", "scale-info", - "sp-arithmetic", - "sp-io", - "sp-runtime", - "sp-std", - "sp-weights", + "sp-arithmetic 24.0.0", + "sp-io 31.0.0", + "sp-runtime 32.0.0", + "sp-std 14.0.0", + "sp-weights 28.0.0", "staging-xcm", "staging-xcm-executor", ] @@ -13992,12 +14796,12 @@ dependencies = [ "log", "parity-scale-codec", "scale-info", - "sp-arithmetic", - "sp-core", - "sp-io", - "sp-runtime", - "sp-std", - "sp-weights", + "sp-arithmetic 24.0.0", + "sp-core 29.0.0", + "sp-io 31.0.0", + "sp-runtime 32.0.0", + "sp-std 14.0.0", + "sp-weights 28.0.0", "staging-xcm", ] @@ -14136,8 +14940,8 @@ dependencies = [ "sp-api", "sp-block-builder", "sp-blockchain", - "sp-core", - "sp-runtime", + "sp-core 29.0.0", + "sp-runtime 32.0.0", ] [[package]] @@ -14164,7 +14968,7 @@ dependencies = [ "log", "sc-rpc-api", "serde", - "sp-runtime", + "sp-runtime 32.0.0", ] [[package]] @@ -14178,11 +14982,11 @@ dependencies = [ "sc-client-api", "sc-rpc-api", "serde", - "sp-core", - "sp-runtime", - "sp-state-machine", - "sp-trie", - "trie-db", + "sp-core 29.0.0", + "sp-runtime 32.0.0", + "sp-state-machine 0.36.0", + "sp-trie 30.0.0", + "trie-db 0.28.0", ] [[package]] @@ -14248,7 +15052,7 @@ dependencies = [ "scale-value", "serde", "serde_json", - "sp-core-hashing", + "sp-core-hashing 15.0.0", "subxt-lightclient", "subxt-macro", "subxt-metadata", @@ -14320,7 +15124,7 @@ dependencies = [ "frame-metadata 16.0.0", "parity-scale-codec", "scale-info", - "sp-core-hashing", + "sp-core-hashing 15.0.0", "thiserror", ] @@ -14337,10 +15141,10 @@ dependencies = [ "pbkdf2 0.12.2", "regex", "schnorrkel 0.11.4", - "secp256k1", + "secp256k1 0.28.2", "secrecy", "sha2 0.10.8", - "sp-core-hashing", + "sp-core-hashing 15.0.0", "subxt", "thiserror", "zeroize", @@ -14380,6 +15184,17 @@ dependencies = [ "unicode-xid", ] +[[package]] +name = "synstructure" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.58", +] + [[package]] name = "system-configuration" version = "0.5.1" @@ -14460,7 +15275,7 @@ dependencies = [ "polkadot-core-primitives", "rococo-runtime-constants", "smallvec", - "sp-runtime", + "sp-runtime 32.0.0", "staging-xcm", "westend-runtime-constants", ] @@ -14595,6 +15410,25 @@ dependencies = [ "time-core", ] +[[package]] +name = "tiny-bip39" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62cc94d358b5a1e84a5cb9109f559aa3c4d634d2b1b4de3d0fa4adc7c78e2861" +dependencies = [ + "anyhow", + "hmac 0.12.1", + "once_cell", + "pbkdf2 0.11.0", + "rand 0.8.5", + "rustc-hash", + "sha2 0.10.8", + "thiserror", + "unicode-normalization", + "wasm-bindgen", + "zeroize", +] + [[package]] name = "tiny-keccak" version = "2.0.2" @@ -14656,7 +15490,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f57eb36ecbe0fc510036adff84824dd3c24bb781e21bfa67b69d556aa85214f" dependencies = [ "pin-project", - "rand", + "rand 0.8.5", "tokio", ] @@ -14968,6 +15802,19 @@ dependencies = [ "tracing-log 0.2.0", ] +[[package]] +name = "trie-db" +version = "0.27.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "767abe6ffed88a1889671a102c2861ae742726f52e0a5a425b92c9fbfa7e9c85" +dependencies = [ + "hash-db", + "hashbrown 0.13.2", + "log", + "rustc-hex", + "smallvec", +] + [[package]] name = "trie-db" version = "0.28.0" @@ -15006,7 +15853,7 @@ dependencies = [ "idna 0.2.3", "ipnet", "lazy_static", - "rand", + "rand 0.8.5", "smallvec", "socket2 0.4.10", "thiserror", @@ -15062,19 +15909,19 @@ dependencies = [ "sp-api", "sp-consensus-aura", "sp-consensus-babe", - "sp-core", - "sp-debug-derive", - "sp-externalities", + "sp-core 29.0.0", + "sp-debug-derive 14.0.0", + "sp-externalities 0.26.0", "sp-inherents", - "sp-io", - "sp-keystore", + "sp-io 31.0.0", + "sp-keystore 0.35.0", "sp-rpc", - "sp-runtime", - "sp-state-machine", + "sp-runtime 32.0.0", + "sp-state-machine 0.36.0", "sp-timestamp", "sp-transaction-storage-proof", "sp-version", - "sp-weights", + "sp-weights 28.0.0", "substrate-rpc-client", "zstd 0.12.4", ] @@ -15093,7 +15940,7 @@ checksum = "97fee6b57c6a41524a810daee9286c02d7752c4253064d0b05472833a438f675" dependencies = [ "cfg-if", "digest 0.10.7", - "rand", + "rand 0.8.5", "static_assertions", ] @@ -15244,7 +16091,7 @@ dependencies = [ "arrayref", "constcat", "digest 0.10.7", - "rand", + "rand 0.8.5", "rand_chacha 0.3.1", "rand_core 0.6.4", "sha2 0.10.8", @@ -15654,7 +16501,7 @@ dependencies = [ "memfd", "memoffset", "paste", - "rand", + "rand 0.8.5", "rustix 0.36.17", "wasmtime-asm-macros", "wasmtime-environ", @@ -15783,24 +16630,24 @@ dependencies = [ "serde_derive", "smallvec", "sp-api", - "sp-application-crypto", - "sp-arithmetic", + "sp-application-crypto 31.0.0", + "sp-arithmetic 24.0.0", "sp-authority-discovery", "sp-block-builder", "sp-consensus-babe", "sp-consensus-beefy", - "sp-core", + "sp-core 29.0.0", "sp-genesis-builder", "sp-inherents", - "sp-io", + "sp-io 31.0.0", "sp-mmr-primitives", "sp-npos-elections", "sp-offchain", - "sp-runtime", + "sp-runtime 32.0.0", "sp-session", "sp-staking", - "sp-std", - "sp-storage", + "sp-std 14.0.0", + "sp-storage 20.0.0", "sp-transaction-pool", "sp-version", "staging-xcm", @@ -15820,9 +16667,9 @@ dependencies = [ "polkadot-primitives", "polkadot-runtime-common", "smallvec", - "sp-core", - "sp-runtime", - "sp-weights", + "sp-core 29.0.0", + "sp-runtime 32.0.0", + "sp-weights 28.0.0", "staging-xcm", "staging-xcm-builder", ] @@ -16214,13 +17061,13 @@ dependencies = [ "polkadot-parachain-primitives", "polkadot-primitives", "polkadot-runtime-parachains", - "sp-arithmetic", - "sp-core", + "sp-arithmetic 24.0.0", + "sp-core 29.0.0", "sp-crypto-hashing", - "sp-io", - "sp-runtime", - "sp-std", - "sp-tracing", + "sp-io 31.0.0", + "sp-runtime 32.0.0", + "sp-std 14.0.0", + "sp-tracing 16.0.0", "staging-xcm", "staging-xcm-executor", ] @@ -16237,6 +17084,12 @@ dependencies = [ "syn 2.0.58", ] +[[package]] +name = "xxhash-rust" +version = "0.8.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "927da81e25be1e1a2901d59b81b37dd2efd1fc9c9345a55007f09bf5a2d3ee03" + [[package]] name = "yamux" version = "0.10.2" @@ -16247,7 +17100,7 @@ dependencies = [ "log", "nohash-hasher", "parking_lot 0.12.1", - "rand", + "rand 0.8.5", "static_assertions", ] diff --git a/pop-api/examples/fungibles/expanded.rs b/pop-api/examples/fungibles/expanded.rs deleted file mode 100644 index c73cdeb7..00000000 --- a/pop-api/examples/fungibles/expanded.rs +++ /dev/null @@ -1,2766 +0,0 @@ -#![feature(prelude_import)] -#[prelude_import] -use std::prelude::rust_2021::*; -#[macro_use] -extern crate std; -use pop_api::{ - primitives::{AccountId as AccountId32, AssetId}, - assets::fungibles::*, -}; -pub enum FungiblesError { - /// Not enough balance to fulfill a request is available. - InsufficientBalance, - /// Not enough allowance to fulfill a request is available. - InsufficientAllowance, - /// The asset status is not the expected status. - IncorrectStatus, - /// The asset ID is already taken. - InUse, - /// Minimum balance should be non-zero. - MinBalanceZero, - /// The signing account has no permission to do the operation. - NoPermission, - /// The given asset ID is unknown. - Unknown, - /// Recipient's address is zero. - ZeroRecipientAddress, - /// Sender's address is zero. - ZeroSenderAddress, -} -#[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] -const _: () = { - impl ::scale_info::TypeInfo for FungiblesError { - type Identity = Self; - fn type_info() -> ::scale_info::Type { - ::scale_info::Type::builder() - .path( - ::scale_info::Path::new_with_replace( - "FungiblesError", - "fungibles", - &[], - ), - ) - .type_params(::alloc::vec::Vec::new()) - .variant( - ::scale_info::build::Variants::new() - .variant( - "InsufficientBalance", - |v| { - v - .index(0usize as ::core::primitive::u8) - .docs( - &["Not enough balance to fulfill a request is available."], - ) - }, - ) - .variant( - "InsufficientAllowance", - |v| { - v - .index(1usize as ::core::primitive::u8) - .docs( - &["Not enough allowance to fulfill a request is available."], - ) - }, - ) - .variant( - "IncorrectStatus", - |v| { - v - .index(2usize as ::core::primitive::u8) - .docs(&["The asset status is not the expected status."]) - }, - ) - .variant( - "InUse", - |v| { - v - .index(3usize as ::core::primitive::u8) - .docs(&["The asset ID is already taken."]) - }, - ) - .variant( - "MinBalanceZero", - |v| { - v - .index(4usize as ::core::primitive::u8) - .docs(&["Minimum balance should be non-zero."]) - }, - ) - .variant( - "NoPermission", - |v| { - v - .index(5usize as ::core::primitive::u8) - .docs( - &[ - "The signing account has no permission to do the operation.", - ], - ) - }, - ) - .variant( - "Unknown", - |v| { - v - .index(6usize as ::core::primitive::u8) - .docs(&["The given asset ID is unknown."]) - }, - ) - .variant( - "ZeroRecipientAddress", - |v| { - v - .index(7usize as ::core::primitive::u8) - .docs(&["Recipient's address is zero."]) - }, - ) - .variant( - "ZeroSenderAddress", - |v| { - v - .index(8usize as ::core::primitive::u8) - .docs(&["Sender's address is zero."]) - }, - ), - ) - } - } -}; -#[automatically_derived] -impl ::core::fmt::Debug for FungiblesError { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::write_str( - f, - match self { - FungiblesError::InsufficientBalance => "InsufficientBalance", - FungiblesError::InsufficientAllowance => "InsufficientAllowance", - FungiblesError::IncorrectStatus => "IncorrectStatus", - FungiblesError::InUse => "InUse", - FungiblesError::MinBalanceZero => "MinBalanceZero", - FungiblesError::NoPermission => "NoPermission", - FungiblesError::Unknown => "Unknown", - FungiblesError::ZeroRecipientAddress => "ZeroRecipientAddress", - FungiblesError::ZeroSenderAddress => "ZeroSenderAddress", - }, - ) - } -} -#[automatically_derived] -impl ::core::marker::Copy for FungiblesError {} -#[automatically_derived] -impl ::core::clone::Clone for FungiblesError { - #[inline] - fn clone(&self) -> FungiblesError { - *self - } -} -#[automatically_derived] -impl ::core::marker::StructuralPartialEq for FungiblesError {} -#[automatically_derived] -impl ::core::cmp::PartialEq for FungiblesError { - #[inline] - fn eq(&self, other: &FungiblesError) -> bool { - let __self_tag = ::core::intrinsics::discriminant_value(self); - let __arg1_tag = ::core::intrinsics::discriminant_value(other); - __self_tag == __arg1_tag - } -} -#[automatically_derived] -impl ::core::cmp::Eq for FungiblesError { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () {} -} -#[allow(deprecated)] -const _: () = { - #[automatically_derived] - impl ::scale::Encode for FungiblesError { - fn size_hint(&self) -> usize { - 1_usize - + match *self { - FungiblesError::InsufficientBalance => 0_usize, - FungiblesError::InsufficientAllowance => 0_usize, - FungiblesError::IncorrectStatus => 0_usize, - FungiblesError::InUse => 0_usize, - FungiblesError::MinBalanceZero => 0_usize, - FungiblesError::NoPermission => 0_usize, - FungiblesError::Unknown => 0_usize, - FungiblesError::ZeroRecipientAddress => 0_usize, - FungiblesError::ZeroSenderAddress => 0_usize, - _ => 0_usize, - } - } - fn encode_to<__CodecOutputEdqy: ::scale::Output + ?::core::marker::Sized>( - &self, - __codec_dest_edqy: &mut __CodecOutputEdqy, - ) { - match *self { - FungiblesError::InsufficientBalance => { - #[allow(clippy::unnecessary_cast)] - __codec_dest_edqy.push_byte(0usize as ::core::primitive::u8); - } - FungiblesError::InsufficientAllowance => { - #[allow(clippy::unnecessary_cast)] - __codec_dest_edqy.push_byte(1usize as ::core::primitive::u8); - } - FungiblesError::IncorrectStatus => { - #[allow(clippy::unnecessary_cast)] - __codec_dest_edqy.push_byte(2usize as ::core::primitive::u8); - } - FungiblesError::InUse => { - #[allow(clippy::unnecessary_cast)] - __codec_dest_edqy.push_byte(3usize as ::core::primitive::u8); - } - FungiblesError::MinBalanceZero => { - #[allow(clippy::unnecessary_cast)] - __codec_dest_edqy.push_byte(4usize as ::core::primitive::u8); - } - FungiblesError::NoPermission => { - #[allow(clippy::unnecessary_cast)] - __codec_dest_edqy.push_byte(5usize as ::core::primitive::u8); - } - FungiblesError::Unknown => { - #[allow(clippy::unnecessary_cast)] - __codec_dest_edqy.push_byte(6usize as ::core::primitive::u8); - } - FungiblesError::ZeroRecipientAddress => { - #[allow(clippy::unnecessary_cast)] - __codec_dest_edqy.push_byte(7usize as ::core::primitive::u8); - } - FungiblesError::ZeroSenderAddress => { - #[allow(clippy::unnecessary_cast)] - __codec_dest_edqy.push_byte(8usize as ::core::primitive::u8); - } - _ => {} - } - } - } - #[automatically_derived] - impl ::scale::EncodeLike for FungiblesError {} -}; -#[allow(deprecated)] -const _: () = { - #[automatically_derived] - impl ::scale::Decode for FungiblesError { - fn decode<__CodecInputEdqy: ::scale::Input>( - __codec_input_edqy: &mut __CodecInputEdqy, - ) -> ::core::result::Result { - match __codec_input_edqy - .read_byte() - .map_err(|e| { - e - .chain( - "Could not decode `FungiblesError`, failed to read variant byte", - ) - })? - { - #[allow(clippy::unnecessary_cast)] - __codec_x_edqy if __codec_x_edqy == 0usize as ::core::primitive::u8 => { - #[allow(clippy::redundant_closure_call)] - return (move || { - ::core::result::Result::Ok(FungiblesError::InsufficientBalance) - })(); - } - #[allow(clippy::unnecessary_cast)] - __codec_x_edqy if __codec_x_edqy == 1usize as ::core::primitive::u8 => { - #[allow(clippy::redundant_closure_call)] - return (move || { - ::core::result::Result::Ok(FungiblesError::InsufficientAllowance) - })(); - } - #[allow(clippy::unnecessary_cast)] - __codec_x_edqy if __codec_x_edqy == 2usize as ::core::primitive::u8 => { - #[allow(clippy::redundant_closure_call)] - return (move || { - ::core::result::Result::Ok(FungiblesError::IncorrectStatus) - })(); - } - #[allow(clippy::unnecessary_cast)] - __codec_x_edqy if __codec_x_edqy == 3usize as ::core::primitive::u8 => { - #[allow(clippy::redundant_closure_call)] - return (move || { - ::core::result::Result::Ok(FungiblesError::InUse) - })(); - } - #[allow(clippy::unnecessary_cast)] - __codec_x_edqy if __codec_x_edqy == 4usize as ::core::primitive::u8 => { - #[allow(clippy::redundant_closure_call)] - return (move || { - ::core::result::Result::Ok(FungiblesError::MinBalanceZero) - })(); - } - #[allow(clippy::unnecessary_cast)] - __codec_x_edqy if __codec_x_edqy == 5usize as ::core::primitive::u8 => { - #[allow(clippy::redundant_closure_call)] - return (move || { - ::core::result::Result::Ok(FungiblesError::NoPermission) - })(); - } - #[allow(clippy::unnecessary_cast)] - __codec_x_edqy if __codec_x_edqy == 6usize as ::core::primitive::u8 => { - #[allow(clippy::redundant_closure_call)] - return (move || { - ::core::result::Result::Ok(FungiblesError::Unknown) - })(); - } - #[allow(clippy::unnecessary_cast)] - __codec_x_edqy if __codec_x_edqy == 7usize as ::core::primitive::u8 => { - #[allow(clippy::redundant_closure_call)] - return (move || { - ::core::result::Result::Ok(FungiblesError::ZeroRecipientAddress) - })(); - } - #[allow(clippy::unnecessary_cast)] - __codec_x_edqy if __codec_x_edqy == 8usize as ::core::primitive::u8 => { - #[allow(clippy::redundant_closure_call)] - return (move || { - ::core::result::Result::Ok(FungiblesError::ZeroSenderAddress) - })(); - } - _ => { - #[allow(clippy::redundant_closure_call)] - return (move || { - ::core::result::Result::Err( - <_ as ::core::convert::Into< - _, - >>::into( - "Could not decode `FungiblesError`, variant doesn't exist", - ), - ) - })(); - } - } - } - } -}; -impl From for FungiblesError { - fn from(error: Error) -> Self { - match error { - Error::InUse => FungiblesError::InUse, - Error::MinBalanceZero => FungiblesError::MinBalanceZero, - Error::Unknown => FungiblesError::Unknown, - _ => ::core::panicking::panic("not yet implemented"), - } - } -} -/// The fungibles result type. -pub type Result = core::result::Result; -mod fungibles { - impl ::ink::env::ContractEnv for Fungibles { - type Env = pop_api::Environment; - } - type Environment = ::Env; - type AccountId = <::Env as ::ink::env::Environment>::AccountId; - type Balance = <::Env as ::ink::env::Environment>::Balance; - type Hash = <::Env as ::ink::env::Environment>::Hash; - type Timestamp = <::Env as ::ink::env::Environment>::Timestamp; - type BlockNumber = <::Env as ::ink::env::Environment>::BlockNumber; - type ChainExtension = <::Env as ::ink::env::Environment>::ChainExtension; - const MAX_EVENT_TOPICS: usize = <::Env as ::ink::env::Environment>::MAX_EVENT_TOPICS; - const _: () = { - struct Check { - salt: (), - } - }; - #[scale_info(crate = ::ink::scale_info)] - #[cfg(not(feature = "__ink_dylint_Storage"))] - pub struct Fungibles {} - const _: () = { - impl< - __ink_generic_salt: ::ink::storage::traits::StorageKey, - > ::ink::storage::traits::StorableHint<__ink_generic_salt> for Fungibles { - type Type = Fungibles; - type PreferredKey = ::ink::storage::traits::AutoKey; - } - }; - const _: () = { - impl ::ink::storage::traits::StorageKey for Fungibles { - const KEY: ::ink::primitives::Key = <() as ::ink::storage::traits::StorageKey>::KEY; - } - }; - const _: () = { - impl ::ink::storage::traits::Storable for Fungibles { - #[inline(always)] - #[allow(non_camel_case_types)] - fn decode<__ink_I: ::ink::scale::Input>( - __input: &mut __ink_I, - ) -> ::core::result::Result { - ::core::result::Result::Ok(Fungibles {}) - } - #[inline(always)] - #[allow(non_camel_case_types)] - fn encode<__ink_O: ::ink::scale::Output + ?::core::marker::Sized>( - &self, - __dest: &mut __ink_O, - ) { - match self { - Fungibles {} => {} - } - } - #[inline(always)] - #[allow(non_camel_case_types)] - fn encoded_size(&self) -> ::core::primitive::usize { - match self { - Fungibles {} => ::core::primitive::usize::MIN, - } - } - } - }; - #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] - const _: () = { - impl ::ink::scale_info::TypeInfo for Fungibles { - type Identity = Self; - fn type_info() -> ::ink::scale_info::Type { - ::ink::scale_info::Type::builder() - .path( - ::ink::scale_info::Path::new_with_replace( - "Fungibles", - "fungibles::fungibles", - &[], - ), - ) - .type_params(::alloc::vec::Vec::new()) - .composite(::ink::scale_info::build::Fields::named()) - } - } - }; - const _: () = { - impl ::ink::storage::traits::StorageLayout for Fungibles { - fn layout( - __key: &::ink::primitives::Key, - ) -> ::ink::metadata::layout::Layout { - ::ink::metadata::layout::Layout::Struct( - ::ink::metadata::layout::StructLayout::new("Fungibles", []), - ) - } - } - }; - #[automatically_derived] - impl ::core::default::Default for Fungibles { - #[inline] - fn default() -> Fungibles { - Fungibles {} - } - } - const _: () = { - impl ::ink::reflect::ContractName for Fungibles { - const NAME: &'static str = "Fungibles"; - } - }; - const _: () = { - impl<'a> ::ink::codegen::Env for &'a Fungibles { - type EnvAccess = ::ink::EnvAccess< - 'a, - ::Env, - >; - fn env(self) -> Self::EnvAccess { - <::EnvAccess as ::core::default::Default>::default() - } - } - impl<'a> ::ink::codegen::StaticEnv for Fungibles { - type EnvAccess = ::ink::EnvAccess< - 'static, - ::Env, - >; - fn env() -> Self::EnvAccess { - <::EnvAccess as ::core::default::Default>::default() - } - } - }; - const _: () = { - #[allow(unused_imports)] - use ::ink::codegen::{Env as _, StaticEnv as _}; - }; - impl ::ink::reflect::DispatchableConstructorInfo<0x9BAE9D5E_u32> for Fungibles { - type Input = (); - type Output = Self; - type Storage = Fungibles; - type Error = <::ink::reflect::ConstructorOutputValue< - Self, - > as ::ink::reflect::ConstructorOutput>::Error; - const IS_RESULT: ::core::primitive::bool = <::ink::reflect::ConstructorOutputValue< - Self, - > as ::ink::reflect::ConstructorOutput>::IS_RESULT; - const CALLABLE: fn(Self::Input) -> Self::Output = |_| { Fungibles::new() }; - const PAYABLE: ::core::primitive::bool = true; - const SELECTOR: [::core::primitive::u8; 4usize] = [ - 0x9B_u8, - 0xAE_u8, - 0x9D_u8, - 0x5E_u8, - ]; - const LABEL: &'static ::core::primitive::str = "new"; - } - impl ::ink::reflect::DispatchableMessageInfo<0xDB6375A8_u32> for Fungibles { - type Input = AssetId; - type Output = Result; - type Storage = Fungibles; - const CALLABLE: fn(&mut Self::Storage, Self::Input) -> Self::Output = | - storage, - __ink_binding_0| - { Fungibles::total_supply(storage, __ink_binding_0) }; - const SELECTOR: [::core::primitive::u8; 4usize] = [ - 0xDB_u8, - 0x63_u8, - 0x75_u8, - 0xA8_u8, - ]; - const PAYABLE: ::core::primitive::bool = false; - const MUTATES: ::core::primitive::bool = false; - const LABEL: &'static ::core::primitive::str = "total_supply"; - } - impl ::ink::reflect::DispatchableMessageInfo<0x0F755A56_u32> for Fungibles { - type Input = (AssetId, AccountId32); - type Output = Result; - type Storage = Fungibles; - const CALLABLE: fn(&mut Self::Storage, Self::Input) -> Self::Output = | - storage, - (__ink_binding_0, __ink_binding_1)| - { Fungibles::balance_of(storage, __ink_binding_0, __ink_binding_1) }; - const SELECTOR: [::core::primitive::u8; 4usize] = [ - 0x0F_u8, - 0x75_u8, - 0x5A_u8, - 0x56_u8, - ]; - const PAYABLE: ::core::primitive::bool = false; - const MUTATES: ::core::primitive::bool = false; - const LABEL: &'static ::core::primitive::str = "balance_of"; - } - impl ::ink::reflect::DispatchableMessageInfo<0x6A00165E_u32> for Fungibles { - type Input = (AssetId, AccountId32, AccountId32); - type Output = Result; - type Storage = Fungibles; - const CALLABLE: fn(&mut Self::Storage, Self::Input) -> Self::Output = | - storage, - (__ink_binding_0, __ink_binding_1, __ink_binding_2)| - { - Fungibles::allowance( - storage, - __ink_binding_0, - __ink_binding_1, - __ink_binding_2, - ) - }; - const SELECTOR: [::core::primitive::u8; 4usize] = [ - 0x6A_u8, - 0x00_u8, - 0x16_u8, - 0x5E_u8, - ]; - const PAYABLE: ::core::primitive::bool = false; - const MUTATES: ::core::primitive::bool = false; - const LABEL: &'static ::core::primitive::str = "allowance"; - } - impl ::ink::reflect::DispatchableMessageInfo<0xAA6B65DB_u32> for Fungibles { - type Input = AssetId; - type Output = Result; - type Storage = Fungibles; - const CALLABLE: fn(&mut Self::Storage, Self::Input) -> Self::Output = | - storage, - __ink_binding_0| - { Fungibles::asset_exists(storage, __ink_binding_0) }; - const SELECTOR: [::core::primitive::u8; 4usize] = [ - 0xAA_u8, - 0x6B_u8, - 0x65_u8, - 0xDB_u8, - ]; - const PAYABLE: ::core::primitive::bool = false; - const MUTATES: ::core::primitive::bool = false; - const LABEL: &'static ::core::primitive::str = "asset_exists"; - } - impl ::ink::reflect::DispatchableMessageInfo<0x1F8E8E22_u32> for Fungibles { - type Input = (u32, AccountId32, Balance); - type Output = Result<()>; - type Storage = Fungibles; - const CALLABLE: fn(&mut Self::Storage, Self::Input) -> Self::Output = | - storage, - (__ink_binding_0, __ink_binding_1, __ink_binding_2)| - { - Fungibles::mint_asset( - storage, - __ink_binding_0, - __ink_binding_1, - __ink_binding_2, - ) - }; - const SELECTOR: [::core::primitive::u8; 4usize] = [ - 0x1F_u8, - 0x8E_u8, - 0x8E_u8, - 0x22_u8, - ]; - const PAYABLE: ::core::primitive::bool = false; - const MUTATES: ::core::primitive::bool = false; - const LABEL: &'static ::core::primitive::str = "mint_asset"; - } - const _: () = { - #[allow(non_camel_case_types)] - pub enum __ink_ConstructorDecoder { - Constructor0( - >::Input, - ), - } - impl ::ink::reflect::DecodeDispatch for __ink_ConstructorDecoder { - fn decode_dispatch( - input: &mut I, - ) -> ::core::result::Result - where - I: ::ink::scale::Input, - { - const CONSTRUCTOR_0: [::core::primitive::u8; 4usize] = >::SELECTOR; - match <[::core::primitive::u8; 4usize] as ::ink::scale::Decode>::decode( - input, - ) - .map_err(|_| ::ink::reflect::DispatchError::InvalidSelector)? - { - CONSTRUCTOR_0 => { - ::core::result::Result::Ok( - Self::Constructor0( - <>::Input as ::ink::scale::Decode>::decode(input) - .map_err(|_| { - ::ink::reflect::DispatchError::InvalidParameters - })?, - ), - ) - } - _invalid => { - ::core::result::Result::Err( - ::ink::reflect::DispatchError::UnknownSelector, - ) - } - } - } - } - impl ::ink::scale::Decode for __ink_ConstructorDecoder { - fn decode( - input: &mut I, - ) -> ::core::result::Result - where - I: ::ink::scale::Input, - { - ::decode_dispatch(input) - .map_err(::core::convert::Into::into) - } - } - impl ::ink::reflect::ExecuteDispatchable for __ink_ConstructorDecoder { - #[allow(clippy::nonminimal_bool)] - fn execute_dispatchable( - self, - ) -> ::core::result::Result<(), ::ink::reflect::DispatchError> { - match self { - Self::Constructor0(input) => { - if { - false - || { - let constructor_0 = false; - let constructor_0 = >::PAYABLE; - constructor_0 - } - } - && !>::PAYABLE - { - ::ink::codegen::deny_payment::< - ::Env, - >()?; - } - let result: >::Output = >::CALLABLE(input); - let output_value = ::ink::reflect::ConstructorOutputValue::new( - result, - ); - let output_result = <::ink::reflect::ConstructorOutputValue< - >::Output, - > as ::ink::reflect::ConstructorOutput< - Fungibles, - >>::as_result(&output_value); - if let ::core::result::Result::Ok(contract) = output_result - .as_ref() - { - ::ink::env::set_contract_storage::< - ::ink::primitives::Key, - Fungibles, - >( - &::KEY, - contract, - ); - } - let mut flag = ::ink::env::ReturnFlags::empty(); - if output_result.is_err() { - flag = ::ink::env::ReturnFlags::REVERT; - } - ::ink::env::return_value::< - ::ink::ConstructorResult< - ::core::result::Result< - (), - &<::ink::reflect::ConstructorOutputValue< - >::Output, - > as ::ink::reflect::ConstructorOutput>::Error, - >, - >, - >( - flag, - &::ink::ConstructorResult::Ok(output_result.map(|_| ())), - ); - } - } - } - } - impl ::ink::reflect::ContractConstructorDecoder for Fungibles { - type Type = __ink_ConstructorDecoder; - } - }; - const _: () = { - #[allow(non_camel_case_types)] - pub enum __ink_MessageDecoder { - Message0( - >::Input, - ), - Message1( - >::Input, - ), - Message2( - >::Input, - ), - Message3( - >::Input, - ), - Message4( - >::Input, - ), - } - impl ::ink::reflect::DecodeDispatch for __ink_MessageDecoder { - fn decode_dispatch( - input: &mut I, - ) -> ::core::result::Result - where - I: ::ink::scale::Input, - { - const MESSAGE_0: [::core::primitive::u8; 4usize] = >::SELECTOR; - const MESSAGE_1: [::core::primitive::u8; 4usize] = >::SELECTOR; - const MESSAGE_2: [::core::primitive::u8; 4usize] = >::SELECTOR; - const MESSAGE_3: [::core::primitive::u8; 4usize] = >::SELECTOR; - const MESSAGE_4: [::core::primitive::u8; 4usize] = >::SELECTOR; - match <[::core::primitive::u8; 4usize] as ::ink::scale::Decode>::decode( - input, - ) - .map_err(|_| ::ink::reflect::DispatchError::InvalidSelector)? - { - MESSAGE_0 => { - ::core::result::Result::Ok( - Self::Message0( - <>::Input as ::ink::scale::Decode>::decode(input) - .map_err(|_| { - ::ink::reflect::DispatchError::InvalidParameters - })?, - ), - ) - } - MESSAGE_1 => { - ::core::result::Result::Ok( - Self::Message1( - <>::Input as ::ink::scale::Decode>::decode(input) - .map_err(|_| { - ::ink::reflect::DispatchError::InvalidParameters - })?, - ), - ) - } - MESSAGE_2 => { - ::core::result::Result::Ok( - Self::Message2( - <>::Input as ::ink::scale::Decode>::decode(input) - .map_err(|_| { - ::ink::reflect::DispatchError::InvalidParameters - })?, - ), - ) - } - MESSAGE_3 => { - ::core::result::Result::Ok( - Self::Message3( - <>::Input as ::ink::scale::Decode>::decode(input) - .map_err(|_| { - ::ink::reflect::DispatchError::InvalidParameters - })?, - ), - ) - } - MESSAGE_4 => { - ::core::result::Result::Ok( - Self::Message4( - <>::Input as ::ink::scale::Decode>::decode(input) - .map_err(|_| { - ::ink::reflect::DispatchError::InvalidParameters - })?, - ), - ) - } - _invalid => { - ::core::result::Result::Err( - ::ink::reflect::DispatchError::UnknownSelector, - ) - } - } - } - } - impl ::ink::scale::Decode for __ink_MessageDecoder { - fn decode( - input: &mut I, - ) -> ::core::result::Result - where - I: ::ink::scale::Input, - { - ::decode_dispatch(input) - .map_err(::core::convert::Into::into) - } - } - fn push_contract(contract: ::core::mem::ManuallyDrop, mutates: bool) { - if mutates { - ::ink::env::set_contract_storage::< - ::ink::primitives::Key, - Fungibles, - >(&::KEY, &contract); - } - } - impl ::ink::reflect::ExecuteDispatchable for __ink_MessageDecoder { - #[allow(clippy::nonminimal_bool, clippy::let_unit_value)] - fn execute_dispatchable( - self, - ) -> ::core::result::Result<(), ::ink::reflect::DispatchError> { - let key = ::KEY; - let mut contract: ::core::mem::ManuallyDrop = ::core::mem::ManuallyDrop::new( - match ::ink::env::get_contract_storage(&key) { - ::core::result::Result::Ok( - ::core::option::Option::Some(value), - ) => value, - ::core::result::Result::Ok(::core::option::Option::None) => { - ::core::panicking::panic_fmt( - format_args!("storage entry was empty"), - ); - } - ::core::result::Result::Err(_) => { - ::core::panicking::panic_fmt( - format_args!("could not properly decode storage entry"), - ); - } - }, - ); - match self { - Self::Message0(input) => { - if { - false - || { - let message_0 = false; - let message_0 = >::PAYABLE; - message_0 - } - || { - let message_1 = false; - let message_1 = >::PAYABLE; - message_1 - } - || { - let message_2 = false; - let message_2 = >::PAYABLE; - message_2 - } - || { - let message_3 = false; - let message_3 = >::PAYABLE; - message_3 - } - || { - let message_4 = false; - let message_4 = >::PAYABLE; - message_4 - } - } - && !>::PAYABLE - { - ::ink::codegen::deny_payment::< - ::Env, - >()?; - } - let result: >::Output = >::CALLABLE(&mut contract, input); - let is_reverted = { - #[allow(unused_imports)] - use ::ink::result_info::IsResultTypeFallback as _; - ::ink::result_info::IsResultType::< - >::Output, - >::VALUE - } - && { - #[allow(unused_imports)] - use ::ink::result_info::IsResultErrFallback as _; - ::ink::result_info::IsResultErr(&result).value() - }; - let mut flag = ::ink::env::ReturnFlags::REVERT; - if !is_reverted { - flag = ::ink::env::ReturnFlags::empty(); - push_contract( - contract, - >::MUTATES, - ); - } - ::ink::env::return_value::< - ::ink::MessageResult< - >::Output, - >, - >(flag, &::ink::MessageResult::Ok(result)) - } - Self::Message1(input) => { - if { - false - || { - let message_0 = false; - let message_0 = >::PAYABLE; - message_0 - } - || { - let message_1 = false; - let message_1 = >::PAYABLE; - message_1 - } - || { - let message_2 = false; - let message_2 = >::PAYABLE; - message_2 - } - || { - let message_3 = false; - let message_3 = >::PAYABLE; - message_3 - } - || { - let message_4 = false; - let message_4 = >::PAYABLE; - message_4 - } - } - && !>::PAYABLE - { - ::ink::codegen::deny_payment::< - ::Env, - >()?; - } - let result: >::Output = >::CALLABLE(&mut contract, input); - let is_reverted = { - #[allow(unused_imports)] - use ::ink::result_info::IsResultTypeFallback as _; - ::ink::result_info::IsResultType::< - >::Output, - >::VALUE - } - && { - #[allow(unused_imports)] - use ::ink::result_info::IsResultErrFallback as _; - ::ink::result_info::IsResultErr(&result).value() - }; - let mut flag = ::ink::env::ReturnFlags::REVERT; - if !is_reverted { - flag = ::ink::env::ReturnFlags::empty(); - push_contract( - contract, - >::MUTATES, - ); - } - ::ink::env::return_value::< - ::ink::MessageResult< - >::Output, - >, - >(flag, &::ink::MessageResult::Ok(result)) - } - Self::Message2(input) => { - if { - false - || { - let message_0 = false; - let message_0 = >::PAYABLE; - message_0 - } - || { - let message_1 = false; - let message_1 = >::PAYABLE; - message_1 - } - || { - let message_2 = false; - let message_2 = >::PAYABLE; - message_2 - } - || { - let message_3 = false; - let message_3 = >::PAYABLE; - message_3 - } - || { - let message_4 = false; - let message_4 = >::PAYABLE; - message_4 - } - } - && !>::PAYABLE - { - ::ink::codegen::deny_payment::< - ::Env, - >()?; - } - let result: >::Output = >::CALLABLE(&mut contract, input); - let is_reverted = { - #[allow(unused_imports)] - use ::ink::result_info::IsResultTypeFallback as _; - ::ink::result_info::IsResultType::< - >::Output, - >::VALUE - } - && { - #[allow(unused_imports)] - use ::ink::result_info::IsResultErrFallback as _; - ::ink::result_info::IsResultErr(&result).value() - }; - let mut flag = ::ink::env::ReturnFlags::REVERT; - if !is_reverted { - flag = ::ink::env::ReturnFlags::empty(); - push_contract( - contract, - >::MUTATES, - ); - } - ::ink::env::return_value::< - ::ink::MessageResult< - >::Output, - >, - >(flag, &::ink::MessageResult::Ok(result)) - } - Self::Message3(input) => { - if { - false - || { - let message_0 = false; - let message_0 = >::PAYABLE; - message_0 - } - || { - let message_1 = false; - let message_1 = >::PAYABLE; - message_1 - } - || { - let message_2 = false; - let message_2 = >::PAYABLE; - message_2 - } - || { - let message_3 = false; - let message_3 = >::PAYABLE; - message_3 - } - || { - let message_4 = false; - let message_4 = >::PAYABLE; - message_4 - } - } - && !>::PAYABLE - { - ::ink::codegen::deny_payment::< - ::Env, - >()?; - } - let result: >::Output = >::CALLABLE(&mut contract, input); - let is_reverted = { - #[allow(unused_imports)] - use ::ink::result_info::IsResultTypeFallback as _; - ::ink::result_info::IsResultType::< - >::Output, - >::VALUE - } - && { - #[allow(unused_imports)] - use ::ink::result_info::IsResultErrFallback as _; - ::ink::result_info::IsResultErr(&result).value() - }; - let mut flag = ::ink::env::ReturnFlags::REVERT; - if !is_reverted { - flag = ::ink::env::ReturnFlags::empty(); - push_contract( - contract, - >::MUTATES, - ); - } - ::ink::env::return_value::< - ::ink::MessageResult< - >::Output, - >, - >(flag, &::ink::MessageResult::Ok(result)) - } - Self::Message4(input) => { - if { - false - || { - let message_0 = false; - let message_0 = >::PAYABLE; - message_0 - } - || { - let message_1 = false; - let message_1 = >::PAYABLE; - message_1 - } - || { - let message_2 = false; - let message_2 = >::PAYABLE; - message_2 - } - || { - let message_3 = false; - let message_3 = >::PAYABLE; - message_3 - } - || { - let message_4 = false; - let message_4 = >::PAYABLE; - message_4 - } - } - && !>::PAYABLE - { - ::ink::codegen::deny_payment::< - ::Env, - >()?; - } - let result: >::Output = >::CALLABLE(&mut contract, input); - let is_reverted = { - #[allow(unused_imports)] - use ::ink::result_info::IsResultTypeFallback as _; - ::ink::result_info::IsResultType::< - >::Output, - >::VALUE - } - && { - #[allow(unused_imports)] - use ::ink::result_info::IsResultErrFallback as _; - ::ink::result_info::IsResultErr(&result).value() - }; - let mut flag = ::ink::env::ReturnFlags::REVERT; - if !is_reverted { - flag = ::ink::env::ReturnFlags::empty(); - push_contract( - contract, - >::MUTATES, - ); - } - ::ink::env::return_value::< - ::ink::MessageResult< - >::Output, - >, - >(flag, &::ink::MessageResult::Ok(result)) - } - }; - } - } - impl ::ink::reflect::ContractMessageDecoder for Fungibles { - type Type = __ink_MessageDecoder; - } - }; - const _: () = { - use ::ink::codegen::{Env as _, StaticEnv as _}; - const _: ::ink::codegen::utils::IsSameType = ::ink::codegen::utils::IsSameType::< - Fungibles, - >::new(); - impl Fungibles { - #[cfg(not(feature = "__ink_dylint_Constructor"))] - pub fn new() -> Self { - ::ink_env::debug_message( - &{ - let res = ::alloc::fmt::format( - format_args!( - "{0}\n", - { - let res = ::alloc::fmt::format( - format_args!("PopApiAssetsExample::new"), - ); - res - }, - ), - ); - res - }, - ); - Default::default() - } - pub fn total_supply(&self, id: AssetId) -> Result { - total_supply(id).map_err(From::from) - } - pub fn balance_of( - &self, - id: AssetId, - owner: AccountId32, - ) -> Result { - balance_of(id, owner).map_err(From::from) - } - pub fn allowance( - &self, - id: AssetId, - owner: AccountId32, - spender: AccountId32, - ) -> Result { - allowance(id, owner, spender).map_err(From::from) - } - pub fn asset_exists(&self, id: AssetId) -> Result { - asset_exists(id).map_err(From::from) - } - pub fn mint_asset( - &self, - id: u32, - beneficiary: AccountId32, - amount: Balance, - ) -> Result<()> { - ::ink_env::debug_message( - &{ - let res = ::alloc::fmt::format( - format_args!( - "{0}\n", - { - let res = ::alloc::fmt::format( - format_args!( - "PopApiAssetsExample::mint_asset_through_runtime: id: {0:?} beneficiary: {1:?} amount: {2:?}", - id, - beneficiary, - amount, - ), - ); - res - }, - ), - ); - res - }, - ); - let result = mint(id, beneficiary, amount)?; - ::ink_env::debug_message( - &{ - let res = ::alloc::fmt::format( - format_args!( - "{0}\n", - { - let res = ::alloc::fmt::format( - format_args!("Result: {0:?}", result), - ); - res - }, - ), - ); - res - }, - ); - Ok(()) - } - } - const _: () = { - ::ink::codegen::utils::consume_type::< - ::ink::codegen::DispatchInput, - >(); - ::ink::codegen::utils::consume_type::< - ::ink::codegen::DispatchOutput>, - >(); - ::ink::codegen::utils::consume_type::< - ::ink::codegen::DispatchInput, - >(); - ::ink::codegen::utils::consume_type::< - ::ink::codegen::DispatchInput, - >(); - ::ink::codegen::utils::consume_type::< - ::ink::codegen::DispatchOutput>, - >(); - ::ink::codegen::utils::consume_type::< - ::ink::codegen::DispatchInput, - >(); - ::ink::codegen::utils::consume_type::< - ::ink::codegen::DispatchInput, - >(); - ::ink::codegen::utils::consume_type::< - ::ink::codegen::DispatchInput, - >(); - ::ink::codegen::utils::consume_type::< - ::ink::codegen::DispatchOutput>, - >(); - ::ink::codegen::utils::consume_type::< - ::ink::codegen::DispatchInput, - >(); - ::ink::codegen::utils::consume_type::< - ::ink::codegen::DispatchOutput>, - >(); - ::ink::codegen::utils::consume_type::<::ink::codegen::DispatchInput>(); - ::ink::codegen::utils::consume_type::< - ::ink::codegen::DispatchInput, - >(); - ::ink::codegen::utils::consume_type::< - ::ink::codegen::DispatchInput, - >(); - ::ink::codegen::utils::consume_type::< - ::ink::codegen::DispatchOutput>, - >(); - }; - }; - const _: () = { - #[codec(crate = ::ink::scale)] - #[scale_info(crate = ::ink::scale_info)] - /// The ink! smart contract's call builder. - /// - /// Implements the underlying on-chain calling of the ink! smart contract - /// messages and trait implementations in a type safe way. - #[repr(transparent)] - pub struct CallBuilder { - account_id: AccountId, - } - #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] - const _: () = { - impl ::ink::scale_info::TypeInfo for CallBuilder { - type Identity = Self; - fn type_info() -> ::ink::scale_info::Type { - ::ink::scale_info::Type::builder() - .path( - ::ink::scale_info::Path::new_with_replace( - "CallBuilder", - "fungibles::fungibles", - &[], - ), - ) - .type_params(::alloc::vec::Vec::new()) - .docs( - &[ - "The ink! smart contract's call builder.", - "", - "Implements the underlying on-chain calling of the ink! smart contract", - "messages and trait implementations in a type safe way.", - ], - ) - .composite( - ::ink::scale_info::build::Fields::named() - .field(|f| { - f - .ty::() - .name("account_id") - .type_name("AccountId") - }), - ) - } - } - }; - #[allow(deprecated)] - const _: () = { - #[automatically_derived] - impl ::ink::scale::Decode for CallBuilder { - fn decode<__CodecInputEdqy: ::ink::scale::Input>( - __codec_input_edqy: &mut __CodecInputEdqy, - ) -> ::core::result::Result { - ::core::result::Result::Ok(CallBuilder { - account_id: { - let __codec_res_edqy = ::decode( - __codec_input_edqy, - ); - match __codec_res_edqy { - ::core::result::Result::Err(e) => { - return ::core::result::Result::Err( - e.chain("Could not decode `CallBuilder::account_id`"), - ); - } - ::core::result::Result::Ok(__codec_res_edqy) => { - __codec_res_edqy - } - } - }, - }) - } - fn decode_into<__CodecInputEdqy: ::ink::scale::Input>( - __codec_input_edqy: &mut __CodecInputEdqy, - dst_: &mut ::core::mem::MaybeUninit, - ) -> ::core::result::Result< - ::ink::scale::DecodeFinished, - ::ink::scale::Error, - > { - match ( - &::core::mem::size_of::(), - &::core::mem::size_of::(), - ) { - (left_val, right_val) => { - if !(*left_val == *right_val) { - let kind = ::core::panicking::AssertKind::Eq; - ::core::panicking::assert_failed( - kind, - &*left_val, - &*right_val, - ::core::option::Option::None, - ); - } - } - }; - if !(if ::core::mem::size_of::() > 0 { 1 } else { 0 } - <= 1) - { - ::core::panicking::panic( - "assertion failed: if ::core::mem::size_of::() > 0 { 1 } else { 0 } <= 1", - ) - } - { - let dst_: &mut ::core::mem::MaybeUninit = dst_; - let dst_: &mut ::core::mem::MaybeUninit = unsafe { - &mut *dst_ - .as_mut_ptr() - .cast::<::core::mem::MaybeUninit>() - }; - ::decode_into( - __codec_input_edqy, - dst_, - )?; - } - unsafe { - ::core::result::Result::Ok( - ::ink::scale::DecodeFinished::assert_decoding_finished(), - ) - } - } - } - }; - #[allow(deprecated)] - const _: () = { - #[automatically_derived] - impl ::ink::scale::Encode for CallBuilder { - fn size_hint(&self) -> usize { - ::ink::scale::Encode::size_hint(&&self.account_id) - } - fn encode_to< - __CodecOutputEdqy: ::ink::scale::Output + ?::core::marker::Sized, - >(&self, __codec_dest_edqy: &mut __CodecOutputEdqy) { - ::ink::scale::Encode::encode_to(&&self.account_id, __codec_dest_edqy) - } - fn encode( - &self, - ) -> ::ink::scale::alloc::vec::Vec<::core::primitive::u8> { - ::ink::scale::Encode::encode(&&self.account_id) - } - fn using_encoded< - __CodecOutputReturn, - __CodecUsingEncodedCallback: ::core::ops::FnOnce( - &[::core::primitive::u8], - ) -> __CodecOutputReturn, - >(&self, f: __CodecUsingEncodedCallback) -> __CodecOutputReturn { - ::ink::scale::Encode::using_encoded(&&self.account_id, f) - } - } - #[automatically_derived] - impl ::ink::scale::EncodeLike for CallBuilder {} - }; - #[automatically_derived] - impl ::core::fmt::Debug for CallBuilder { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_struct_field1_finish( - f, - "CallBuilder", - "account_id", - &&self.account_id, - ) - } - } - #[automatically_derived] - impl ::core::hash::Hash for CallBuilder { - #[inline] - fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () { - ::core::hash::Hash::hash(&self.account_id, state) - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for CallBuilder {} - #[automatically_derived] - impl ::core::cmp::PartialEq for CallBuilder { - #[inline] - fn eq(&self, other: &CallBuilder) -> bool { - self.account_id == other.account_id - } - } - #[automatically_derived] - impl ::core::cmp::Eq for CallBuilder { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { - let _: ::core::cmp::AssertParamIsEq; - } - } - #[automatically_derived] - impl ::core::clone::Clone for CallBuilder { - #[inline] - fn clone(&self) -> CallBuilder { - CallBuilder { - account_id: ::core::clone::Clone::clone(&self.account_id), - } - } - } - const _: () = { - impl ::ink::storage::traits::StorageLayout for CallBuilder { - fn layout( - __key: &::ink::primitives::Key, - ) -> ::ink::metadata::layout::Layout { - ::ink::metadata::layout::Layout::Struct( - ::ink::metadata::layout::StructLayout::new( - "CallBuilder", - [ - ::ink::metadata::layout::FieldLayout::new( - "account_id", - ::layout( - __key, - ), - ), - ], - ), - ) - } - } - }; - const _: () = { - impl ::ink::codegen::ContractCallBuilder for Fungibles { - type Type = CallBuilder; - } - impl ::ink::env::ContractEnv for CallBuilder { - type Env = ::Env; - } - }; - impl ::ink::env::call::FromAccountId for CallBuilder { - #[inline] - fn from_account_id(account_id: AccountId) -> Self { - Self { account_id } - } - } - impl ::ink::ToAccountId for CallBuilder { - #[inline] - fn to_account_id(&self) -> AccountId { - ::clone(&self.account_id) - } - } - impl ::core::convert::AsRef for CallBuilder { - fn as_ref(&self) -> &AccountId { - &self.account_id - } - } - impl ::core::convert::AsMut for CallBuilder { - fn as_mut(&mut self) -> &mut AccountId { - &mut self.account_id - } - } - impl CallBuilder { - #[allow(clippy::type_complexity)] - #[inline] - pub fn total_supply( - &self, - __ink_binding_0: AssetId, - ) -> ::ink::env::call::CallBuilder< - Environment, - ::ink::env::call::utils::Set<::ink::env::call::Call>, - ::ink::env::call::utils::Set< - ::ink::env::call::ExecutionInput< - ::ink::env::call::utils::ArgumentList< - ::ink::env::call::utils::Argument, - ::ink::env::call::utils::EmptyArgumentList, - >, - >, - >, - ::ink::env::call::utils::Set< - ::ink::env::call::utils::ReturnType>, - >, - > { - ::ink::env::call::build_call::() - .call(::ink::ToAccountId::to_account_id(self)) - .exec_input( - ::ink::env::call::ExecutionInput::new( - ::ink::env::call::Selector::new([ - 0xDB_u8, - 0x63_u8, - 0x75_u8, - 0xA8_u8, - ]), - ) - .push_arg(__ink_binding_0), - ) - .returns::>() - } - #[allow(clippy::type_complexity)] - #[inline] - pub fn balance_of( - &self, - __ink_binding_0: AssetId, - __ink_binding_1: AccountId32, - ) -> ::ink::env::call::CallBuilder< - Environment, - ::ink::env::call::utils::Set<::ink::env::call::Call>, - ::ink::env::call::utils::Set< - ::ink::env::call::ExecutionInput< - ::ink::env::call::utils::ArgumentList< - ::ink::env::call::utils::Argument, - ::ink::env::call::utils::ArgumentList< - ::ink::env::call::utils::Argument, - ::ink::env::call::utils::EmptyArgumentList, - >, - >, - >, - >, - ::ink::env::call::utils::Set< - ::ink::env::call::utils::ReturnType>, - >, - > { - ::ink::env::call::build_call::() - .call(::ink::ToAccountId::to_account_id(self)) - .exec_input( - ::ink::env::call::ExecutionInput::new( - ::ink::env::call::Selector::new([ - 0x0F_u8, - 0x75_u8, - 0x5A_u8, - 0x56_u8, - ]), - ) - .push_arg(__ink_binding_0) - .push_arg(__ink_binding_1), - ) - .returns::>() - } - #[allow(clippy::type_complexity)] - #[inline] - pub fn allowance( - &self, - __ink_binding_0: AssetId, - __ink_binding_1: AccountId32, - __ink_binding_2: AccountId32, - ) -> ::ink::env::call::CallBuilder< - Environment, - ::ink::env::call::utils::Set<::ink::env::call::Call>, - ::ink::env::call::utils::Set< - ::ink::env::call::ExecutionInput< - ::ink::env::call::utils::ArgumentList< - ::ink::env::call::utils::Argument, - ::ink::env::call::utils::ArgumentList< - ::ink::env::call::utils::Argument, - ::ink::env::call::utils::ArgumentList< - ::ink::env::call::utils::Argument, - ::ink::env::call::utils::EmptyArgumentList, - >, - >, - >, - >, - >, - ::ink::env::call::utils::Set< - ::ink::env::call::utils::ReturnType>, - >, - > { - ::ink::env::call::build_call::() - .call(::ink::ToAccountId::to_account_id(self)) - .exec_input( - ::ink::env::call::ExecutionInput::new( - ::ink::env::call::Selector::new([ - 0x6A_u8, - 0x00_u8, - 0x16_u8, - 0x5E_u8, - ]), - ) - .push_arg(__ink_binding_0) - .push_arg(__ink_binding_1) - .push_arg(__ink_binding_2), - ) - .returns::>() - } - #[allow(clippy::type_complexity)] - #[inline] - pub fn asset_exists( - &self, - __ink_binding_0: AssetId, - ) -> ::ink::env::call::CallBuilder< - Environment, - ::ink::env::call::utils::Set<::ink::env::call::Call>, - ::ink::env::call::utils::Set< - ::ink::env::call::ExecutionInput< - ::ink::env::call::utils::ArgumentList< - ::ink::env::call::utils::Argument, - ::ink::env::call::utils::EmptyArgumentList, - >, - >, - >, - ::ink::env::call::utils::Set< - ::ink::env::call::utils::ReturnType>, - >, - > { - ::ink::env::call::build_call::() - .call(::ink::ToAccountId::to_account_id(self)) - .exec_input( - ::ink::env::call::ExecutionInput::new( - ::ink::env::call::Selector::new([ - 0xAA_u8, - 0x6B_u8, - 0x65_u8, - 0xDB_u8, - ]), - ) - .push_arg(__ink_binding_0), - ) - .returns::>() - } - #[allow(clippy::type_complexity)] - #[inline] - pub fn mint_asset( - &self, - __ink_binding_0: u32, - __ink_binding_1: AccountId32, - __ink_binding_2: Balance, - ) -> ::ink::env::call::CallBuilder< - Environment, - ::ink::env::call::utils::Set<::ink::env::call::Call>, - ::ink::env::call::utils::Set< - ::ink::env::call::ExecutionInput< - ::ink::env::call::utils::ArgumentList< - ::ink::env::call::utils::Argument, - ::ink::env::call::utils::ArgumentList< - ::ink::env::call::utils::Argument, - ::ink::env::call::utils::ArgumentList< - ::ink::env::call::utils::Argument, - ::ink::env::call::utils::EmptyArgumentList, - >, - >, - >, - >, - >, - ::ink::env::call::utils::Set< - ::ink::env::call::utils::ReturnType>, - >, - > { - ::ink::env::call::build_call::() - .call(::ink::ToAccountId::to_account_id(self)) - .exec_input( - ::ink::env::call::ExecutionInput::new( - ::ink::env::call::Selector::new([ - 0x1F_u8, - 0x8E_u8, - 0x8E_u8, - 0x22_u8, - ]), - ) - .push_arg(__ink_binding_0) - .push_arg(__ink_binding_1) - .push_arg(__ink_binding_2), - ) - .returns::>() - } - } - }; - #[codec(crate = ::ink::scale)] - #[scale_info(crate = ::ink::scale_info)] - pub struct FungiblesRef { - inner: ::Type, - } - #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] - const _: () = { - impl ::ink::scale_info::TypeInfo for FungiblesRef { - type Identity = Self; - fn type_info() -> ::ink::scale_info::Type { - ::ink::scale_info::Type::builder() - .path( - ::ink::scale_info::Path::new_with_replace( - "FungiblesRef", - "fungibles::fungibles", - &[], - ), - ) - .type_params(::alloc::vec::Vec::new()) - .composite( - ::ink::scale_info::build::Fields::named() - .field(|f| { - f - .ty::< - ::Type, - >() - .name("inner") - .type_name( - "::Type", - ) - }), - ) - } - } - }; - #[allow(deprecated)] - const _: () = { - #[automatically_derived] - impl ::ink::scale::Decode for FungiblesRef { - fn decode<__CodecInputEdqy: ::ink::scale::Input>( - __codec_input_edqy: &mut __CodecInputEdqy, - ) -> ::core::result::Result { - ::core::result::Result::Ok(FungiblesRef { - inner: { - let __codec_res_edqy = <::Type as ::ink::scale::Decode>::decode( - __codec_input_edqy, - ); - match __codec_res_edqy { - ::core::result::Result::Err(e) => { - return ::core::result::Result::Err( - e.chain("Could not decode `FungiblesRef::inner`"), - ); - } - ::core::result::Result::Ok(__codec_res_edqy) => { - __codec_res_edqy - } - } - }, - }) - } - } - }; - #[allow(deprecated)] - const _: () = { - #[automatically_derived] - impl ::ink::scale::Encode for FungiblesRef { - fn size_hint(&self) -> usize { - ::ink::scale::Encode::size_hint(&&self.inner) - } - fn encode_to< - __CodecOutputEdqy: ::ink::scale::Output + ?::core::marker::Sized, - >(&self, __codec_dest_edqy: &mut __CodecOutputEdqy) { - ::ink::scale::Encode::encode_to(&&self.inner, __codec_dest_edqy) - } - fn encode(&self) -> ::ink::scale::alloc::vec::Vec<::core::primitive::u8> { - ::ink::scale::Encode::encode(&&self.inner) - } - fn using_encoded< - __CodecOutputReturn, - __CodecUsingEncodedCallback: ::core::ops::FnOnce( - &[::core::primitive::u8], - ) -> __CodecOutputReturn, - >(&self, f: __CodecUsingEncodedCallback) -> __CodecOutputReturn { - ::ink::scale::Encode::using_encoded(&&self.inner, f) - } - } - #[automatically_derived] - impl ::ink::scale::EncodeLike for FungiblesRef {} - }; - #[automatically_derived] - impl ::core::fmt::Debug for FungiblesRef { - #[inline] - fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::fmt::Formatter::debug_struct_field1_finish( - f, - "FungiblesRef", - "inner", - &&self.inner, - ) - } - } - #[automatically_derived] - impl ::core::hash::Hash for FungiblesRef { - #[inline] - fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () { - ::core::hash::Hash::hash(&self.inner, state) - } - } - #[automatically_derived] - impl ::core::marker::StructuralPartialEq for FungiblesRef {} - #[automatically_derived] - impl ::core::cmp::PartialEq for FungiblesRef { - #[inline] - fn eq(&self, other: &FungiblesRef) -> bool { - self.inner == other.inner - } - } - #[automatically_derived] - impl ::core::cmp::Eq for FungiblesRef { - #[inline] - #[doc(hidden)] - #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { - let _: ::core::cmp::AssertParamIsEq< - ::Type, - >; - } - } - #[automatically_derived] - impl ::core::clone::Clone for FungiblesRef { - #[inline] - fn clone(&self) -> FungiblesRef { - FungiblesRef { - inner: ::core::clone::Clone::clone(&self.inner), - } - } - } - const _: () = { - impl ::ink::storage::traits::StorageLayout for FungiblesRef { - fn layout( - __key: &::ink::primitives::Key, - ) -> ::ink::metadata::layout::Layout { - ::ink::metadata::layout::Layout::Struct( - ::ink::metadata::layout::StructLayout::new( - "FungiblesRef", - [ - ::ink::metadata::layout::FieldLayout::new( - "inner", - <::Type as ::ink::storage::traits::StorageLayout>::layout( - __key, - ), - ), - ], - ), - ) - } - } - }; - const _: () = { - impl ::ink::env::ContractReference for Fungibles { - type Type = FungiblesRef; - } - impl ::ink::env::call::ConstructorReturnType for Fungibles { - type Output = FungiblesRef; - type Error = (); - fn ok(value: FungiblesRef) -> Self::Output { - value - } - } - impl ::ink::env::call::ConstructorReturnType - for ::core::result::Result - where - E: ::ink::scale::Decode, - { - const IS_RESULT: bool = true; - type Output = ::core::result::Result; - type Error = E; - fn ok(value: FungiblesRef) -> Self::Output { - ::core::result::Result::Ok(value) - } - fn err(err: Self::Error) -> ::core::option::Option { - ::core::option::Option::Some(::core::result::Result::Err(err)) - } - } - impl ::ink::env::ContractEnv for FungiblesRef { - type Env = ::Env; - } - }; - impl FungiblesRef { - #[inline] - #[allow(clippy::type_complexity)] - pub fn new() -> ::ink::env::call::CreateBuilder< - Environment, - Self, - ::ink::env::call::utils::Unset, - ::ink::env::call::utils::Set< - ::ink::env::call::LimitParamsV2< - ::Env, - >, - >, - ::ink::env::call::utils::Unset, - ::ink::env::call::utils::Set< - ::ink::env::call::ExecutionInput< - ::ink::env::call::utils::EmptyArgumentList, - >, - >, - ::ink::env::call::utils::Unset<::ink::env::call::state::Salt>, - ::ink::env::call::utils::Set<::ink::env::call::utils::ReturnType>, - > { - ::ink::env::call::build_create::() - .exec_input( - ::ink::env::call::ExecutionInput::new( - ::ink::env::call::Selector::new([ - 0x9B_u8, - 0xAE_u8, - 0x9D_u8, - 0x5E_u8, - ]), - ), - ) - .returns::() - } - #[inline] - pub fn total_supply(&self, id: AssetId) -> Result { - self.try_total_supply(id) - .unwrap_or_else(|error| { - ::core::panicking::panic_fmt( - format_args!( - "encountered error while calling {0}::{1}: {2:?}", - "Fungibles", - "total_supply", - error, - ), - ); - }) - } - #[inline] - pub fn try_total_supply( - &self, - id: AssetId, - ) -> ::ink::MessageResult> { - ::call(self) - .total_supply(id) - .try_invoke() - .unwrap_or_else(|error| { - ::core::panicking::panic_fmt( - format_args!( - "encountered error while calling {0}::{1}: {2:?}", - "Fungibles", - "total_supply", - error, - ), - ); - }) - } - #[inline] - pub fn balance_of(&self, id: AssetId, owner: AccountId32) -> Result { - self.try_balance_of(id, owner) - .unwrap_or_else(|error| { - ::core::panicking::panic_fmt( - format_args!( - "encountered error while calling {0}::{1}: {2:?}", - "Fungibles", - "balance_of", - error, - ), - ); - }) - } - #[inline] - pub fn try_balance_of( - &self, - id: AssetId, - owner: AccountId32, - ) -> ::ink::MessageResult> { - ::call(self) - .balance_of(id, owner) - .try_invoke() - .unwrap_or_else(|error| { - ::core::panicking::panic_fmt( - format_args!( - "encountered error while calling {0}::{1}: {2:?}", - "Fungibles", - "balance_of", - error, - ), - ); - }) - } - #[inline] - pub fn allowance( - &self, - id: AssetId, - owner: AccountId32, - spender: AccountId32, - ) -> Result { - self.try_allowance(id, owner, spender) - .unwrap_or_else(|error| { - ::core::panicking::panic_fmt( - format_args!( - "encountered error while calling {0}::{1}: {2:?}", - "Fungibles", - "allowance", - error, - ), - ); - }) - } - #[inline] - pub fn try_allowance( - &self, - id: AssetId, - owner: AccountId32, - spender: AccountId32, - ) -> ::ink::MessageResult> { - ::call(self) - .allowance(id, owner, spender) - .try_invoke() - .unwrap_or_else(|error| { - ::core::panicking::panic_fmt( - format_args!( - "encountered error while calling {0}::{1}: {2:?}", - "Fungibles", - "allowance", - error, - ), - ); - }) - } - #[inline] - pub fn asset_exists(&self, id: AssetId) -> Result { - self.try_asset_exists(id) - .unwrap_or_else(|error| { - ::core::panicking::panic_fmt( - format_args!( - "encountered error while calling {0}::{1}: {2:?}", - "Fungibles", - "asset_exists", - error, - ), - ); - }) - } - #[inline] - pub fn try_asset_exists( - &self, - id: AssetId, - ) -> ::ink::MessageResult> { - ::call(self) - .asset_exists(id) - .try_invoke() - .unwrap_or_else(|error| { - ::core::panicking::panic_fmt( - format_args!( - "encountered error while calling {0}::{1}: {2:?}", - "Fungibles", - "asset_exists", - error, - ), - ); - }) - } - #[inline] - pub fn mint_asset( - &self, - id: u32, - beneficiary: AccountId32, - amount: Balance, - ) -> Result<()> { - self.try_mint_asset(id, beneficiary, amount) - .unwrap_or_else(|error| { - ::core::panicking::panic_fmt( - format_args!( - "encountered error while calling {0}::{1}: {2:?}", - "Fungibles", - "mint_asset", - error, - ), - ); - }) - } - #[inline] - pub fn try_mint_asset( - &self, - id: u32, - beneficiary: AccountId32, - amount: Balance, - ) -> ::ink::MessageResult> { - ::call(self) - .mint_asset(id, beneficiary, amount) - .try_invoke() - .unwrap_or_else(|error| { - ::core::panicking::panic_fmt( - format_args!( - "encountered error while calling {0}::{1}: {2:?}", - "Fungibles", - "mint_asset", - error, - ), - ); - }) - } - } - const _: () = { - impl ::ink::codegen::TraitCallBuilder for FungiblesRef { - type Builder = ::Type; - #[inline] - fn call(&self) -> &Self::Builder { - &self.inner - } - #[inline] - fn call_mut(&mut self) -> &mut Self::Builder { - &mut self.inner - } - } - }; - impl ::ink::env::call::FromAccountId for FungiblesRef { - #[inline] - fn from_account_id(account_id: AccountId) -> Self { - Self { - inner: <::Type as ::ink::env::call::FromAccountId< - Environment, - >>::from_account_id(account_id), - } - } - } - impl ::ink::ToAccountId for FungiblesRef { - #[inline] - fn to_account_id(&self) -> AccountId { - <::Type as ::ink::ToAccountId< - Environment, - >>::to_account_id(&self.inner) - } - } - impl ::core::convert::AsRef for FungiblesRef { - fn as_ref(&self) -> &AccountId { - <_ as ::core::convert::AsRef>::as_ref(&self.inner) - } - } - impl ::core::convert::AsMut for FungiblesRef { - fn as_mut(&mut self) -> &mut AccountId { - <_ as ::core::convert::AsMut>::as_mut(&mut self.inner) - } - } - #[cfg(feature = "std")] - #[cfg(not(feature = "ink-as-dependency"))] - const _: () = { - #[no_mangle] - pub fn __ink_generate_metadata() -> ::ink::metadata::InkProject { - let layout = ::ink::metadata::layout::Layout::Root( - ::ink::metadata::layout::RootLayout::new( - <::ink::metadata::layout::LayoutKey as ::core::convert::From< - ::ink::primitives::Key, - >>::from(::KEY), - ::layout( - &::KEY, - ), - ::ink::scale_info::meta_type::(), - ), - ); - ::ink::metadata::layout::ValidateLayout::validate(&layout) - .unwrap_or_else(|error| { - { - ::core::panicking::panic_fmt( - format_args!("metadata ink! generation failed: {0}", error), - ); - } - }); - ::ink::metadata::InkProject::new( - layout, - ::ink::metadata::ContractSpec::new() - .constructors([ - ::ink::metadata::ConstructorSpec::from_label("new") - .selector([0x9B_u8, 0xAE_u8, 0x9D_u8, 0x5E_u8]) - .args([]) - .payable(true) - .default(false) - .returns( - ::ink::metadata::ReturnTypeSpec::new( - if >::IS_RESULT { - ::ink::metadata::TypeSpec::with_name_str::< - ::ink::ConstructorResult< - ::core::result::Result< - (), - >::Error, - >, - >, - >("ink_primitives::ConstructorResult") - } else { - ::ink::metadata::TypeSpec::with_name_str::< - ::ink::ConstructorResult<()>, - >("ink_primitives::ConstructorResult") - }, - ), - ) - .docs([]) - .done(), - ]) - .messages([ - ::ink::metadata::MessageSpec::from_label("total_supply") - .selector([0xDB_u8, 0x63_u8, 0x75_u8, 0xA8_u8]) - .args([ - ::ink::metadata::MessageParamSpec::new("id") - .of_type( - ::ink::metadata::TypeSpec::with_name_segs::< - AssetId, - _, - >( - ::core::iter::Iterator::map( - ::core::iter::IntoIterator::into_iter(["AssetId"]), - ::core::convert::AsRef::as_ref, - ), - ), - ) - .done(), - ]) - .returns( - ::ink::metadata::ReturnTypeSpec::new( - ::ink::metadata::TypeSpec::with_name_segs::< - ::ink::MessageResult>, - _, - >( - ::core::iter::Iterator::map( - ::core::iter::IntoIterator::into_iter([ - "ink", - "MessageResult", - ]), - ::core::convert::AsRef::as_ref, - ), - ), - ), - ) - .mutates(false) - .payable(false) - .default(false) - .docs([]) - .done(), - ::ink::metadata::MessageSpec::from_label("balance_of") - .selector([0x0F_u8, 0x75_u8, 0x5A_u8, 0x56_u8]) - .args([ - ::ink::metadata::MessageParamSpec::new("id") - .of_type( - ::ink::metadata::TypeSpec::with_name_segs::< - AssetId, - _, - >( - ::core::iter::Iterator::map( - ::core::iter::IntoIterator::into_iter(["AssetId"]), - ::core::convert::AsRef::as_ref, - ), - ), - ) - .done(), - ::ink::metadata::MessageParamSpec::new("owner") - .of_type( - ::ink::metadata::TypeSpec::with_name_segs::< - AccountId32, - _, - >( - ::core::iter::Iterator::map( - ::core::iter::IntoIterator::into_iter(["AccountId32"]), - ::core::convert::AsRef::as_ref, - ), - ), - ) - .done(), - ]) - .returns( - ::ink::metadata::ReturnTypeSpec::new( - ::ink::metadata::TypeSpec::with_name_segs::< - ::ink::MessageResult>, - _, - >( - ::core::iter::Iterator::map( - ::core::iter::IntoIterator::into_iter([ - "ink", - "MessageResult", - ]), - ::core::convert::AsRef::as_ref, - ), - ), - ), - ) - .mutates(false) - .payable(false) - .default(false) - .docs([]) - .done(), - ::ink::metadata::MessageSpec::from_label("allowance") - .selector([0x6A_u8, 0x00_u8, 0x16_u8, 0x5E_u8]) - .args([ - ::ink::metadata::MessageParamSpec::new("id") - .of_type( - ::ink::metadata::TypeSpec::with_name_segs::< - AssetId, - _, - >( - ::core::iter::Iterator::map( - ::core::iter::IntoIterator::into_iter(["AssetId"]), - ::core::convert::AsRef::as_ref, - ), - ), - ) - .done(), - ::ink::metadata::MessageParamSpec::new("owner") - .of_type( - ::ink::metadata::TypeSpec::with_name_segs::< - AccountId32, - _, - >( - ::core::iter::Iterator::map( - ::core::iter::IntoIterator::into_iter(["AccountId32"]), - ::core::convert::AsRef::as_ref, - ), - ), - ) - .done(), - ::ink::metadata::MessageParamSpec::new("spender") - .of_type( - ::ink::metadata::TypeSpec::with_name_segs::< - AccountId32, - _, - >( - ::core::iter::Iterator::map( - ::core::iter::IntoIterator::into_iter(["AccountId32"]), - ::core::convert::AsRef::as_ref, - ), - ), - ) - .done(), - ]) - .returns( - ::ink::metadata::ReturnTypeSpec::new( - ::ink::metadata::TypeSpec::with_name_segs::< - ::ink::MessageResult>, - _, - >( - ::core::iter::Iterator::map( - ::core::iter::IntoIterator::into_iter([ - "ink", - "MessageResult", - ]), - ::core::convert::AsRef::as_ref, - ), - ), - ), - ) - .mutates(false) - .payable(false) - .default(false) - .docs([]) - .done(), - ::ink::metadata::MessageSpec::from_label("asset_exists") - .selector([0xAA_u8, 0x6B_u8, 0x65_u8, 0xDB_u8]) - .args([ - ::ink::metadata::MessageParamSpec::new("id") - .of_type( - ::ink::metadata::TypeSpec::with_name_segs::< - AssetId, - _, - >( - ::core::iter::Iterator::map( - ::core::iter::IntoIterator::into_iter(["AssetId"]), - ::core::convert::AsRef::as_ref, - ), - ), - ) - .done(), - ]) - .returns( - ::ink::metadata::ReturnTypeSpec::new( - ::ink::metadata::TypeSpec::with_name_segs::< - ::ink::MessageResult>, - _, - >( - ::core::iter::Iterator::map( - ::core::iter::IntoIterator::into_iter([ - "ink", - "MessageResult", - ]), - ::core::convert::AsRef::as_ref, - ), - ), - ), - ) - .mutates(false) - .payable(false) - .default(false) - .docs([]) - .done(), - ::ink::metadata::MessageSpec::from_label("mint_asset") - .selector([0x1F_u8, 0x8E_u8, 0x8E_u8, 0x22_u8]) - .args([ - ::ink::metadata::MessageParamSpec::new("id") - .of_type( - ::ink::metadata::TypeSpec::with_name_segs::< - u32, - _, - >( - ::core::iter::Iterator::map( - ::core::iter::IntoIterator::into_iter(["u32"]), - ::core::convert::AsRef::as_ref, - ), - ), - ) - .done(), - ::ink::metadata::MessageParamSpec::new("beneficiary") - .of_type( - ::ink::metadata::TypeSpec::with_name_segs::< - AccountId32, - _, - >( - ::core::iter::Iterator::map( - ::core::iter::IntoIterator::into_iter(["AccountId32"]), - ::core::convert::AsRef::as_ref, - ), - ), - ) - .done(), - ::ink::metadata::MessageParamSpec::new("amount") - .of_type( - ::ink::metadata::TypeSpec::with_name_segs::< - Balance, - _, - >( - ::core::iter::Iterator::map( - ::core::iter::IntoIterator::into_iter(["Balance"]), - ::core::convert::AsRef::as_ref, - ), - ), - ) - .done(), - ]) - .returns( - ::ink::metadata::ReturnTypeSpec::new( - ::ink::metadata::TypeSpec::with_name_segs::< - ::ink::MessageResult>, - _, - >( - ::core::iter::Iterator::map( - ::core::iter::IntoIterator::into_iter([ - "ink", - "MessageResult", - ]), - ::core::convert::AsRef::as_ref, - ), - ), - ), - ) - .mutates(false) - .payable(false) - .default(false) - .docs([]) - .done(), - ]) - .collect_events() - .docs([]) - .lang_error( - ::ink::metadata::TypeSpec::with_name_segs::< - ::ink::LangError, - _, - >( - ::core::iter::Iterator::map( - ::core::iter::IntoIterator::into_iter(["ink", "LangError"]), - ::core::convert::AsRef::as_ref, - ), - ), - ) - .environment( - ::ink::metadata::EnvironmentSpec::new() - .account_id( - ::ink::metadata::TypeSpec::with_name_segs::< - AccountId, - _, - >( - ::core::iter::Iterator::map( - ::core::iter::IntoIterator::into_iter(["AccountId"]), - ::core::convert::AsRef::as_ref, - ), - ), - ) - .balance( - ::ink::metadata::TypeSpec::with_name_segs::< - Balance, - _, - >( - ::core::iter::Iterator::map( - ::core::iter::IntoIterator::into_iter(["Balance"]), - ::core::convert::AsRef::as_ref, - ), - ), - ) - .hash( - ::ink::metadata::TypeSpec::with_name_segs::< - Hash, - _, - >( - ::core::iter::Iterator::map( - ::core::iter::IntoIterator::into_iter(["Hash"]), - ::core::convert::AsRef::as_ref, - ), - ), - ) - .timestamp( - ::ink::metadata::TypeSpec::with_name_segs::< - Timestamp, - _, - >( - ::core::iter::Iterator::map( - ::core::iter::IntoIterator::into_iter(["Timestamp"]), - ::core::convert::AsRef::as_ref, - ), - ), - ) - .block_number( - ::ink::metadata::TypeSpec::with_name_segs::< - BlockNumber, - _, - >( - ::core::iter::Iterator::map( - ::core::iter::IntoIterator::into_iter(["BlockNumber"]), - ::core::convert::AsRef::as_ref, - ), - ), - ) - .chain_extension( - ::ink::metadata::TypeSpec::with_name_segs::< - ChainExtension, - _, - >( - ::core::iter::Iterator::map( - ::core::iter::IntoIterator::into_iter(["ChainExtension"]), - ::core::convert::AsRef::as_ref, - ), - ), - ) - .max_event_topics(MAX_EVENT_TOPICS) - .static_buffer_size(::ink::env::BUFFER_SIZE) - .done(), - ) - .done(), - ) - } - }; - use super::*; -} diff --git a/pop-api/examples/fungibles/lib.rs b/pop-api/examples/fungibles/lib.rs index 68e43865..59040590 100755 --- a/pop-api/examples/fungibles/lib.rs +++ b/pop-api/examples/fungibles/lib.rs @@ -7,61 +7,12 @@ /// use ink::prelude::vec::Vec; use pop_api::{ - assets::fungibles::*, + assets::use_cases::fungibles as api, + error::PopApiError, primitives::{AccountId as AccountId32, AssetId}, }; -#[derive(Debug, Copy, Clone, PartialEq, Eq, scale::Encode, scale::Decode)] -#[cfg_attr(feature = "std", derive(scale_info::TypeInfo))] -pub enum ContractError { - /// The asset is not live; either frozen or being destroyed. - AssetNotLive, - /// The amount to mint is less than the existential deposit. - BelowMinimum, - /// Unspecified dispatch error, providing the index and its error index (if none `0`). - DispatchError { index: u8, error: u8 }, - /// Not enough allowance to fulfill a request is available. - InsufficientAllowance, - /// Not enough balance to fulfill a request is available. - InsufficientBalance, - /// The asset ID is already taken. - InUse, - /// Minimum balance should be non-zero. - MinBalanceZero, - /// Unspecified pallet error, providing pallet index and error index. - ModuleError { pallet: u8, error: u16 }, - /// The account to alter does not exist. - NoAccount, - /// The signing account has no permission to do the operation. - NoPermission, - /// The given asset ID is unknown. - Unknown, -} - -impl From for ContractError { - fn from(error: FungiblesError) -> Self { - match error { - FungiblesError::AssetNotLive => ContractError::AssetNotLive, - FungiblesError::BelowMinimum => ContractError::BelowMinimum, - FungiblesError::DispatchError { index, error } => { - ContractError::DispatchError { index, error } - }, - FungiblesError::InsufficientAllowance => ContractError::InsufficientAllowance, - FungiblesError::InsufficientBalance => ContractError::InsufficientBalance, - FungiblesError::InUse => ContractError::InUse, - FungiblesError::MinBalanceZero => ContractError::MinBalanceZero, - FungiblesError::ModuleError { pallet, error } => { - ContractError::ModuleError { pallet, error } - }, - FungiblesError::NoAccount => ContractError::NoAccount, - FungiblesError::NoPermission => ContractError::NoPermission, - FungiblesError::Unknown => ContractError::Unknown, - } - } -} - -/// The fungibles result type. -pub type Result = core::result::Result; +pub type Result = core::result::Result; #[ink::contract(env = pop_api::Environment)] mod fungibles { @@ -74,7 +25,7 @@ mod fungibles { impl Fungibles { #[ink(constructor, payable)] pub fn new() -> Self { - ink::env::debug_println!("PopApiAssetsExample::new"); + ink::env::debug_println!("PopApiFungiblesExample::new"); Default::default() } @@ -90,12 +41,12 @@ mod fungibles { #[ink(message)] pub fn total_supply(&self, id: AssetId) -> Result { - total_supply(id).map_err(From::from) + api::total_supply(id) } #[ink(message)] pub fn balance_of(&self, id: AssetId, owner: AccountId32) -> Result { - balance_of(id, owner).map_err(From::from) + api::balance_of(id, owner) } #[ink(message)] @@ -105,21 +56,21 @@ mod fungibles { owner: AccountId32, spender: AccountId32, ) -> Result { - allowance(id, owner, spender).map_err(From::from) + api::allowance(id, owner, spender) } #[ink(message)] pub fn transfer(&self, id: AssetId, to: AccountId32, value: Balance) -> Result<()> { ink::env::debug_println!( - "PopApiAssetsExample::transfer: id: {:?}, to: {:?} value: {:?}", + "PopApiFungiblesExample::transfer: id: {:?}, to: {:?} value: {:?}", id, to, value, ); - let result = transfer(id, to, value); + let result = api::transfer(id, to, value); ink::env::debug_println!("Result: {:?}", result); - result.map_err(From::from) + result } #[ink(message)] @@ -129,20 +80,21 @@ mod fungibles { from: Option, to: Option, value: Balance, - // Size needs to be known at compile time or ink's `Vec` + // In the standard a `[u8]`, but the size needs to be known at compile time ink's `Vec` + // has to be used. data: Vec, ) -> Result<()> { ink::env::debug_println!( - "PopApiAssetsExample::transfer_from: id: {:?}, from: {:?}, to: {:?} value: {:?}", + "PopApiFungiblesExample::transfer_from: id: {:?}, from: {:?}, to: {:?} value: {:?}", id, from, to, value, ); - let result = transfer_from(id, from, to, value, &data); + let result = api::transfer_from(id, from, to, value, &data); ink::env::debug_println!("Result: {:?}", result); - result.map_err(From::from) + result } /// 2. PSP-22 Metadata Interface: @@ -162,14 +114,14 @@ mod fungibles { #[ink(message)] pub fn create(&self, id: AssetId, admin: AccountId32, min_balance: Balance) -> Result<()> { ink::env::debug_println!( - "PopApiAssetsExample::create: id: {:?} admin: {:?} min_balance: {:?}", + "PopApiFungiblesExample::create: id: {:?} admin: {:?} min_balance: {:?}", id, admin, min_balance, ); - let result = create(id, admin, min_balance); + let result = api::create(id, admin, min_balance); ink::env::debug_println!("Result: {:?}", result); - result.map_err(From::from) + result } #[ink(message)] @@ -181,20 +133,20 @@ mod fungibles { decimals: u8, ) -> Result<()> { ink::env::debug_println!( - "PopApiAssetsExample::set_metadata: id: {:?} name: {:?} symbol: {:?}, decimals: {:?}", + "PopApiFungiblesExample::set_metadata: id: {:?} name: {:?} symbol: {:?}, decimals: {:?}", id, name, symbol, decimals, ); - let result = set_metadata(id, name, symbol, decimals); + let result = api::set_metadata(id, name, symbol, decimals); ink::env::debug_println!("Result: {:?}", result); - result.map_err(From::from) + result } #[ink(message)] pub fn asset_exists(&self, id: AssetId) -> Result { - asset_exists(id).map_err(From::from) + api::asset_exists(id) } } @@ -204,7 +156,7 @@ mod fungibles { #[ink::test] fn default_works() { - PopApiAssetsExample::new(); + PopApiFungiblesExample::new(); } } } diff --git a/pop-api/src/error.rs b/pop-api/src/error.rs new file mode 100644 index 00000000..92da4045 --- /dev/null +++ b/pop-api/src/error.rs @@ -0,0 +1,255 @@ +use crate::assets::use_cases::fungibles::{convert_to_fungibles_error, FungiblesError}; +use ink::env::chain_extension::FromStatusCode; +use scale::{Decode, Encode}; +use PopApiError::*; + +#[derive(Debug, Copy, Clone, PartialEq, Eq, Encode, Decode)] +#[cfg_attr(feature = "std", derive(scale_info::TypeInfo))] +#[repr(u8)] +pub enum PopApiError { + /// Some unknown error occurred. Go to the Pop API docs section `Pop API error`. + Other { + // Index within the `DispatchError` + dispatch_error_index: u8, + // Index within the `DispatchError` variant. + error_index: u8, + // Index for further nesting, e.g. pallet error. + error: u8, + } = 0, + /// Failed to lookup some data. + CannotLookup = 1, + /// A bad origin. + BadOrigin = 2, + /// A custom error in a module. + Module { + index: u8, + error: u8, + } = 3, + /// At least one consumer is remaining so the account cannot be destroyed. + ConsumerRemaining = 4, + /// There are no providers so the account cannot be created. + NoProviders = 5, + /// There are too many consumers so the account cannot be created. + TooManyConsumers = 6, + /// An error to do with tokens. + Token(TokenError) = 7, + /// An arithmetic error. + Arithmetic(ArithmeticError) = 8, + /// The number of transactional layers has been reached, or we are not in a transactional + /// layer. + Transactional(TransactionalError) = 9, + /// Resources exhausted, e.g. attempt to read/write data which is too large to manipulate. + Exhausted = 10, + /// The state is corrupt; this is generally not going to fix itself. + Corruption = 11, + /// Some resource (e.g. a preimage) is unavailable right now. This might fix itself later. + Unavailable = 12, + /// Root origin is not allowed. + RootNotAllowed = 13, + // TODO: make generic and add docs. + UseCaseError(FungiblesError) = 254, + DecodingFailed = 255, +} + +impl FromStatusCode for PopApiError { + fn from_status_code(status_code: u32) -> core::result::Result<(), Self> { + match status_code { + 0 => Ok(()), + _ => Err(convert_to_pop_api_error(status_code)), + } + } +} + +// `pub` because it is used in `runtime/devnet/src/extensions/tests/mod.rs`'s test: +// `dispatch_error_to_status_code_to_pop_api_error_works` +// +// This function converts a given `status_code` (u32) into a `PopApiError`. First it encodes the +// status code into a 4-byte array and checks for unknown nested errors. If decoding into +// `PopApiError` fails (e.g. a breaking change in the `DispatchError`), it handles the error by +// converting it to the `Other` variant by shifting each byte one position forward (the last byte is +// not used for anything)and setting the first byte to 0. If decoding succeeds, it checks if the +// error is of the `Module` variant and performs any necessary conversion based on the use case. +pub fn convert_to_pop_api_error(status_code: u32) -> PopApiError { + let mut encoded: [u8; 4] = + status_code.encode().try_into().expect("qid u32 always encodes to 4 bytes"); + encoded = check_for_unknown_nesting(encoded); + let error = match PopApiError::decode(&mut &encoded[..]) { + Err(_) => { + encoded[3] = encoded[2]; + encoded[2] = encoded[1]; + encoded[1] = encoded[0]; + encoded[0] = 0; + PopApiError::decode(&mut &encoded[..]).unwrap().into() + }, + Ok(error) => { + if let crate::PopApiError::Module { index, error } = error { + // TODO: make generic. + convert_to_fungibles_error(index, error) + } else { + error + } + }, + }; + ink::env::debug_println!("PopApiError: {:?}", error); + error +} + +// If a unknown nested variant of the `DispatchError` is detected meaning any of the subsequent +// bytes are non-zero (e.g. breaking change in the DispatchError), the error needs to be converted +// into `PopApiError::Other`'s encoded value. This conversion is done by shifting the bytes one +// position forward (the last byte is discarded as it is not being used) and replacing the first +// byte with the `Other` encoded value (0u8). This ensures that the error is correctly categorized +// as an `Other` variant. +fn check_for_unknown_nesting(encoded_error: [u8; 4]) -> [u8; 4] { + if non_nested_pop_api_errors().contains(&encoded_error[0]) + && encoded_error[1..].iter().any(|x| *x != 0u8) + { + [0u8, encoded_error[0], encoded_error[1], encoded_error[2]] + } else if singular_nested_pop_api_errors().contains(&encoded_error[0]) + && encoded_error[2..].iter().any(|x| *x != 0u8) + { + [0u8, encoded_error[0], encoded_error[1], encoded_error[2]] + } else { + encoded_error + } +} + +impl From for PopApiError { + fn from(_: scale::Error) -> Self { + DecodingFailed + } +} +#[derive(Debug, Copy, Clone, PartialEq, Eq, scale::Encode, scale::Decode)] +#[cfg_attr(feature = "std", derive(scale_info::TypeInfo))] +pub enum TokenError { + /// Funds are unavailable. + FundsUnavailable, + /// Some part of the balance gives the only provider reference to the account and thus cannot + /// be (re)moved. + OnlyProvider, + /// Account cannot exist with the funds that would be given. + BelowMinimum, + /// Account cannot be created. + CannotCreate, + /// The asset in question is unknown. + UnknownAsset, + /// Funds exist but are frozen. + Frozen, + /// Operation is not supported by the asset. + Unsupported, + /// Account cannot be created for a held balance. + CannotCreateHold, + /// Withdrawal would cause unwanted loss of account. + NotExpendable, + /// Account cannot receive the assets. + Blocked, +} + +#[derive(Debug, Copy, Clone, PartialEq, Eq, scale::Encode, scale::Decode)] +#[cfg_attr(feature = "std", derive(scale_info::TypeInfo))] +pub enum ArithmeticError { + /// Underflow. + Underflow, + /// Overflow. + Overflow, + /// Division by zero. + DivisionByZero, +} + +#[derive(Debug, Copy, Clone, PartialEq, Eq, scale::Encode, scale::Decode)] +#[cfg_attr(feature = "std", derive(scale_info::TypeInfo))] +pub enum TransactionalError { + /// Too many transactional layers have been spawned. + LimitReached, + /// A transactional layer was expected, but does not exist. + NoLayer, +} + +fn singular_nested_pop_api_errors() -> [u8; 3] { + const TOKEN_ERROR: u8 = 7; + const ARITHMETIC_ERROR: u8 = 8; + const TRANSACTION_ERROR: u8 = 9; + [TOKEN_ERROR, ARITHMETIC_ERROR, TRANSACTION_ERROR] +} + +fn non_nested_pop_api_errors() -> [u8; 9] { + const CANNOT_LOOKUP: u8 = 1; + const BAD_ORIGIN: u8 = 2; + const CONSUMER_REMAINING: u8 = 4; + const NO_PROVIDERS: u8 = 5; + const TOO_MANY_CONSUMERS: u8 = 6; + const EXHAUSTED: u8 = 10; + const CORRUPTION: u8 = 11; + const UNAVAILABLE: u8 = 12; + const ROOT_NOT_ALLOWED: u8 = 13; + [ + CANNOT_LOOKUP, + BAD_ORIGIN, + CONSUMER_REMAINING, + NO_PROVIDERS, + TOO_MANY_CONSUMERS, + EXHAUSTED, + CORRUPTION, + UNAVAILABLE, + ROOT_NOT_ALLOWED, + ] +} + +#[test] +fn u32_always_encodes_to_4_bytes() { + assert_eq!(0u32.encode().len(), 4); + assert_eq!(u32::MAX.encode().len(), 4); +} + +// If decoding failed the encoded value is converted to the `PopApiError::Other`. This handles +// unknown errors coming from the runtime. This could happen if a contract is not upgraded to the +// latest Pop API version. +#[test] +fn test_non_existing_pop_api_errors() { + let encoded_error = [7u8, 100u8, 0u8, 0u8]; + let status_code = u32::decode(&mut &encoded_error[..]).unwrap(); + let pop_api_error = ::from_status_code(status_code); + assert_eq!(Err(Other { dispatch_error_index: 7, error_index: 100, error: 0 }), pop_api_error); +} + +// If the encoded value indicates a nested PopApiError which is not handled by the Pop API version, +// the encoded value is converted into `PopApiError::Other`. +#[test] +fn check_for_unknown_nested_pop_api_errors_works() { + for &error_code in &non_nested_pop_api_errors() { + let encoded_error = [error_code, 1, 2, 3]; + let result = check_for_unknown_nesting(encoded_error); + let decoded = PopApiError::decode(&mut &result[..]).unwrap(); + + assert_eq!( + decoded, + Other { dispatch_error_index: error_code, error_index: 1, error: 2 }, + "Failed for error code: {}", + error_code + ); + } + for &error_code in &singular_nested_pop_api_errors() { + let encoded_error = [error_code, 1, 2, 3]; + let result = check_for_unknown_nesting(encoded_error); + let decoded = PopApiError::decode(&mut &result[..]).unwrap(); + + assert_eq!( + decoded, + Other { dispatch_error_index: error_code, error_index: 1, error: 2 }, + "Failed for error code: {}", + error_code + ); + } +} + +// This test ensures that a non-zero value for unused bytes does not interfere with the correct +// decoding of the error. It verifies that even with an additional byte, the errors are correctly +// decoded and represented in its correct variant. +#[test] +fn extra_byte_does_not_mess_up_decoding() { + // Module error + let encoded_error = [3u8, 4u8, 5u8, 6u8]; + let status_code = u32::decode(&mut &encoded_error[..]).unwrap(); + let pop_api_error = ::from_status_code(status_code); + assert_eq!(Err(Module { index: 4, error: 5 }), pop_api_error); +} diff --git a/pop-api/src/lib.rs b/pop-api/src/lib.rs index be448890..a785aebe 100644 --- a/pop-api/src/lib.rs +++ b/pop-api/src/lib.rs @@ -1,19 +1,19 @@ #![cfg_attr(not(feature = "std"), no_std, no_main)] -use core::convert::TryInto; +use crate::error::PopApiError; use ink::{prelude::vec::Vec, ChainExtensionInstance}; use primitives::{cross_chain::*, storage_keys::*, AccountId as AccountId32}; +use scale::Encode; pub use sp_runtime::{BoundedVec, MultiAddress, MultiSignature}; use v0::RuntimeCall; -pub use v0::{ - assets, balances, contracts, cross_chain, dispatch_error, nfts, relay_chain_block_number, state, -}; +pub use v0::{assets, balances, cross_chain, nfts, relay_chain_block_number, state}; +pub mod error; pub mod primitives; pub mod v0; -// type AccountId = ::AccountId; type AccountId = AccountId32; +// TODO: do the same as above and check expanded code. type Balance = ::Balance; type BlockNumber = ::BlockNumber; type StringLimit = u32; @@ -21,54 +21,6 @@ type MaxTips = u32; pub type Result = core::result::Result; -#[derive(Debug, Copy, Clone, PartialEq, Eq, scale::Encode, scale::Decode)] -#[cfg_attr(feature = "std", derive(scale_info::TypeInfo))] -pub enum PopApiError { - Assets(assets::fungibles::AssetsError), - Balances(balances::BalancesError), - Contracts(contracts::Error), - DecodingFailed, - Nfts(nfts::Error), - SystemCallFiltered, - TokenError(dispatch_error::TokenError), - UnknownModuleStatusCode(u32), - UnknownDispatchStatusCode(u32), - Xcm(cross_chain::Error), -} - -impl ink::env::chain_extension::FromStatusCode for PopApiError { - fn from_status_code(status_code: u32) -> core::result::Result<(), Self> { - use crate::PopApiError::{ - Assets, Balances, Contracts, Nfts, TokenError, UnknownDispatchStatusCode, - UnknownModuleStatusCode, - }; - - match status_code { - 0 => Ok(()), - 3_000_000..=3_999_999 => { - let status_code = status_code - 3_000_000; - match status_code { - // CallFiltered originates from `frame_system` with pallet-index 0. The CallFiltered error is at index 5 - 5 => Err(PopApiError::SystemCallFiltered), - 10_000..=10_999 => Err(Balances((status_code - 10_000).try_into()?)), - 40_000..=40_999 => Err(Contracts((status_code - 40_000).try_into()?)), - 50_000..=50_999 => Err(Nfts((status_code - 50_000).try_into()?)), - 52_000..=52_999 => Err(Assets((status_code - 52_000).try_into()?)), - _ => Err(UnknownModuleStatusCode(status_code)), - } - }, - 7_000_000..=7_999_999 => Err(TokenError((status_code - 7_000_000).try_into()?)), - _ => Err(UnknownDispatchStatusCode(status_code)), - } - } -} - -impl From for PopApiError { - fn from(_: scale::Error) -> Self { - panic!("encountered unexpected invalid SCALE encoding") - } -} - #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "std", derive(scale_info::TypeInfo))] pub enum Environment {} diff --git a/pop-api/src/v0/assets/fungibles.rs b/pop-api/src/v0/assets/fungibles.rs deleted file mode 100644 index df9033c7..00000000 --- a/pop-api/src/v0/assets/fungibles.rs +++ /dev/null @@ -1,610 +0,0 @@ -use crate::{ - balances::BalancesError, AccountId, Balance, PopApiError::UnknownModuleStatusCode, RuntimeCall, - *, -}; -use ink::prelude::vec::Vec; -use primitives::AssetId; -use scale::{Compact, Encode}; - -type Result = core::result::Result; - -/// Local Fungibles: -/// 1. PSP-22 Interface -/// 2. PSP-22 Metadata Interface -/// 3. Asset Management - -/// 1. PSP-22 Interface: -/// - total_supply -/// - balance_of -/// - allowance -/// - transfer -/// - transfer_from -/// - approve -/// - increase_allowance -/// - decrease_allowance - -/// Returns the total token supply for a given asset ID. -/// -/// # Arguments -/// * `id` - The ID of the asset. -/// -/// # Returns -/// The total supply of the token, or an error if the operation fails. -pub fn total_supply(id: AssetId) -> Result { - Ok(state::read(RuntimeStateKeys::Assets(AssetsKeys::TotalSupply(id)))?) -} - -/// Returns the account balance for the specified `owner` for a given asset ID. Returns `0` if -/// the account is non-existent. -/// -/// # Arguments -/// * `id` - The ID of the asset. -/// * `owner` - The account whose balance is being queried. -/// -/// # Returns -/// The balance of the specified account, or an error if the operation fails. -pub fn balance_of(id: AssetId, owner: AccountId) -> Result { - Ok(state::read(RuntimeStateKeys::Assets(AssetsKeys::BalanceOf(id, owner)))?) -} - -/// Returns the amount which `spender` is still allowed to withdraw from `owner` for a given -/// asset ID. Returns `0` if no allowance has been set. -/// -/// # Arguments -/// * `id` - The ID of the asset. -/// * `owner` - The account that owns the tokens. -/// * `spender` - The account that is allowed to spend the tokens. -/// -/// # Returns -/// The remaining allowance, or an error if the operation fails. -pub fn allowance(id: AssetId, owner: AccountId, spender: AccountId) -> Result { - Ok(state::read(RuntimeStateKeys::Assets(AssetsKeys::Allowance(id, owner, spender)))?) -} - -/// Transfers `value` amount of tokens from the caller's account to account `to`, with additional -/// `data` in unspecified format. -/// -/// # Arguments -/// * `id` - The ID of the asset. -/// * `to` - The recipient account. -/// * `value` - The number of tokens to transfer. -/// -/// # Returns -/// Returns `Ok(())` if successful, or an error if the transfer fails. -pub fn transfer( - id: AssetId, - to: impl Into>, - value: Balance, -) -> Result<()> { - // TODO: transfer or transfer_keep_alive - // Ok(dispatch(RuntimeCall::Assets(AssetsCall::Transfer { - // id: id.into(), - // target: target.into(), - // amount: Compact(amount), - // }))?) - Ok(dispatch(RuntimeCall::Assets(AssetsCall::TransferKeepAlive { - id: id.into(), - target: to.into(), - amount: Compact(value), - }))?) -} - -/// Transfers `value` tokens on behalf of `from` to account `to` with additional `data` -/// in unspecified format. If `from` is equal to `None`, tokens will be minted to account `to`. If -/// `to` is equal to `None`, tokens will be burned from account `from`. -/// -/// # Arguments -/// * `id` - The ID of the asset. -/// * `from` - The account from which the tokens are transferred. -/// * `to` - The recipient account. -/// * `value` - The number of tokens to transfer. -/// -/// # Returns -/// Returns `Ok(())` if successful, or an error if the transfer fails. -pub fn transfer_from( - id: AssetId, - from: Option>>, - to: Option>>, - value: Balance, - _data: &[u8], -) -> Result<()> { - match (from, to) { - (None, Some(to)) => mint(id, to, value), - // (Some(from), None) => burn(id, from, value), - (Some(from), Some(to)) => { - Ok(dispatch(RuntimeCall::Assets(AssetsCall::TransferApproved { - id: id.into(), - owner: from.into(), - destination: to.into(), - amount: Compact(value), - }))?) - }, - _ => Ok(()), - } -} - -/// Approves an account to spend a specified number of tokens on behalf of the caller. -/// -/// # Arguments -/// * `id` - The ID of the asset. -/// * `spender` - The account that is allowed to spend the tokens. -/// * `value` - The number of tokens to approve. -/// -/// # Returns -/// Returns `Ok(())` if successful, or an error if the approval fails. -// #[allow(unused_variables)] -// fn approve(id: AssetId, spender: AccountId, value: Balance) -> Result<()> { -// todo!() -// // TODO: read allowance and increase or decrease. -// // Ok(dispatch(RuntimeCall::Assets(AssetsCall::ApproveTransfer { -// // id: id.into(), -// // delegate: spender.into(), -// // amount: Compact(value), -// // }))?) -// } - -/// Increases the allowance of a spender. -/// -/// # Arguments -/// * `id` - The ID of the asset. -/// * `spender` - The account that is allowed to spend the tokens. -/// * `value` - The number of tokens to increase the allowance by. -/// -/// # Returns -/// Returns `Ok(())` if successful, or an error if the operation fails. -// fn increase_allowance(id: AssetId, spender: AccountId, value: Balance) -> Result<()> { -// Ok(dispatch(RuntimeCall::Assets(AssetsCall::ApproveTransfer { -// id: id.into(), -// delegate: spender.into(), -// amount: Compact(value), -// }))?) -// } - -/// Decreases the allowance of a spender. -/// -/// # Arguments -/// * `id` - The ID of the asset. -/// * `spender` - The account that is allowed to spend the tokens. -/// * `value` - The number of tokens to decrease the allowance by. -/// -/// # Returns -/// Returns `Ok(())` if successful, or an error if the operation fails. -// #[allow(unused_variables)] -// fn decrease_allowance(id: AssetId, spender: AccountId, value: Balance) -> Result<()> { -// todo!() -// // TODO: cancel_approval + approve_transfer -// // Ok(dispatch(RuntimeCall::Assets(AssetsCall::CancelApproval { -// // id: id.into(), -// // delegate: delegate.into(), -// // }))?) -// // Ok(dispatch(RuntimeCall::Assets(AssetsCall::ApproveTransfer { -// // id: id.into(), -// // delegate: spender.into(), -// // amount: Compact(value), -// // }))?) -// } - -/// 2. PSP-22 Metadata Interface: -/// - token_name -/// - token_symbol -/// - token_decimals - -/// Returns the token name for a given asset ID. -/// -/// # Arguments -/// * `id` - The ID of the asset. -/// -/// # Returns -/// The name of the token as a byte vector, or an error if the operation fails. -// #[allow(unused_variables)] -// pub fn token_name(id: AssetId) -> Result>> { -// todo!() -// // Ok(state::read(RuntimeStateKeys::Assets(AssetsKeys::TokenName(id)))?) -// } - -/// Returns the token symbol for a given asset ID. -/// -/// # Arguments -/// * `id` - The ID of the asset. -/// -/// # Returns -/// The symbol of the token as a byte vector, or an error if the operation fails. -// #[allow(unused_variables)] -// fn token_symbol(id: AssetId) -> Result>> { -// todo!() -// } - -/// Returns the token decimals for a given asset ID. -/// -/// # Arguments -/// * `id` - The ID of the asset. -/// -/// # Returns -/// The number of decimals of the token as a byte vector, or an error if the operation fails. -// #[allow(unused_variables)] -// fn token_decimals(id: AssetId) -> Result>> { -// todo!() -// } - -/// 3. Asset Management: -/// - create -/// - start_destroy -/// - destroy_accounts -/// - destroy_approvals -/// - finish_destroy -/// - set_metadata -/// - clear_metadata - -/// Create a new token with a given asset ID. -/// -/// # Arguments -/// * `id` - The ID of the asset. -/// * `admin` - The account that will administer the asset. -/// * `min_balance` - The minimum balance required for accounts holding this asset. -/// -/// # Returns -/// Returns `Ok(())` if successful, or an error if the creation fails. -pub fn create( - id: AssetId, - admin: impl Into>, - min_balance: Balance, -) -> Result<()> { - Ok(dispatch(RuntimeCall::Assets(AssetsCall::Create { - id: id.into(), - admin: admin.into(), - min_balance, - }))?) -} - -/// Start the process of destroying a token with a given asset ID. -/// -/// # Arguments -/// * `id` - The ID of the asset. -/// -/// # Returns -/// Returns `Ok(())` if successful, or an error if the operation fails. -// fn start_destroy(id: AssetId) -> Result<()> { -// Ok(dispatch(RuntimeCall::Assets(AssetsCall::StartDestroy { -// id: id.into(), -// }))?) -// } - -/// Destroy all accounts associated with a token with a given asset ID. -/// -/// # Arguments -/// * `id` - The ID of the asset. -/// -/// # Returns -/// Returns `Ok(())` if successful, or an error if the operation fails. -// fn destroy_accounts(id: AssetId) -> Result<()> { -// Ok(dispatch(RuntimeCall::Assets(AssetsCall::DestroyAccounts { -// id: id.into(), -// }))?) -// } - -/// Destroy all approvals associated with a token with a given asset ID. -/// -/// # Arguments -/// * `id` - The ID of the asset. -/// -/// # Returns -/// Returns `Ok(())` if successful, or an error if the operation fails. -// fn destroy_approvals(id: AssetId) -> Result<()> { -// Ok(dispatch(RuntimeCall::Assets(AssetsCall::DestroyApprovals { -// id: id.into(), -// }))?) -// } - -/// Complete the process of destroying a token with a given asset ID. -/// -/// # Arguments -/// * `id` - The ID of the asset. -/// -/// # Returns -/// Returns `Ok(())` if successful, or an error if the operation fails. -// fn finish_destroy(id: AssetId) -> Result<()> { -// Ok(dispatch(RuntimeCall::Assets(AssetsCall::FinishDestroy { -// id: id.into(), -// }))?) -// } - -/// Set the metadata for a token with a given asset ID. -/// -/// # Arguments -/// * `id` - The ID of the asset. -/// -/// # Returns -/// Returns `Ok(())` if successful, or an error if the operation fails. -pub fn set_metadata(id: AssetId, name: Vec, symbol: Vec, decimals: u8) -> Result<()> { - Ok(dispatch(RuntimeCall::Assets(AssetsCall::SetMetadata { - id: id.into(), - name, - symbol, - decimals, - }))?) -} - -/// Clear the metadata for a token with a given asset ID. -/// -/// # Arguments -/// * `id` - The ID of the asset. -/// -/// # Returns -/// Returns `Ok(())` if successful, or an error if the operation fails. -// fn clear_metadata(id: AssetId) -> Result<()> { -// Ok(dispatch(RuntimeCall::Assets(AssetsCall::ClearMetadata { -// id: id.into(), -// }))?) -// } - -pub fn asset_exists(id: AssetId) -> Result { - Ok(state::read(RuntimeStateKeys::Assets(AssetsKeys::AssetExists(id)))?) -} - -/// Mint assets of a particular class. -fn mint( - id: AssetId, - beneficiary: impl Into>, - amount: Balance, -) -> Result<()> { - Ok(dispatch(RuntimeCall::Assets(AssetsCall::Mint { - id: id.into(), - beneficiary: beneficiary.into(), - amount: Compact(amount), - }))?) -} - -// Parameters to extrinsics representing an asset id (`AssetIdParameter`) and a balance amount -// (`Balance`) are expected to be compact encoded. The pop api handles that for the developer. -// https://substrate.stackexchange.com/questions/1873/what-is-the-meaning-of-palletcompact-in-pallet-development -// -// Asset id that is compact encoded. -type AssetIdParameter = Compact; -// Balance amount that is compact encoded. -type BalanceParameter = Compact; - -#[allow(warnings, unused)] -#[derive(Encode)] -pub(crate) enum AssetsCall { - #[codec(index = 0)] - Create { id: AssetIdParameter, admin: MultiAddress, min_balance: Balance }, - #[codec(index = 2)] - StartDestroy { id: AssetIdParameter }, - #[codec(index = 3)] - DestroyAccounts { id: AssetIdParameter }, - #[codec(index = 4)] - DestroyApprovals { id: AssetIdParameter }, - #[codec(index = 5)] - FinishDestroy { id: AssetIdParameter }, - #[codec(index = 6)] - Mint { - id: AssetIdParameter, - beneficiary: MultiAddress, - amount: BalanceParameter, - }, - #[codec(index = 7)] - Burn { id: AssetIdParameter, who: MultiAddress, amount: BalanceParameter }, - // TODO: ED or not - // #[codec(index = 8)] - // Transfer { id: AssetIdParameter, target: MultiAddress, amount: BalanceParameter }, - #[codec(index = 9)] - TransferKeepAlive { - id: AssetIdParameter, - target: MultiAddress, - amount: BalanceParameter, - }, - #[codec(index = 17)] - SetMetadata { id: AssetIdParameter, name: Vec, symbol: Vec, decimals: u8 }, - #[codec(index = 18)] - ClearMetadata { id: AssetIdParameter }, - #[codec(index = 22)] - ApproveTransfer { - id: AssetIdParameter, - delegate: MultiAddress, - amount: BalanceParameter, - }, - #[codec(index = 23)] - CancelApproval { id: AssetIdParameter, delegate: MultiAddress }, - #[codec(index = 25)] - TransferApproved { - id: AssetIdParameter, - owner: MultiAddress, - destination: MultiAddress, - amount: BalanceParameter, - }, -} - -#[derive(Debug, Copy, Clone, PartialEq, Eq, Encode, scale::Decode)] -#[cfg_attr(feature = "std", derive(scale_info::TypeInfo))] -pub(crate) enum AssetsError { - /// Account balance must be greater than or equal to the transfer amount. - BalanceLow, - /// The account to alter does not exist. - NoAccount, - /// The signing account has no permission to do the operation. - NoPermission, - /// The given asset ID is unknown. - Unknown, - /// The origin account is frozen. - Frozen, - /// The asset ID is already taken. - InUse, - /// Invalid witness data given. - BadWitness, - /// Minimum balance should be non-zero. - MinBalanceZero, - /// Unable to increment the consumer reference counters on the account. Either no provider - /// reference exists to allow a non-zero balance of a non-self-sufficient asset, or one - /// fewer then the maximum number of consumers has been reached. - UnavailableConsumer, - /// Invalid metadata given. - BadMetadata, - /// No approval exists that would allow the transfer. - Unapproved, - /// The source account would not survive the transfer and it needs to stay alive. - WouldDie, - /// The asset-account already exists. - AlreadyExists, - /// The asset-account doesn't have an associated deposit. - NoDeposit, - /// The operation would result in funds being burned. - WouldBurn, - /// The asset is a live asset and is actively being used. Usually emit for operations such - /// as `start_destroy` which require the asset to be in a destroying state. - LiveAsset, - /// The asset is not live, and likely being destroyed. - AssetNotLive, - /// The asset status is not the expected status. - IncorrectStatus, - /// The asset should be frozen before the given operation. - NotFrozen, - /// Callback action resulted in error - CallbackFailed, -} - -impl From for AssetsError { - fn from(error: PopApiError) -> Self { - match error { - PopApiError::Assets(e) => e, - _ => panic!("Expected AssetsError"), - } - } -} - -impl TryFrom for AssetsError { - type Error = PopApiError; - - fn try_from(status_code: u32) -> core::result::Result { - use AssetsError::*; - match status_code { - 0 => Ok(BalanceLow), - 1 => Ok(NoAccount), - 2 => Ok(NoPermission), - 3 => Ok(Unknown), - 4 => Ok(Frozen), - 5 => Ok(InUse), - 6 => Ok(BadWitness), - 7 => Ok(MinBalanceZero), - 8 => Ok(UnavailableConsumer), - 9 => Ok(BadMetadata), - 10 => Ok(Unapproved), - 11 => Ok(WouldDie), - 12 => Ok(AlreadyExists), - 13 => Ok(NoDeposit), - 14 => Ok(WouldBurn), - 15 => Ok(LiveAsset), - 16 => Ok(AssetNotLive), - 17 => Ok(IncorrectStatus), - 18 => Ok(NotFrozen), - _ => Err(UnknownModuleStatusCode(status_code)), - } - } -} - -#[derive(Debug, Copy, Clone, PartialEq, Eq, Encode, scale::Decode)] -#[cfg_attr(feature = "std", derive(scale_info::TypeInfo))] -pub enum FungiblesError { - /// The asset is not live; either frozen or being destroyed. - AssetNotLive, - /// The amount to mint is less than the existential deposit. - BelowMinimum, - /// Unspecified dispatch error, providing the index and its error index (if none `0`). - DispatchError { index: u8, error: u8 }, - /// Not enough allowance to fulfill a request is available. - InsufficientAllowance, - /// Not enough balance to fulfill a request is available. - InsufficientBalance, - /// The asset ID is already taken. - InUse, - /// Minimum balance should be non-zero. - MinBalanceZero, - /// Unspecified pallet error, providing pallet index and error index. - ModuleError { pallet: u8, error: u16 }, - /// The account to alter does not exist. - NoAccount, - /// The signing account has no permission to do the operation. - NoPermission, - /// The given asset ID is unknown. - Unknown, -} - -impl From for FungiblesError { - fn from(error: BalancesError) -> Self { - match error { - // TODO: this insufficient balance is different than the assets variant. This one is - // for a deposit of creating an asset, the latter is for transfer tokens. - BalancesError::InsufficientBalance => FungiblesError::InsufficientBalance, - _ => FungiblesError::ModuleError { pallet: 40, error: error as u16 }, - } - } -} - -impl From for FungiblesError { - fn from(error: dispatch_error::TokenError) -> Self { - match error { - dispatch_error::TokenError::BelowMinimum => FungiblesError::BelowMinimum, - // ED is not respected. - dispatch_error::TokenError::OnlyProvider => FungiblesError::InsufficientBalance, - dispatch_error::TokenError::UnknownAsset => FungiblesError::Unknown, - _ => FungiblesError::DispatchError { index: 7, error: error as u8 }, - } - } -} - -impl From for FungiblesError { - fn from(error: AssetsError) -> Self { - match error { - AssetsError::AssetNotLive => FungiblesError::AssetNotLive, - AssetsError::BalanceLow => FungiblesError::InsufficientBalance, - AssetsError::Unapproved => FungiblesError::InsufficientAllowance, - AssetsError::InUse => FungiblesError::InUse, - AssetsError::MinBalanceZero => FungiblesError::MinBalanceZero, - AssetsError::NoPermission => FungiblesError::NoPermission, - AssetsError::NoAccount => FungiblesError::NoAccount, - AssetsError::Unknown => FungiblesError::Unknown, - _ => FungiblesError::ModuleError { pallet: 52, error: error as u16 }, - } - } -} - -impl From for FungiblesError { - fn from(error: PopApiError) -> Self { - match error { - PopApiError::Assets(e) => e.into(), - PopApiError::Balances(e) => e.into(), - PopApiError::TokenError(e) => e.into(), - PopApiError::UnknownModuleStatusCode(e) => { - let pallet = (e / 1_000) as u8; - let error = (e % 1_000) as u16; - FungiblesError::ModuleError { pallet, error } - }, - PopApiError::UnknownDispatchStatusCode(e) => { - let index = (e / 1_000_000) as u8; - let error = (3 % 1_000_000) as u8; - FungiblesError::DispatchError { index, error } - }, - _ => todo!(), - } - } -} - -// macro_rules! impl_error_conversion { -// ($pallet_index:, $pallet_error:ty, $interface_error:ty, $($variant:ident),*) => { -// impl From<$pallet_error> for $interface_error { -// fn from(error: $pallet_error) -> Self { -// match error { -// $( -// <$pallet_error>::$variant => <$interface_error>::$variant, -// )* -// _ => <$interface_error>::ModuleError { pallet: 0, error: [255, 0, 0, 0] }, // Default case -// } -// } -// } -// -// impl FromPalletError<$pallet_error> for $interface_error { -// fn from_pallet_error(error: $pallet_error) -> Self { -// Self::from(error) -// } -// } -// }; -// } diff --git a/pop-api/src/v0/assets/mod.rs b/pop-api/src/v0/assets/mod.rs index d6b0261c..736ccc0e 100644 --- a/pop-api/src/v0/assets/mod.rs +++ b/pop-api/src/v0/assets/mod.rs @@ -1 +1,2 @@ -pub mod fungibles; \ No newline at end of file +pub(crate) mod pallets; +pub mod use_cases; diff --git a/pop-api/src/v0/assets/pallets/assets.rs b/pop-api/src/v0/assets/pallets/assets.rs new file mode 100644 index 00000000..7a575e08 --- /dev/null +++ b/pop-api/src/v0/assets/pallets/assets.rs @@ -0,0 +1,491 @@ +// TODO: what to put in this file? +#![allow(dead_code)] + +use crate::{Balance, RuntimeCall, *}; +use ink::prelude::vec::Vec; +use primitives::{AssetId, MultiAddress}; +use scale::{Compact, Encode}; + +type Result = core::result::Result; + +/// [Pallet Assets](https://github.com/paritytech/polkadot-sdk/blob/master/substrate/frame/assets/src/lib.rs): +/// 1. Dispatchables +/// 2. Read state functions +/// +/// 1. Dispatchables within pallet assets (TrustBackedAssets instance) that can be used via the pop api on Pop Network: +/// - create +/// - start_destroy +/// - destroy_accounts +/// - destroy_approvals +/// - finish_destroy +/// - mint +/// - burn +/// - transfer +/// - transfer_keep_alive +/// - force_transfer +/// - freeze +/// - thaw +/// - freeze_asset +/// - thaw_asset +/// - transfer_ownership +/// - set_team +/// - set_metadata +/// - clear_metadata +/// - approve_transfer +/// - cancel_approval +/// - force_cancel_approval +/// - transfer_approved +/// - touch +/// - refund +/// - set_min_balance +/// - touch_other +/// - refund_other +/// - block + +/// Issue a new class of fungible assets from a public origin. +pub(crate) fn create( + id: AssetId, + admin: impl Into>, + min_balance: Balance, +) -> Result<()> { + dispatch(RuntimeCall::Assets(AssetsCall::Create { + id: id.into(), + admin: admin.into(), + min_balance, + })) +} + +/// Start the process of destroying a fungible asset class. +pub(crate) fn start_destroy(id: AssetId) -> Result<()> { + dispatch(RuntimeCall::Assets(AssetsCall::StartDestroy { id: id.into() })) +} + +/// Destroy all accounts associated with a given asset. +pub(crate) fn destroy_accounts(id: AssetId) -> Result<()> { + dispatch(RuntimeCall::Assets(AssetsCall::DestroyAccounts { id: id.into() })) +} + +/// Destroy all approvals associated with a given asset up to the max (see runtime configuration Assets `RemoveItemsLimit`). +pub(crate) fn destroy_approvals(id: AssetId) -> Result<()> { + dispatch(RuntimeCall::Assets(AssetsCall::DestroyApprovals { id: id.into() })) +} + +/// Complete destroying asset and unreserve currency. +pub(crate) fn finish_destroy(id: AssetId) -> Result<()> { + dispatch(RuntimeCall::Assets(AssetsCall::FinishDestroy { id: id.into() })) +} + +/// Mint assets of a particular class. +pub(crate) fn mint( + id: AssetId, + beneficiary: impl Into>, + amount: Balance, +) -> Result<()> { + dispatch(RuntimeCall::Assets(AssetsCall::Mint { + id: id.into(), + beneficiary: beneficiary.into(), + amount: Compact(amount), + })) +} + +/// Reduce the balance of `who` by as much as possible up to `amount` assets of `id`. +pub(crate) fn burn( + id: AssetId, + who: impl Into>, + amount: Balance, +) -> Result<()> { + dispatch(RuntimeCall::Assets(AssetsCall::Burn { + id: id.into(), + who: who.into(), + amount: Compact(amount), + })) +} + +/// Move some assets from the sender account to another. +pub(crate) fn transfer( + id: AssetId, + target: impl Into>, + amount: Balance, +) -> Result<()> { + dispatch(RuntimeCall::Assets(AssetsCall::TransferKeepAlive { + id: id.into(), + target: target.into(), + amount: Compact(amount), + })) +} + +/// Move some assets from the sender account to another, keeping the sender account alive. +pub(crate) fn transfer_keep_alive( + id: AssetId, + target: impl Into>, + amount: Balance, +) -> Result<()> { + dispatch(RuntimeCall::Assets(AssetsCall::TransferKeepAlive { + id: id.into(), + target: target.into(), + amount: Compact(amount), + })) +} + +/// Move some assets from one account to another. Sender should be the Admin of the asset `id`. +pub(crate) fn force_transfer( + id: AssetId, + source: impl Into>, + dest: impl Into>, + amount: Balance, +) -> Result<()> { + dispatch(RuntimeCall::Assets(AssetsCall::ForceTransfer { + id: id.into(), + source: source.into(), + dest: dest.into(), + amount: Compact(amount), + })) +} + +/// Disallow further unprivileged transfers of an asset `id` from an account `who`. `who` +/// must already exist as an entry in `Account`s of the asset. If you want to freeze an +/// account that does not have an entry, use `touch_other` first. +pub(crate) fn freeze(id: AssetId, who: impl Into>) -> Result<()> { + dispatch(RuntimeCall::Assets(AssetsCall::Freeze { id: id.into(), who: who.into() })) +} + +/// Allow unprivileged transfers to and from an account again. +pub(crate) fn thaw(id: AssetId, who: impl Into>) -> Result<()> { + dispatch(RuntimeCall::Assets(AssetsCall::Thaw { id: id.into(), who: who.into() })) +} + +/// Disallow further unprivileged transfers for the asset class. +pub(crate) fn freeze_asset(id: AssetId) -> Result<()> { + dispatch(RuntimeCall::Assets(AssetsCall::FreezeAsset { id: id.into() })) +} + +/// Allow unprivileged transfers for the asset again. +pub(crate) fn thaw_asset(id: AssetId) -> Result<()> { + dispatch(RuntimeCall::Assets(AssetsCall::ThawAsset { id: id.into() })) +} + +/// Change the Owner of an asset. +pub(crate) fn transfer_ownership( + id: AssetId, + owner: impl Into>, +) -> Result<()> { + dispatch(RuntimeCall::Assets(AssetsCall::TransferOwnership { + id: id.into(), + owner: owner.into(), + })) +} + +/// Change the Issuer, Admin and Freezer of an asset. +pub(crate) fn set_team( + id: AssetId, + issuer: impl Into>, + admin: impl Into>, + freezer: impl Into>, +) -> Result<()> { + dispatch(RuntimeCall::Assets(AssetsCall::SetTeam { + id: id.into(), + issuer: issuer.into(), + admin: admin.into(), + freezer: freezer.into(), + })) +} + +/// Set the metadata for an asset. +pub(crate) fn set_metadata( + id: AssetId, + name: Vec, + symbol: Vec, + decimals: u8, +) -> Result<()> { + dispatch(RuntimeCall::Assets(AssetsCall::SetMetadata { id: id.into(), name, symbol, decimals })) +} + +/// Clear the metadata for an asset. +pub(crate) fn clear_metadata(id: AssetId) -> Result<()> { + dispatch(RuntimeCall::Assets(AssetsCall::ClearMetadata { id: id.into() })) +} + +/// Approve an amount of asset for transfer by a delegated third-party account. +pub(crate) fn approve_transfer( + id: AssetId, + delegate: impl Into>, + amount: Balance, +) -> Result<()> { + dispatch(RuntimeCall::Assets(AssetsCall::ApproveTransfer { + id: id.into(), + delegate: delegate.into(), + amount: Compact(amount), + })) +} + +/// Cancel all of some asset approved for delegated transfer by a third-party account. +pub(crate) fn cancel_approval( + id: AssetId, + delegate: impl Into>, +) -> Result<()> { + dispatch(RuntimeCall::Assets(AssetsCall::CancelApproval { + id: id.into(), + delegate: delegate.into(), + })) +} + +/// Cancel all of some asset approved for delegated transfer by a third-party account. +pub(crate) fn force_cancel_approval( + id: AssetId, + owner: impl Into>, + delegate: impl Into>, +) -> Result<()> { + dispatch(RuntimeCall::Assets(AssetsCall::ForceCancelApproval { + id: id.into(), + owner: owner.into(), + delegate: delegate.into(), + })) +} + +/// Transfer some asset balance from a previously delegated account to some third-party +/// account. +pub(crate) fn transfer_approved( + id: AssetId, + owner: impl Into>, + destination: impl Into>, + amount: Balance, +) -> Result<()> { + dispatch(RuntimeCall::Assets(AssetsCall::TransferApproved { + id: id.into(), + owner: owner.into(), + destination: destination.into(), + amount: Compact(amount), + })) +} + +/// Create an asset account for non-provider assets. +pub(crate) fn touch(id: AssetId) -> Result<()> { + dispatch(RuntimeCall::Assets(AssetsCall::Touch { id: id.into() })) +} + +/// Return the deposit (if any) of an asset account or a consumer reference (if any) of an +/// account. +pub(crate) fn refund(id: AssetId, allow_burn: bool) -> Result<()> { + dispatch(RuntimeCall::Assets(AssetsCall::Refund { id: id.into(), allow_burn })) +} + +/// Sets the minimum balance of an asset. +pub(crate) fn set_min_balance(id: AssetId, min_balance: Balance) -> Result<()> { + dispatch(RuntimeCall::Assets(AssetsCall::SetMinBalance { + id: id.into(), + min_balance: Compact(min_balance), + })) +} + +/// Create an asset account for `who`. +pub(crate) fn touch_other(id: AssetId, who: impl Into>) -> Result<()> { + dispatch(RuntimeCall::Assets(AssetsCall::TouchOther { id: id.into(), who: who.into() })) +} + +/// Return the deposit (if any) of a target asset account. Useful if you are the depositor. +pub(crate) fn refund_other(id: AssetId, who: impl Into>) -> Result<()> { + dispatch(RuntimeCall::Assets(AssetsCall::RefundOther { id: id.into(), who: who.into() })) +} + +/// Disallow further unprivileged transfers of an asset `id` to and from an account `who`. +pub(crate) fn block(id: AssetId, who: impl Into>) -> Result<()> { + dispatch(RuntimeCall::Assets(AssetsCall::Block { id: id.into(), who: who.into() })) +} + +/// 2. Read state functions +/// - total_supply +/// - + +pub(crate) fn total_supply(id: AssetId) -> Result { + state::read(RuntimeStateKeys::Assets(AssetsKeys::TotalSupply(id))).into() +} + +pub(crate) fn balance_of(id: AssetId, owner: AccountId) -> Result { + state::read(RuntimeStateKeys::Assets(AssetsKeys::BalanceOf(id, owner))).into() +} + +pub(crate) fn allowance(id: AssetId, owner: AccountId, spender: AccountId) -> Result { + state::read(RuntimeStateKeys::Assets(AssetsKeys::Allowance(id, owner, spender))).into() +} +pub(crate) fn asset_exists(id: AssetId) -> Result { + state::read(RuntimeStateKeys::Assets(AssetsKeys::AssetExists(id))).into() +} + +// Parameters to extrinsics representing an asset id (`AssetIdParameter`) and a balance amount (`Balance`) are expected +// to be compact encoded. The pop api handles that for the developer. +// +// reference: https://substrate.stackexchange.com/questions/1873/what-is-the-meaning-of-palletcompact-in-pallet-development +// +// Asset id that is compact encoded. +type AssetIdParameter = Compact; +// Balance amount that is compact encoded. +type BalanceParameter = Compact; + +#[derive(Encode)] +pub(crate) enum AssetsCall { + #[codec(index = 0)] + Create { id: AssetIdParameter, admin: MultiAddress, min_balance: Balance }, + #[codec(index = 2)] + StartDestroy { id: AssetIdParameter }, + #[codec(index = 3)] + DestroyAccounts { id: AssetIdParameter }, + #[codec(index = 4)] + DestroyApprovals { id: AssetIdParameter }, + #[codec(index = 5)] + FinishDestroy { id: AssetIdParameter }, + #[codec(index = 6)] + Mint { + id: AssetIdParameter, + beneficiary: MultiAddress, + amount: BalanceParameter, + }, + #[codec(index = 7)] + Burn { id: AssetIdParameter, who: MultiAddress, amount: BalanceParameter }, + #[codec(index = 8)] + Transfer { id: AssetIdParameter, target: MultiAddress, amount: BalanceParameter }, + #[codec(index = 9)] + TransferKeepAlive { + id: AssetIdParameter, + target: MultiAddress, + amount: BalanceParameter, + }, + #[codec(index = 10)] + ForceTransfer { + id: AssetIdParameter, + source: MultiAddress, + dest: MultiAddress, + amount: BalanceParameter, + }, + #[codec(index = 11)] + Freeze { id: AssetIdParameter, who: MultiAddress }, + #[codec(index = 12)] + Thaw { id: AssetIdParameter, who: MultiAddress }, + #[codec(index = 13)] + FreezeAsset { id: AssetIdParameter }, + #[codec(index = 14)] + ThawAsset { id: AssetIdParameter }, + #[codec(index = 15)] + TransferOwnership { id: AssetIdParameter, owner: MultiAddress }, + #[codec(index = 16)] + SetTeam { + id: AssetIdParameter, + issuer: MultiAddress, + admin: MultiAddress, + freezer: MultiAddress, + }, + #[codec(index = 17)] + SetMetadata { id: AssetIdParameter, name: Vec, symbol: Vec, decimals: u8 }, + #[codec(index = 18)] + ClearMetadata { id: AssetIdParameter }, + #[codec(index = 22)] + ApproveTransfer { + id: AssetIdParameter, + delegate: MultiAddress, + amount: BalanceParameter, + }, + #[codec(index = 23)] + CancelApproval { id: AssetIdParameter, delegate: MultiAddress }, + #[codec(index = 24)] + ForceCancelApproval { + id: AssetIdParameter, + owner: MultiAddress, + delegate: MultiAddress, + }, + #[codec(index = 25)] + TransferApproved { + id: AssetIdParameter, + owner: MultiAddress, + destination: MultiAddress, + amount: BalanceParameter, + }, + #[codec(index = 26)] + Touch { id: AssetIdParameter }, + #[codec(index = 27)] + Refund { id: AssetIdParameter, allow_burn: bool }, + #[codec(index = 28)] + SetMinBalance { id: AssetIdParameter, min_balance: BalanceParameter }, + #[codec(index = 29)] + TouchOther { id: AssetIdParameter, who: MultiAddress }, + #[codec(index = 30)] + RefundOther { id: AssetIdParameter, who: MultiAddress }, + #[codec(index = 31)] + Block { id: AssetIdParameter, who: MultiAddress }, +} + +#[derive(Debug, Copy, Clone, PartialEq, Eq, Encode, scale::Decode)] +#[cfg_attr(feature = "std", derive(scale_info::TypeInfo))] +pub enum AssetsError { + /// Account balance must be greater than or equal to the transfer amount. + BalanceLow, + /// The account to alter does not exist. + NoAccount, + /// The signing account has no permission to do the operation. + NoPermission, + /// The given asset ID is unknown. + Unknown, + /// The origin account is frozen. + Frozen, + /// The asset ID is already taken. + InUse, + /// Invalid witness data given. + BadWitness, + /// Minimum balance should be non-zero. + MinBalanceZero, + /// Unable to increment the consumer reference counters on the account. Either no provider + /// reference exists to allow a non-zero balance of a non-self-sufficient asset, or one + /// fewer then the maximum number of consumers has been reached. + UnavailableConsumer, + /// Invalid metadata given. + BadMetadata, + /// No approval exists that would allow the transfer. + Unapproved, + /// The source account would not survive the transfer and it needs to stay alive. + WouldDie, + /// The asset-account already exists. + AlreadyExists, + /// The asset-account doesn't have an associated deposit. + NoDeposit, + /// The operation would result in funds being burned. + WouldBurn, + /// The asset is a live asset and is actively being used. Usually emit for operations such + /// as `start_destroy` which require the asset to be in a destroying state. + LiveAsset, + /// The asset is not live, and likely being destroyed. + AssetNotLive, + /// The asset status is not the expected status. + IncorrectStatus, + /// The asset should be frozen before the given operation. + NotFrozen, + /// Callback action resulted in error. + CallbackFailed, +} + +impl TryFrom for AssetsError { + type Error = PopApiError; + + fn try_from(status_code: u32) -> core::result::Result { + use AssetsError::*; + match status_code { + 0 => Ok(BalanceLow), + 1 => Ok(NoAccount), + 2 => Ok(NoPermission), + 3 => Ok(Unknown), + 4 => Ok(Frozen), + 5 => Ok(InUse), + 6 => Ok(BadWitness), + 7 => Ok(MinBalanceZero), + 8 => Ok(UnavailableConsumer), + 9 => Ok(BadMetadata), + 10 => Ok(Unapproved), + 11 => Ok(WouldDie), + 12 => Ok(AlreadyExists), + 13 => Ok(NoDeposit), + 14 => Ok(WouldBurn), + 15 => Ok(LiveAsset), + 16 => Ok(AssetNotLive), + 17 => Ok(IncorrectStatus), + 18 => Ok(NotFrozen), + _ => todo!(), + } + } +} diff --git a/pop-api/src/v0/assets/pallets/mod.rs b/pop-api/src/v0/assets/pallets/mod.rs new file mode 100644 index 00000000..0b8a53a0 --- /dev/null +++ b/pop-api/src/v0/assets/pallets/mod.rs @@ -0,0 +1 @@ +pub(crate) mod assets; diff --git a/pop-api/src/v0/assets/use_cases/fungibles.rs b/pop-api/src/v0/assets/use_cases/fungibles.rs new file mode 100644 index 00000000..4af5d97e --- /dev/null +++ b/pop-api/src/v0/assets/use_cases/fungibles.rs @@ -0,0 +1,372 @@ +use crate::{ + assets::pallets, + error::PopApiError::{self, *}, + AccountId, Balance, *, +}; +use ink::prelude::vec::Vec; +use primitives::AssetId; + +type Result = core::result::Result; + +/// Local Fungibles: +/// 1. PSP-22 Interface +/// 2. PSP-22 Metadata Interface +/// 3. Asset Management + +/// 1. PSP-22 Interface: +/// - total_supply +/// - balance_of +/// - allowance +/// - transfer +/// - transfer_from +/// - approve +/// - increase_allowance +/// - decrease_allowance + +/// Returns the total token supply for a given asset ID. +/// +/// # Arguments +/// * `id` - The ID of the asset. +/// +/// # Returns +/// The total supply of the token, or an error if the operation fails. +pub fn total_supply(id: AssetId) -> Result { + pallets::assets::total_supply(id) +} + +/// Returns the account balance for the specified `owner` for a given asset ID. Returns `0` if +/// the account is non-existent. +/// +/// # Arguments +/// * `id` - The ID of the asset. +/// * `owner` - The account whose balance is being queried. +/// +/// # Returns +/// The balance of the specified account, or an error if the operation fails. +pub fn balance_of(id: AssetId, owner: AccountId) -> Result { + pallets::assets::balance_of(id, owner) +} + +/// Returns the amount which `spender` is still allowed to withdraw from `owner` for a given +/// asset ID. Returns `0` if no allowance has been set. +/// +/// # Arguments +/// * `id` - The ID of the asset. +/// * `owner` - The account that owns the tokens. +/// * `spender` - The account that is allowed to spend the tokens. +/// +/// # Returns +/// The remaining allowance, or an error if the operation fails. +pub fn allowance(id: AssetId, owner: AccountId, spender: AccountId) -> Result { + pallets::assets::allowance(id, owner, spender) +} + +/// Transfers `value` amount of tokens from the caller's account to account `to`, with additional +/// `data` in unspecified format. +/// +/// # Arguments +/// * `id` - The ID of the asset. +/// * `to` - The recipient account. +/// * `value` - The number of tokens to transfer. +/// +/// # Returns +/// Returns `Ok(())` if successful, or an error if the transfer fails. +pub fn transfer( + id: AssetId, + to: impl Into>, + value: Balance, +) -> Result<()> { + pallets::assets::transfer(id, to, value) +} + +/// Transfers `value` tokens on behalf of `from` to account `to` with additional `data` +/// in unspecified format. If `from` is equal to `None`, tokens will be minted to account `to`. If +/// `to` is equal to `None`, tokens will be burned from account `from`. +/// +/// # Arguments +/// * `id` - The ID of the asset. +/// * `from` - The account from which the tokens are transferred. +/// * `to` - The recipient account. +/// * `value` - The number of tokens to transfer. +/// +/// # Returns +/// Returns `Ok(())` if successful, or an error if the transfer fails. +pub fn transfer_from( + id: AssetId, + from: Option>>, + to: Option>>, + value: Balance, + _data: &[u8], +) -> Result<()> { + match (from, to) { + (None, Some(to)) => pallets::assets::mint(id, to, value), + (Some(from), None) => pallets::assets::burn(id, from, value), + (Some(from), Some(to)) => pallets::assets::transfer_approved(id, from, to, value), + _ => Ok(()), + } +} + +/// Approves an account to spend a specified number of tokens on behalf of the caller. +/// +/// # Arguments +/// * `id` - The ID of the asset. +/// * `spender` - The account that is allowed to spend the tokens. +/// * `value` - The number of tokens to approve. +/// +/// # Returns +/// Returns `Ok(())` if successful, or an error if the approval fails. +// #[allow(unused_variables)] +// fn approve(id: AssetId, spender: AccountId, value: Balance) -> Result<()> { +// todo!() +// // TODO: read allowance and increase or decrease. +// // Ok(dispatch(RuntimeCall::Assets(AssetsCall::ApproveTransfer { +// // id: id.into(), +// // delegate: spender.into(), +// // amount: Compact(value), +// // }))?) +// } + +/// Increases the allowance of a spender. +/// +/// # Arguments +/// * `id` - The ID of the asset. +/// * `spender` - The account that is allowed to spend the tokens. +/// * `value` - The number of tokens to increase the allowance by. +/// +/// # Returns +/// Returns `Ok(())` if successful, or an error if the operation fails. +// fn increase_allowance(id: AssetId, spender: AccountId, value: Balance) -> Result<()> { +// Ok(dispatch(RuntimeCall::Assets(AssetsCall::ApproveTransfer { +// id: id.into(), +// delegate: spender.into(), +// amount: Compact(value), +// }))?) +// } + +/// Decreases the allowance of a spender. +/// +/// # Arguments +/// * `id` - The ID of the asset. +/// * `spender` - The account that is allowed to spend the tokens. +/// * `value` - The number of tokens to decrease the allowance by. +/// +/// # Returns +/// Returns `Ok(())` if successful, or an error if the operation fails. +// #[allow(unused_variables)] +// fn decrease_allowance(id: AssetId, spender: AccountId, value: Balance) -> Result<()> { +// todo!() +// // TODO: cancel_approval + approve_transfer +// // Ok(dispatch(RuntimeCall::Assets(AssetsCall::CancelApproval { +// // id: id.into(), +// // delegate: delegate.into(), +// // }))?) +// // Ok(dispatch(RuntimeCall::Assets(AssetsCall::ApproveTransfer { +// // id: id.into(), +// // delegate: spender.into(), +// // amount: Compact(value), +// // }))?) +// } + +/// 2. PSP-22 Metadata Interface: +/// - token_name +/// - token_symbol +/// - token_decimals + +/// Returns the token name for a given asset ID. +/// +/// # Arguments +/// * `id` - The ID of the asset. +/// +/// # Returns +/// The name of the token as a byte vector, or an error if the operation fails. +// #[allow(unused_variables)] +// pub fn token_name(id: AssetId) -> Result>> { +// todo!() +// // Ok(state::read(RuntimeStateKeys::Assets(AssetsKeys::TokenName(id)))?) +// } + +/// Returns the token symbol for a given asset ID. +/// +/// # Arguments +/// * `id` - The ID of the asset. +/// +/// # Returns +/// The symbol of the token as a byte vector, or an error if the operation fails. +// #[allow(unused_variables)] +// fn token_symbol(id: AssetId) -> Result>> { +// todo!() +// } + +/// Returns the token decimals for a given asset ID. +/// +/// # Arguments +/// * `id` - The ID of the asset. +/// +/// # Returns +/// The number of decimals of the token as a byte vector, or an error if the operation fails. +// #[allow(unused_variables)] +// fn token_decimals(id: AssetId) -> Result>> { +// todo!() +// } + +/// 3. Asset Management: +/// - create +/// - start_destroy +/// - destroy_accounts +/// - destroy_approvals +/// - finish_destroy +/// - set_metadata +/// - clear_metadata + +/// Create a new token with a given asset ID. +/// +/// # Arguments +/// * `id` - The ID of the asset. +/// * `admin` - The account that will administer the asset. +/// * `min_balance` - The minimum balance required for accounts holding this asset. +/// +/// # Returns +/// Returns `Ok(())` if successful, or an error if the creation fails. +pub fn create( + id: AssetId, + admin: impl Into>, + min_balance: Balance, +) -> Result<()> { + pallets::assets::create(id, admin, min_balance) +} + +/// Start the process of destroying a token with a given asset ID. +/// +/// # Arguments +/// * `id` - The ID of the asset. +/// +/// # Returns +/// Returns `Ok(())` if successful, or an error if the operation fails. +// fn start_destroy(id: AssetId) -> Result<()> { +// Ok(dispatch(RuntimeCall::Assets(AssetsCall::StartDestroy { +// id: id.into(), +// }))?) +// } + +/// Destroy all accounts associated with a token with a given asset ID. +/// +/// # Arguments +/// * `id` - The ID of the asset. +/// +/// # Returns +/// Returns `Ok(())` if successful, or an error if the operation fails. +// fn destroy_accounts(id: AssetId) -> Result<()> { +// Ok(dispatch(RuntimeCall::Assets(AssetsCall::DestroyAccounts { +// id: id.into(), +// }))?) +// } + +/// Destroy all approvals associated with a token with a given asset ID. +/// +/// # Arguments +/// * `id` - The ID of the asset. +/// +/// # Returns +/// Returns `Ok(())` if successful, or an error if the operation fails. +// fn destroy_approvals(id: AssetId) -> Result<()> { +// Ok(dispatch(RuntimeCall::Assets(AssetsCall::DestroyApprovals { +// id: id.into(), +// }))?) +// } + +/// Complete the process of destroying a token with a given asset ID. +/// +/// # Arguments +/// * `id` - The ID of the asset. +/// +/// # Returns +/// Returns `Ok(())` if successful, or an error if the operation fails. +// fn finish_destroy(id: AssetId) -> Result<()> { +// Ok(dispatch(RuntimeCall::Assets(AssetsCall::FinishDestroy { +// id: id.into(), +// }))?) +// } + +/// Set the metadata for a token with a given asset ID. +/// +/// # Arguments +/// * `id` - The ID of the asset. +/// +/// # Returns +/// Returns `Ok(())` if successful, or an error if the operation fails. +pub fn set_metadata(id: AssetId, name: Vec, symbol: Vec, decimals: u8) -> Result<()> { + pallets::assets::set_metadata(id, name, symbol, decimals) +} + +/// Clear the metadata for a token with a given asset ID. +/// +/// # Arguments +/// * `id` - The ID of the asset. +/// +/// # Returns +/// Returns `Ok(())` if successful, or an error if the operation fails. +// fn clear_metadata(id: AssetId) -> Result<()> { +// Ok(dispatch(RuntimeCall::Assets(AssetsCall::ClearMetadata { +// id: id.into(), +// }))?) +// } + +pub fn asset_exists(id: AssetId) -> Result { + pallets::assets::asset_exists(id) +} + +#[derive(Debug, Copy, Clone, PartialEq, Eq, Encode, scale::Decode)] +#[cfg_attr(feature = "std", derive(scale_info::TypeInfo))] +pub enum FungiblesError { + /// The asset is not live; either frozen or being destroyed. + AssetNotLive, + /// Not enough allowance to fulfill a request is available. + InsufficientAllowance, + /// Not enough balance to fulfill a request is available. + InsufficientBalance, + /// The asset ID is already taken. + InUse, + /// Minimum balance should be non-zero. + MinBalanceZero, + /// The account to alter does not exist. + NoAccount, + /// The signing account has no permission to do the operation. + NoPermission, + /// The given asset ID is unknown. + Unknown, + // // TODO: + // // - Originally `InsufficientBalance` for the deposit but this would result in the same error + // // as the error when there is insufficient balance for transferring an asset. + /// No balance for creation of assets or fees. + NoBalance, +} + +// TODO: make generic. +pub(crate) fn convert_to_fungibles_error(index: u8, error: u8) -> PopApiError { + match index { + 10 => balance_into(error), + 52 => assets_into(error), + _ => Module { index, error }, + } +} + +fn balance_into(error: u8) -> PopApiError { + match error { + 2 => UseCaseError(FungiblesError::NoBalance), + _ => Module { index: 10, error }, + } +} + +fn assets_into(error: u8) -> PopApiError { + match error { + 0 => UseCaseError(FungiblesError::InsufficientBalance), + 1 => UseCaseError(FungiblesError::NoAccount), + 2 => UseCaseError(FungiblesError::NoPermission), + 3 => UseCaseError(FungiblesError::Unknown), + 5 => UseCaseError(FungiblesError::InUse), + 7 => UseCaseError(FungiblesError::MinBalanceZero), + 10 => UseCaseError(FungiblesError::InsufficientAllowance), + 16 => UseCaseError(FungiblesError::AssetNotLive), + _ => Module { index: 52, error }, + } +} diff --git a/pop-api/src/v0/assets/use_cases/mod.rs b/pop-api/src/v0/assets/use_cases/mod.rs new file mode 100644 index 00000000..182590df --- /dev/null +++ b/pop-api/src/v0/assets/use_cases/mod.rs @@ -0,0 +1 @@ +pub mod fungibles; diff --git a/pop-api/src/v0/balances.rs b/pop-api/src/v0/balances.rs index 08db0a75..5d38d851 100644 --- a/pop-api/src/v0/balances.rs +++ b/pop-api/src/v0/balances.rs @@ -1,9 +1,7 @@ -use crate::{ - dispatch, primitives::MultiAddress, v0::RuntimeCall, AccountId, PopApiError, - PopApiError::UnknownModuleStatusCode, -}; +// TODO: what to put in this file? +use crate::{dispatch, error::PopApiError, primitives::MultiAddress, v0::RuntimeCall, AccountId}; -type Result = core::result::Result; +type Result = core::result::Result; pub fn transfer_keep_alive( dest: impl Into>, @@ -17,7 +15,7 @@ pub fn transfer_keep_alive( #[derive(scale::Encode)] #[allow(dead_code)] -pub(crate) enum BalancesCall { +pub enum BalancesCall { #[codec(index = 3)] TransferKeepAlive { dest: MultiAddress, @@ -28,7 +26,7 @@ pub(crate) enum BalancesCall { #[derive(Debug, Copy, Clone, PartialEq, Eq, scale::Encode, scale::Decode)] #[cfg_attr(feature = "std", derive(scale_info::TypeInfo))] -pub(crate) enum BalancesError { +pub enum BalancesError { /// Vesting balance too high to send value. VestingBalance, /// Account liquidity restrictions prevent withdrawal. @@ -73,15 +71,6 @@ impl TryFrom for BalancesError { 9 => Ok(TooManyFreezes), 10 => Ok(IssuanceDeactivated), 11 => Ok(DeltaZero), - _ => Err(UnknownModuleStatusCode(status_code)), - } - } -} - -impl From for BalancesError { - fn from(error: PopApiError) -> Self { - match error { - PopApiError::Balances(e) => e, _ => todo!(), } } diff --git a/pop-api/src/v0/contracts.rs b/pop-api/src/v0/contracts.rs deleted file mode 100644 index 5d4a3692..00000000 --- a/pop-api/src/v0/contracts.rs +++ /dev/null @@ -1,152 +0,0 @@ -use crate::{PopApiError, PopApiError::UnknownModuleStatusCode}; - -#[derive(Debug, Copy, Clone, PartialEq, Eq, scale::Encode, scale::Decode)] -#[cfg_attr(feature = "std", derive(scale_info::TypeInfo))] -pub enum Error { - /// Invalid schedule supplied, e.g. with zero weight of a basic operation. - InvalidSchedule, - /// Invalid combination of flags supplied to `seal_call` or `seal_delegate_call`. - InvalidCallFlags, - /// The executed contract exhausted its gas limit. - OutOfGas, - /// The output buffer supplied to a contract API call was too small. - OutputBufferTooSmall, - /// Performing the requested transfer failed. Probably because there isn't enough - /// free balance in the sender's account. - TransferFailed, - /// Performing a call was denied because the calling depth reached the limit - /// of what is specified in the schedule. - MaxCallDepthReached, - /// No contract was found at the specified address. - ContractNotFound, - /// The code supplied to `instantiate_with_code` exceeds the limit specified in the - /// current schedule. - CodeTooLarge, - /// No code could be found at the supplied code hash. - CodeNotFound, - /// No code info could be found at the supplied code hash. - CodeInfoNotFound, - /// A buffer outside of sandbox memory was passed to a contract API function. - OutOfBounds, - /// Input passed to a contract API function failed to decode as expected type. - DecodingFailed, - /// Contract trapped during execution. - ContractTrapped, - /// The size defined in `T::MaxValueSize` was exceeded. - ValueTooLarge, - /// Termination of a contract is not allowed while the contract is already - /// on the call stack. Can be triggered by `seal_terminate`. - TerminatedWhileReentrant, - /// `seal_call` forwarded this contracts input. It therefore is no longer available. - InputForwarded, - /// The subject passed to `seal_random` exceeds the limit. - RandomSubjectTooLong, - /// The amount of topics passed to `seal_deposit_events` exceeds the limit. - TooManyTopics, - /// The chain does not provide a chain extension. Calling the chain extension results - /// in this error. Note that this usually shouldn't happen as deploying such contracts - /// is rejected. - NoChainExtension, - /// Failed to decode the XCM program. - XCMDecodeFailed, - /// A contract with the same AccountId already exists. - DuplicateContract, - /// A contract self destructed in its constructor. - /// - /// This can be triggered by a call to `seal_terminate`. - TerminatedInConstructor, - /// A call tried to invoke a contract that is flagged as non-reentrant. - /// The only other cause is that a call from a contract into the runtime tried to call back - /// into `pallet-contracts`. This would make the whole pallet reentrant with regard to - /// contract code execution which is not supported. - ReentranceDenied, - /// Origin doesn't have enough balance to pay the required storage deposits. - StorageDepositNotEnoughFunds, - /// More storage was created than allowed by the storage deposit limit. - StorageDepositLimitExhausted, - /// Code removal was denied because the code is still in use by at least one contract. - CodeInUse, - /// The contract ran to completion but decided to revert its storage changes. - /// Please note that this error is only returned from extrinsics. When called directly - /// or via RPC an `Ok` will be returned. In this case the caller needs to inspect the flags - /// to determine whether a reversion has taken place. - ContractReverted, - /// The contract's code was found to be invalid during validation. - /// - /// The most likely cause of this is that an API was used which is not supported by the - /// node. This happens if an older node is used with a new version of ink!. Try updating - /// your node to the newest available version. - /// - /// A more detailed error can be found on the node console if debug messages are enabled - /// by supplying `-lruntime::contracts=debug`. - CodeRejected, - /// An indeterministic code was used in a context where this is not permitted. - Indeterministic, - /// A pending migration needs to complete before the extrinsic can be called. - MigrationInProgress, - /// Migrate dispatch call was attempted but no migration was performed. - NoMigrationPerformed, - /// The contract has reached its maximum number of delegate dependencies. - MaxDelegateDependenciesReached, - /// The dependency was not found in the contract's delegate dependencies. - DelegateDependencyNotFound, - /// The contract already depends on the given delegate dependency. - DelegateDependencyAlreadyExists, - /// Can not add a delegate dependency to the code hash of the contract itself. - CannotAddSelfAsDelegateDependency, -} - -impl TryFrom for Error { - type Error = PopApiError; - - fn try_from(status_code: u32) -> core::result::Result { - use Error::*; - match status_code { - 0 => Ok(InvalidSchedule), - 1 => Ok(InvalidCallFlags), - 2 => Ok(OutOfGas), - 3 => Ok(OutputBufferTooSmall), - 4 => Ok(TransferFailed), - 5 => Ok(MaxCallDepthReached), - 6 => Ok(ContractNotFound), - 7 => Ok(CodeTooLarge), - 8 => Ok(CodeNotFound), - 9 => Ok(CodeInfoNotFound), - 10 => Ok(OutOfBounds), - 11 => Ok(DecodingFailed), - 12 => Ok(ContractTrapped), - 13 => Ok(ValueTooLarge), - 14 => Ok(TerminatedWhileReentrant), - 15 => Ok(InputForwarded), - 16 => Ok(RandomSubjectTooLong), - 17 => Ok(TooManyTopics), - 18 => Ok(NoChainExtension), - 19 => Ok(XCMDecodeFailed), - 20 => Ok(DuplicateContract), - 21 => Ok(TerminatedInConstructor), - 22 => Ok(ReentranceDenied), - 23 => Ok(StorageDepositNotEnoughFunds), - 24 => Ok(StorageDepositLimitExhausted), - 25 => Ok(CodeInUse), - 26 => Ok(ContractReverted), - 27 => Ok(CodeRejected), - 28 => Ok(Indeterministic), - 29 => Ok(MigrationInProgress), - 30 => Ok(NoMigrationPerformed), - 31 => Ok(MaxDelegateDependenciesReached), - 32 => Ok(DelegateDependencyNotFound), - 33 => Ok(DelegateDependencyAlreadyExists), - 34 => Ok(CannotAddSelfAsDelegateDependency), - _ => Err(UnknownModuleStatusCode(status_code)), - } - } -} - -impl From for Error { - fn from(error: PopApiError) -> Self { - match error { - PopApiError::Contracts(e) => e, - _ => panic!("expected balances error"), - } - } -} diff --git a/pop-api/src/v0/cross_chain/mod.rs b/pop-api/src/v0/cross_chain/mod.rs index 1e5afbf5..1d3c5b7d 100644 --- a/pop-api/src/v0/cross_chain/mod.rs +++ b/pop-api/src/v0/cross_chain/mod.rs @@ -1,8 +1,8 @@ pub mod coretime; -use crate::{PopApiError::UnknownModuleStatusCode, *}; +use crate::error::PopApiError; -type Result = core::result::Result; +type Result = core::result::Result; #[derive(Debug, Copy, Clone, PartialEq, Eq, scale::Encode, scale::Decode)] #[cfg_attr(feature = "std", derive(scale_info::TypeInfo))] @@ -92,16 +92,7 @@ impl TryFrom for Error { 21 => Ok(InvalidAssetUnknownReserve), 22 => Ok(InvalidAssetUnsupportedReserve), 23 => Ok(TooManyReserves), - _ => Err(UnknownModuleStatusCode(status_code)), - } - } -} - -impl From for Error { - fn from(error: PopApiError) -> Self { - match error { - PopApiError::Xcm(e) => e, - _ => panic!("expected xcm error"), + _ => todo!(), } } } diff --git a/pop-api/src/v0/dispatch_error.rs b/pop-api/src/v0/dispatch_error.rs deleted file mode 100644 index 6ed40ce5..00000000 --- a/pop-api/src/v0/dispatch_error.rs +++ /dev/null @@ -1,57 +0,0 @@ -use super::*; - -#[derive(Debug, Copy, Clone, PartialEq, Eq, scale::Encode, scale::Decode)] -#[cfg_attr(feature = "std", derive(scale_info::TypeInfo))] -pub(crate) enum TokenError { - /// Funds are unavailable. - FundsUnavailable, - /// Some part of the balance gives the only provider reference to the account and thus cannot - /// be (re)moved. - OnlyProvider, - /// Account cannot exist with the funds that would be given. - BelowMinimum, - /// Account cannot be created. - CannotCreate, - /// The asset in question is unknown. - UnknownAsset, - /// Funds exist but are frozen. - Frozen, - /// Operation is not supported by the asset. - Unsupported, - /// Account cannot be created for a held balance. - CannotCreateHold, - /// Withdrawal would cause unwanted loss of account. - NotExpendable, - /// Account cannot receive the assets. - Blocked, -} - -impl TryFrom for TokenError { - type Error = crate::PopApiError; - - fn try_from(status_code: u32) -> core::result::Result { - use TokenError::*; - match status_code { - 0 => Ok(FundsUnavailable), - 1 => Ok(OnlyProvider), - 2 => Ok(BelowMinimum), - 3 => Ok(CannotCreate), - 4 => Ok(UnknownAsset), - 5 => Ok(Frozen), - 6 => Ok(Unsupported), - 7 => Ok(CannotCreateHold), - 8 => Ok(NotExpendable), - 9 => Ok(Blocked), - _ => todo!(), - } - } -} - -impl From for TokenError { - fn from(error: PopApiError) -> Self { - match error { - PopApiError::TokenError(e) => e, - _ => todo!(), - } - } -} diff --git a/pop-api/src/v0/mod.rs b/pop-api/src/v0/mod.rs index 02169c22..75bcb878 100644 --- a/pop-api/src/v0/mod.rs +++ b/pop-api/src/v0/mod.rs @@ -5,9 +5,7 @@ use crate::{ pub mod assets; pub mod balances; -pub mod contracts; pub mod cross_chain; -pub mod dispatch_error; pub mod nfts; pub mod state; @@ -22,5 +20,5 @@ pub(crate) enum RuntimeCall { #[codec(index = 50)] Nfts(nfts::NftCalls), #[codec(index = 52)] - Assets(assets::fungibles::AssetsCall), + Assets(assets::pallets::assets::AssetsCall), } diff --git a/pop-api/src/v0/nfts.rs b/pop-api/src/v0/nfts.rs index 946a3eca..2de306a9 100644 --- a/pop-api/src/v0/nfts.rs +++ b/pop-api/src/v0/nfts.rs @@ -1,12 +1,12 @@ use super::RuntimeCall; -use crate::{PopApiError::UnknownModuleStatusCode, *}; +use crate::{PopApiError, *}; use ink::prelude::vec::Vec; use primitives::{ApprovalsLimit, BoundedBTreeMap, KeyLimit, MultiAddress}; pub use primitives::{CollectionId, ItemId}; use scale::Encode; pub use types::*; -type Result = core::result::Result; +type Result = core::result::Result; /// Issue a new collection of non-fungible items pub fn create( @@ -660,16 +660,7 @@ impl TryFrom for Error { 42 => Ok(WrongNamespace), 43 => Ok(CollectionNotEmpty), 44 => Ok(WitnessRequired), - _ => Err(UnknownModuleStatusCode(status_code)), - } - } -} - -impl From for Error { - fn from(error: PopApiError) -> Self { - match error { - PopApiError::Nfts(e) => e, - _ => panic!("unexpected pallet nfts error. This error is unknown to pallet nfts"), + _ => todo!(), } } } diff --git a/primitives/src/storage_keys.rs b/primitives/src/storage_keys.rs index 67448842..fc7234aa 100644 --- a/primitives/src/storage_keys.rs +++ b/primitives/src/storage_keys.rs @@ -1,5 +1,4 @@ use super::*; -// use scale::{Decode, Encode, MaxEncodedLen}; #[derive(Encode, Decode, Debug, MaxEncodedLen)] pub enum RuntimeStateKeys { @@ -28,8 +27,6 @@ pub enum NftsKeys { Owner(CollectionId, ItemId), /// Get the attribute value of `item` of `collection` corresponding to `key`. Attribute(CollectionId, ItemId, BoundedVec), - // /// Get the custom attribute value of `item` of `collection` corresponding to `key`. - // CustomAttribute(AccountId, CollectionId, ItemId, BoundedVec), /// Get the system attribute value of `item` of `collection` corresponding to `key` SystemAttribute(CollectionId, Option, BoundedVec), /// Get the attribute value of `item` of `collection` corresponding to `key`. diff --git a/runtime/devnet/Cargo.toml b/runtime/devnet/Cargo.toml index d4fe2923..46208d8f 100644 --- a/runtime/devnet/Cargo.toml +++ b/runtime/devnet/Cargo.toml @@ -91,6 +91,7 @@ parachain-info.workspace = true env_logger = "0.11.2" hex = "0.4.3" enumflags2 = "0.7.9" +pop-api = { path = "../../pop-api", default-features = false } [features] default = ["std"] @@ -138,6 +139,7 @@ std = [ "polkadot-parachain-primitives/std", "polkadot-runtime-common/std", "pop-primitives/std", + "pop-api/std", "scale-info/std", "sp-api/std", "sp-io/std", diff --git a/runtime/devnet/src/extensions/mod.rs b/runtime/devnet/src/extensions.rs similarity index 97% rename from runtime/devnet/src/extensions/mod.rs rename to runtime/devnet/src/extensions.rs index d2129c4f..014893f9 100644 --- a/runtime/devnet/src/extensions/mod.rs +++ b/runtime/devnet/src/extensions.rs @@ -17,10 +17,7 @@ use pop_primitives::{ AssetId, CollectionId, ItemId, }; use sp_core::crypto::UncheckedFrom; -use sp_runtime::{ - traits::{BlockNumberProvider, Dispatchable}, - DispatchError, -}; +use sp_runtime::traits::{BlockNumberProvider, Dispatchable}; use sp_std::{boxed::Box, vec::Vec}; use xcm::{ latest::{prelude::*, OriginKind::SovereignAccount}, @@ -32,9 +29,6 @@ use crate::{ RuntimeOrigin, UNIT, }; -#[cfg(test)] -mod tests; - const LOG_TARGET: &str = "pop-api::extension"; type ContractSchedule = ::Schedule; @@ -42,6 +36,7 @@ type ContractSchedule = ::Schedule; #[derive(Default)] pub struct PopApiExtension; +// TODO: check removal or simplification of trait bounds. impl ChainExtension for PopApiExtension where T: pallet_contracts::Config @@ -59,31 +54,12 @@ where fn call(&mut self, env: Environment) -> Result where E: Ext, - // T::AccountId: UncheckedFrom + AsRef<[u8]>, { log::debug!(target:LOG_TARGET, " extension called "); match v0::FuncId::try_from(env.func_id())? { - v0::FuncId::Dispatch => { - match dispatch::(env) { - Ok(()) => Ok(RetVal::Converging(0)), - Err(DispatchError::Module(error)) => { - // encode status code = pallet index in runtime + error index, allowing for - // 999 errors - let first = (3u32 * 1_000_000u32) - + (error.index as u32 * 1_000u32) - + u32::from_le_bytes(error.error); - Ok(RetVal::Converging( - // (3u32 * 1_000_000u32) - // + (error.index as u32 * 1_000u32) - // + u32::from_le_bytes(error.error), - first, - )) - }, - Err(DispatchError::Token(error)) => { - Ok(RetVal::Converging((7u32 * 1_000_000u32) + error as u32)) - }, - Err(e) => Err(e), - } + v0::FuncId::Dispatch => match dispatch::(env) { + Ok(()) => Ok(RetVal::Converging(0)), + Err(e) => Ok(RetVal::Converging(convert_to_status_code(e))), }, v0::FuncId::ReadState => { read_state::(env)?; @@ -97,6 +73,17 @@ where } } +pub(crate) fn convert_to_status_code(error: DispatchError) -> u32 { + match error { + _ => { + let mut encoded_error = error.encode(); + // Resize the encoded value to 4 bytes in order to decode the value in a u32 (4 bytes). + encoded_error.resize(4, 0); + u32::decode(&mut &encoded_error[..]).unwrap() + }, + } +} + pub mod v0 { #[derive(Debug)] pub enum FuncId { diff --git a/runtime/devnet/src/extensions/tests/mod.rs b/runtime/devnet/src/extensions/tests/mod.rs deleted file mode 100644 index cbd13d62..00000000 --- a/runtime/devnet/src/extensions/tests/mod.rs +++ /dev/null @@ -1,89 +0,0 @@ -#![cfg(test)] -use super::*; -use crate::{Assets, Balances, Contracts, Runtime, System}; -use pallet_contracts::{Code, CollectEvents, Determinism, ExecReturnValue}; -use sp_runtime::{traits::Hash, AccountId32, BuildStorage}; - -mod local_fungibles; - -type Balance = u128; -type AssetId = u32; -const DEBUG_OUTPUT: pallet_contracts::DebugInfo = pallet_contracts::DebugInfo::UnsafeDebug; - -const ALICE: AccountId32 = AccountId32::new([1_u8; 32]); -const BOB: AccountId32 = AccountId32::new([2_u8; 32]); -const INIT_AMOUNT: Balance = 100_000_000 * UNIT; -const INIT_VALUE: Balance = 100 * UNIT; -const GAS_LIMIT: Weight = Weight::from_parts(100_000_000_000, 3 * 1024 * 1024); - -fn new_test_ext() -> sp_io::TestExternalities { - let mut t = frame_system::GenesisConfig::::default() - .build_storage() - .expect("Frame system builds valid default genesis config"); - - pallet_balances::GenesisConfig:: { - balances: vec![(ALICE, INIT_AMOUNT), (BOB, INIT_AMOUNT)], - } - .assimilate_storage(&mut t) - .expect("Pallet balances storage can be assimilated"); - - let mut ext = sp_io::TestExternalities::new(t); - ext.execute_with(|| System::set_block_number(1)); - ext -} - -fn load_wasm_module(path: &str) -> std::io::Result<(Vec, ::Output)> -where - T: frame_system::Config, -{ - let wasm_binary = std::fs::read(path)?; - let code_hash = T::Hashing::hash(&wasm_binary); - Ok((wasm_binary, code_hash)) -} - -fn function_selector(name: &str) -> Vec { - let hash = sp_io::hashing::blake2_256(name.as_bytes()); - [hash[0..4].to_vec()].concat() -} - -fn do_bare_call( - addr: AccountId32, - input: Vec, - value: u128, -) -> Result { - let result = Contracts::bare_call( - ALICE, - addr.into(), - value.into(), - GAS_LIMIT, - None, - input, - DEBUG_OUTPUT, - CollectEvents::Skip, - Determinism::Enforced, - ); - log::debug!("Contract debug buffer - {:?}", String::from_utf8(result.debug_message.clone())); - log::debug!("result: {:?}", result); - result.result -} - -// Deploy, instantiate and return contract address. -fn instantiate(contract: &str, init_value: u128, salt: Vec) -> AccountId32 { - let (wasm_binary, _) = - load_wasm_module::(contract).expect("could not read .wasm file"); - let result = Contracts::bare_instantiate( - ALICE, - init_value, - GAS_LIMIT, - None, - Code::Upload(wasm_binary), - function_selector("new"), - salt, - DEBUG_OUTPUT, - CollectEvents::Skip, - ) - .result - .unwrap(); - assert!(!result.result.did_revert(), "deploying contract reverted {:?}", result); - result.account_id -} diff --git a/runtime/devnet/src/lib.rs b/runtime/devnet/src/lib.rs index a82be804..416a3298 100644 --- a/runtime/devnet/src/lib.rs +++ b/runtime/devnet/src/lib.rs @@ -10,6 +10,8 @@ mod extensions; mod weights; // Public due to integration tests crate. pub mod config; +#[cfg(test)] +mod tests; use cumulus_pallet_parachain_system::RelayNumberMonotonicallyIncreases; use polkadot_runtime_common::xcm_sender::NoPriceForMessageDelivery; diff --git a/runtime/devnet/src/extensions/tests/local_fungibles.rs b/runtime/devnet/src/tests/local_fungibles.rs similarity index 70% rename from runtime/devnet/src/extensions/tests/local_fungibles.rs rename to runtime/devnet/src/tests/local_fungibles.rs index 5de162c9..bc13fbde 100644 --- a/runtime/devnet/src/extensions/tests/local_fungibles.rs +++ b/runtime/devnet/src/tests/local_fungibles.rs @@ -2,31 +2,10 @@ use super::*; -#[derive(Decode, Encode, Debug, Eq, PartialEq)] -enum FungiblesError { - /// The asset is not live; either frozen or being destroyed. - AssetNotLive, - /// The amount to mint is less than the existential deposit. - BelowMinimum, - /// Unspecified dispatch error, providing the index and optionally its error index. - DispatchError { index: u8, error: Option }, - /// Not enough allowance to fulfill a request is available. - InsufficientAllowance, - /// Not enough balance to fulfill a request is available. - InsufficientBalance, - /// The asset ID is already taken. - InUse, - /// Minimum balance should be non-zero. - MinBalanceZero, - /// Unspecified pallet error, providing pallet index and error index. - ModuleError { pallet: u8, error: u16 }, - /// The account to alter does not exist. - NoAccount, - /// The signing account has no permission to do the operation. - NoPermission, - /// The given asset ID is unknown. - Unknown, -} +use pop_api::{ + error::{ArithmeticError::*, PopApiError::*, TokenError::*}, + v0::assets::use_cases::fungibles::FungiblesError::*, +}; const ASSET_ID: AssetId = 1; @@ -119,8 +98,7 @@ fn transfer_from( do_bare_call(addr, params, 0).expect("should work") } -// Create an asset and mint to owner. -fn create_asset(asset_id: AssetId, owner: AccountId32, min_balance: Balance) -> AssetId { +fn create_asset(owner: AccountId32, asset_id: AssetId, min_balance: Balance) -> AssetId { assert_eq!( Assets::create( RuntimeOrigin::signed(owner.clone()), @@ -133,31 +111,34 @@ fn create_asset(asset_id: AssetId, owner: AccountId32, min_balance: Balance) -> asset_id } -// Create an asset and mint to owner. +fn mint_asset(owner: AccountId32, asset_id: AssetId, to: AccountId32, value: Balance) -> AssetId { + assert_eq!( + Assets::mint(RuntimeOrigin::signed(owner.clone()), asset_id.into(), to.into(), value), + Ok(()) + ); + asset_id +} + fn create_asset_and_mint_to( - asset_id: AssetId, owner: AccountId32, + asset_id: AssetId, to: AccountId32, value: Balance, ) -> AssetId { - create_asset(asset_id, owner.clone(), 1); - assert_eq!( - Assets::mint(RuntimeOrigin::signed(owner.into()), asset_id.into(), to.into(), value,), - Ok(()) - ); - asset_id + create_asset(owner.clone(), asset_id, 1); + mint_asset(owner, asset_id, to, value) } // Create an asset, mints to, and approves spender. fn create_asset_mint_and_approve( - asset_id: AssetId, owner: AccountId32, + asset_id: AssetId, to: AccountId32, mint: Balance, spender: AccountId32, approve: Balance, ) { - create_asset_and_mint_to(asset_id, owner.clone(), to.clone(), mint); + create_asset_and_mint_to(owner.clone(), asset_id, to.clone(), mint); assert_eq!( Assets::approve_transfer( RuntimeOrigin::signed(to.into()), @@ -199,7 +180,7 @@ fn total_supply_works() { assert_eq!(Assets::total_supply(ASSET_ID), total_supply(addr.clone(), ASSET_ID)); // Tokens in circulation. - create_asset_and_mint_to(ASSET_ID, addr.clone(), BOB, 100); + create_asset_and_mint_to(addr.clone(), ASSET_ID, BOB, 100); assert_eq!(Assets::total_supply(ASSET_ID), total_supply(addr, ASSET_ID)); }); } @@ -219,7 +200,7 @@ fn balance_of_works() { assert_eq!(Assets::balance(ASSET_ID, BOB), balance_of(addr.clone(), ASSET_ID, BOB)); // Tokens in circulation. - create_asset_and_mint_to(ASSET_ID, addr.clone(), BOB, 100); + create_asset_and_mint_to(addr.clone(), ASSET_ID, BOB, 100); assert_eq!(Assets::balance(ASSET_ID, BOB), balance_of(addr, ASSET_ID, BOB)); }); } @@ -242,7 +223,7 @@ fn allowance_works() { ); // Tokens in circulation. - create_asset_mint_and_approve(ASSET_ID, addr.clone(), BOB, 100, ALICE, 50); + create_asset_mint_and_approve(addr.clone(), ASSET_ID, BOB, 100, ALICE, 50); assert_eq!( Assets::allowance(ASSET_ID, &BOB, &ALICE), allowance(addr, ASSET_ID, BOB, ALICE) @@ -265,7 +246,7 @@ fn asset_exists_works() { assert_eq!(Assets::asset_exists(ASSET_ID), asset_exists(addr.clone(), ASSET_ID)); // Tokens in circulation. - create_asset(ASSET_ID, addr.clone(), 1); + create_asset(addr.clone(), ASSET_ID, 1); assert_eq!(Assets::asset_exists(ASSET_ID), asset_exists(addr, ASSET_ID)); }); } @@ -276,34 +257,52 @@ fn asset_exists_works() { // - reserve(): Overflow, LiquidityRestrictions; frozen // - Callback // - StorageDepositLimitExhausted +// todo: errors: +// - TokenErrors +// - Arithmetic +// - https://github.com/paritytech/polkadot-sdk/blob/3977f389cce4a00fd7100f95262e0563622b9aa4/substrate/frame/assets/src/functions.rs#L125 #[test] #[ignore] fn create_works() { new_test_ext().execute_with(|| { let _ = env_logger::try_init(); let new_asset = 2; + // Instantiate a contract without balance (relay token). let addr = instantiate("../../pop-api/examples/fungibles/target/ink/fungibles.wasm", 0, vec![0]); - + // No balance to pay for fees. assert_eq!( - decoded::(create(addr.clone(), ASSET_ID, addr.clone(), 1)), - FungiblesError::InsufficientBalance + decoded::(create(addr.clone(), ASSET_ID, addr.clone(), 1)), + UseCaseError(NoBalance) ); + // Instantiate a contract without balance (relay token). + let addr = + instantiate("../../pop-api/examples/fungibles/target/ink/fungibles.wasm", 100, vec![2]); + // TODO: make sure it has enough for the fees but not for the deposit. + // No balance to pay fe deposit. + assert_eq!( + decoded::(create(addr.clone(), ASSET_ID, addr.clone(), 1)), + UseCaseError(NoBalance) + ); + // Instantiate a contract with balance. let addr = instantiate( "../../pop-api/examples/fungibles/target/ink/fungibles.wasm", INIT_VALUE, vec![1], ); - create_asset(ASSET_ID, ALICE, 1); + create_asset(ALICE, ASSET_ID, 1); + // Asset ID is already taken. assert_eq!( - decoded::(create(addr.clone(), ASSET_ID, BOB, 1)), - FungiblesError::InUse + decoded::(create(addr.clone(), ASSET_ID, BOB, 1)), + UseCaseError(InUse) ); + // The minimal balance for an asset must be non zero. assert_eq!( - decoded::(create(addr.clone(), new_asset, BOB, 0)), - FungiblesError::MinBalanceZero + decoded::(create(addr.clone(), new_asset, BOB, 0)), + UseCaseError(MinBalanceZero) ); - assert!(!create(addr.clone(), new_asset, BOB, 1).did_revert(), "Contract reverted!"); + let result = create(addr.clone(), new_asset, BOB, 1); + assert!(!result.did_revert(), "Contract reverted!"); }); } @@ -318,17 +317,12 @@ fn set_metadata_works() { vec![], ); - create_asset(ASSET_ID, addr.clone(), 1); - + create_asset(addr.clone(), ASSET_ID, 1); let result = set_metadata(addr.clone(), ASSET_ID, vec![12], vec![12], 12); assert!(!result.did_revert(), "Contract reverted!"); }); } -// todo: errors: -// - TokenErrors -// - Arithmetic -// - https://github.com/paritytech/polkadot-sdk/blob/3977f389cce4a00fd7100f95262e0563622b9aa4/substrate/frame/assets/src/functions.rs#L125 #[test] #[ignore] fn transfer_from_mint_works() { @@ -341,20 +335,15 @@ fn transfer_from_mint_works() { ); let amount: Balance = 100 * UNIT; + // Asset does not exist. assert_eq!( - decoded::(transfer_from( - addr.clone(), - 1, - None, - Some(BOB), - amount, - &[0u8] - )), - FungiblesError::Unknown + decoded::(transfer_from(addr.clone(), 1, None, Some(BOB), amount, &[0u8])), + Token(UnknownAsset) ); - let asset = create_asset(1, ALICE, 2); + let asset = create_asset(ALICE, 1, 2); + // Minting can only be done by the owner. assert_eq!( - decoded::(transfer_from( + decoded::(transfer_from( addr.clone(), asset, None, @@ -362,23 +351,18 @@ fn transfer_from_mint_works() { amount, &[0u8] )), - FungiblesError::NoPermission + UseCaseError(NoPermission) ); + // Minimum balance of an asset can not be zero. assert_eq!( - decoded::(transfer_from( - addr.clone(), - asset, - None, - Some(BOB), - 1, - &[0u8] - )), - FungiblesError::BelowMinimum + decoded::(transfer_from(addr.clone(), asset, None, Some(BOB), 1, &[0u8])), + Token(BelowMinimum) ); - let asset = create_asset(2, addr.clone(), 2); + let asset = create_asset(addr.clone(), 2, 2); + // Asset is not live, i.e. frozen or being destroyed. freeze_asset(asset, addr.clone()); assert_eq!( - decoded::(transfer_from( + decoded::(transfer_from( addr.clone(), asset, None, @@ -386,17 +370,31 @@ fn transfer_from_mint_works() { amount, &[0u8] )), - FungiblesError::AssetNotLive + UseCaseError(AssetNotLive) ); thaw_asset(asset, addr.clone()); + // Successful mint. let bob_balance_before_mint = Assets::balance(asset, &BOB); let result = transfer_from(addr.clone(), asset, None, Some(BOB), amount, &[0u8]); assert!(!result.did_revert(), "Contract reverted!"); let bob_balance_after_mint = Assets::balance(asset, &BOB); assert_eq!(bob_balance_after_mint, bob_balance_before_mint + amount); + // Can not mint more tokens than Balance::MAX. + assert_eq!( + decoded::(transfer_from( + addr.clone(), + asset, + None, + Some(BOB), + Balance::MAX, + &[0u8] + )), + Arithmetic(Overflow) + ); + // Asset is not live, i.e. frozen or being destroyed. start_destroy_asset(asset, addr.clone()); assert_eq!( - decoded::(transfer_from( + decoded::(transfer_from( addr.clone(), asset, None, @@ -404,17 +402,15 @@ fn transfer_from_mint_works() { amount, &[0u8] )), - FungiblesError::AssetNotLive + UseCaseError(AssetNotLive) ); }); } // Todo: error: -// - Frozen: account is frozen, who do you freeze an account? // - https://github.com/paritytech/polkadot-sdk/blob/2460cddf57660a88844d201f769eb17a7accce5a/substrate/frame/assets/src/functions.rs#L161 // - ArithmeticError: Underflow, Overflow // - https://github.com/paritytech/polkadot-sdk/blob/master/substrate/frame/assets/src/functions.rs#L125 -// - #[test] #[ignore] fn transfer_works() { @@ -427,35 +423,46 @@ fn transfer_works() { ); let amount: Balance = 100 * UNIT; + // Asset does not exist. assert_eq!( - decoded::(transfer(addr.clone(), 1, BOB, amount,)), - FungiblesError::Unknown + decoded::(transfer(addr.clone(), 1, BOB, amount,)), + UseCaseError(Unknown) ); - let asset = create_asset_and_mint_to(1, ALICE, addr.clone(), amount); + // Create asset with Alice as owner and mint `amount` to contract address. + let asset = create_asset_and_mint_to(ALICE, 1, addr.clone(), amount); + // Asset is not live, i.e. frozen or being destroyed. freeze_asset(asset, ALICE); assert_eq!( - decoded::(transfer(addr.clone(), asset, BOB, amount,)), - FungiblesError::AssetNotLive + decoded::(transfer(addr.clone(), asset, BOB, amount,)), + UseCaseError(AssetNotLive) ); thaw_asset(asset, ALICE); + // Not enough balance. assert_eq!( - decoded::(transfer(addr.clone(), asset, BOB, amount + 1 * UNIT)), - FungiblesError::InsufficientBalance + decoded::(transfer(addr.clone(), asset, BOB, amount + 1 * UNIT)), + UseCaseError(InsufficientBalance) ); - // Errors due to ED. Could be Belowminimum + // Not enough balance due to ED. assert_eq!( - decoded::(transfer(addr.clone(), asset, BOB, amount)), - FungiblesError::InsufficientBalance + decoded::(transfer(addr.clone(), asset, BOB, amount)), + UseCaseError(InsufficientBalance) ); + // Successful transfer. let bob_balance_before_mint = Assets::balance(asset, &BOB); let result = transfer(addr.clone(), asset, BOB, amount / 2); assert!(!result.did_revert(), "Contract reverted!"); let bob_balance_after_mint = Assets::balance(asset, &BOB); assert_eq!(bob_balance_after_mint, bob_balance_before_mint + amount / 2); + // Transfer asset to account that does not exist. + assert_eq!( + decoded::(transfer(addr.clone(), asset, FERDIE, amount / 4)), + Token(CannotCreate) + ); + // Asset is not live, i.e. frozen or being destroyed. start_destroy_asset(asset, ALICE); assert_eq!( - decoded::(transfer(addr.clone(), asset, BOB, amount / 4)), - FungiblesError::AssetNotLive + decoded::(transfer(addr.clone(), asset, BOB, amount / 4)), + UseCaseError(AssetNotLive) ); }); } diff --git a/runtime/devnet/src/tests/mod.rs b/runtime/devnet/src/tests/mod.rs new file mode 100644 index 00000000..c13030a3 --- /dev/null +++ b/runtime/devnet/src/tests/mod.rs @@ -0,0 +1,262 @@ +#![cfg(test)] + +use crate::{ + config::assets::TrustBackedAssetsInstance, Assets, Contracts, Runtime, RuntimeOrigin, System, + Weight, UNIT, +}; +use codec::{Decode, Encode}; +use frame_support::traits::fungibles::{approvals::Inspect as ApprovalInspect, Inspect}; +use frame_system::Config; +use pallet_contracts::{Code, CollectEvents, Determinism, ExecReturnValue}; +use pop_api::error::{ArithmeticError, PopApiError, TokenError, TransactionalError}; +use sp_runtime::{traits::Hash, AccountId32, BuildStorage, DispatchError}; + +mod local_fungibles; + +type Balance = u128; +type AssetId = u32; +const DEBUG_OUTPUT: pallet_contracts::DebugInfo = pallet_contracts::DebugInfo::UnsafeDebug; + +const ALICE: AccountId32 = AccountId32::new([1_u8; 32]); +const BOB: AccountId32 = AccountId32::new([2_u8; 32]); +// FERDIE has no initial balance. +const FERDIE: AccountId32 = AccountId32::new([3_u8; 32]); +const INIT_AMOUNT: Balance = 100_000_000 * UNIT; +const INIT_VALUE: Balance = 100 * UNIT; +const GAS_LIMIT: Weight = Weight::from_parts(100_000_000_000, 3 * 1024 * 1024); + +fn new_test_ext() -> sp_io::TestExternalities { + let mut t = frame_system::GenesisConfig::::default() + .build_storage() + .expect("Frame system builds valid default genesis config"); + + pallet_balances::GenesisConfig:: { + balances: vec![(ALICE, INIT_AMOUNT), (BOB, INIT_AMOUNT)], + } + .assimilate_storage(&mut t) + .expect("Pallet balances storage can be assimilated"); + + let mut ext = sp_io::TestExternalities::new(t); + ext.execute_with(|| System::set_block_number(1)); + ext +} + +fn load_wasm_module(path: &str) -> std::io::Result<(Vec, ::Output)> +where + T: frame_system::Config, +{ + let wasm_binary = std::fs::read(path)?; + let code_hash = T::Hashing::hash(&wasm_binary); + Ok((wasm_binary, code_hash)) +} + +fn function_selector(name: &str) -> Vec { + let hash = sp_io::hashing::blake2_256(name.as_bytes()); + [hash[0..4].to_vec()].concat() +} + +fn do_bare_call( + addr: AccountId32, + input: Vec, + value: u128, +) -> Result { + let result = Contracts::bare_call( + ALICE, + addr.into(), + value.into(), + GAS_LIMIT, + None, + input, + DEBUG_OUTPUT, + CollectEvents::Skip, + Determinism::Enforced, + ); + log::debug!("Contract debug buffer - {:?}", String::from_utf8(result.debug_message.clone())); + log::debug!("result: {:?}", result); + result.result +} + +// Deploy, instantiate and return contract address. +fn instantiate(contract: &str, init_value: u128, salt: Vec) -> AccountId32 { + let (wasm_binary, _) = + load_wasm_module::(contract).expect("could not read .wasm file"); + let result = Contracts::bare_instantiate( + ALICE, + init_value, + GAS_LIMIT, + None, + Code::Upload(wasm_binary), + function_selector("new"), + salt, + DEBUG_OUTPUT, + CollectEvents::Skip, + ) + .result + .unwrap(); + assert!(!result.result.did_revert(), "deploying contract reverted {:?}", result); + result.account_id +} + +pub fn get_pallet_index() -> u8 { + // Get the index of the pallet (module) + <::PalletInfo as frame_support::traits::PalletInfo>::index::() + .expect("Every active module has an index in the runtime; qed") as u8 +} + +#[test] +fn encoding_decoding_dispatch_error() { + use codec::{Decode, Encode}; + use sp_runtime::{ArithmeticError, DispatchError, ModuleError, TokenError}; + + new_test_ext().execute_with(|| { + let error = DispatchError::Module(ModuleError { + index: 255, + error: [2, 0, 0, 0], + message: Some("error message"), + }); + let encoded = error.encode(); + let decoded = DispatchError::decode(&mut &encoded[..]).unwrap(); + assert_eq!(encoded, vec![3, 255, 2, 0, 0, 0]); + assert_eq!( + decoded, + // `message` is skipped for encoding. + DispatchError::Module(ModuleError { index: 255, error: [2, 0, 0, 0], message: None }) + ); + println!("Encoded Module Error: {:?}", encoded); + + // Example pallet assets Error into ModuleError + let index = get_pallet_index::(); + let mut error = + pallet_assets::Error::NotFrozen::.encode(); + error.resize(sp_runtime::MAX_MODULE_ERROR_ENCODED_SIZE, 0); + let message = None; + let error = DispatchError::Module(ModuleError { + index, + error: TryInto::try_into(error).expect("should work"), + message, + }); + let encoded = error.encode(); + let decoded = DispatchError::decode(&mut &encoded[..]).unwrap(); + assert_eq!(encoded, vec![3, 52, 18, 0, 0, 0]); + assert_eq!( + decoded, + DispatchError::Module(ModuleError { index: 52, error: [18, 0, 0, 0], message: None }) + ); + println!("Encoded Module Error: {:?}", encoded); + + // Example DispatchError::Token + let error = DispatchError::Token(TokenError::UnknownAsset); + let encoded = error.encode(); + assert_eq!(encoded, vec![7, 4]); + println!("Encoded Token Error: {:?}", encoded); + + // Example DispatchError::Arithmetic + let error = DispatchError::Arithmetic(ArithmeticError::Overflow); + let encoded = error.encode(); + assert_eq!(encoded, vec![8, 1]); + println!("Encoded Arithmetic Error: {:?}", encoded); + }); +} + +#[test] +fn encoding_of_enum() { + use codec::{Decode, Encode}; + + // Comprehensive enum with all different type of variants. + #[derive(Debug, PartialEq, Encode, Decode)] + enum ComprehensiveEnum { + SimpleVariant, + DataVariant(u8), + NamedFields { w: u8 }, + NestedEnum(InnerEnum), + OptionVariant(Option), + VecVariant(Vec), + TupleVariant(u8, u8), + NestedStructVariant(NestedStruct), + NestedEnumStructVariant(NestedEnumStruct), + } + + #[derive(Debug, PartialEq, Encode, Decode)] + enum InnerEnum { + A, + B { inner_data: u8 }, + C(u8), + } + + #[derive(Debug, PartialEq, Encode, Decode)] + struct NestedStruct { + x: u8, + y: u8, + } + + #[derive(Debug, PartialEq, Encode, Decode)] + struct NestedEnumStruct { + inner_enum: InnerEnum, + } + + // Creating each possible variant for an enum. + let enum_simple = ComprehensiveEnum::SimpleVariant; + let enum_data = ComprehensiveEnum::DataVariant(42); + let enum_named = ComprehensiveEnum::NamedFields { w: 42 }; + let enum_nested = ComprehensiveEnum::NestedEnum(InnerEnum::B { inner_data: 42 }); + let enum_option = ComprehensiveEnum::OptionVariant(Some(42)); + let enum_vec = ComprehensiveEnum::VecVariant(vec![1, 2, 3, 4, 5]); + let enum_tuple = ComprehensiveEnum::TupleVariant(42, 42); + let enum_nested_struct = ComprehensiveEnum::NestedStructVariant(NestedStruct { x: 42, y: 42 }); + let enum_nested_enum_struct = ComprehensiveEnum::NestedEnumStructVariant(NestedEnumStruct { + inner_enum: InnerEnum::C(42), + }); + + // Encode and print each variant individually to see their encoded values. + println!("{:?} -> {:?}", enum_simple, enum_simple.encode()); + println!("{:?} -> {:?}", enum_data, enum_data.encode()); + println!("{:?} -> {:?}", enum_named, enum_named.encode()); + println!("{:?} -> {:?}", enum_nested, enum_nested.encode()); + println!("{:?} -> {:?}", enum_option, enum_option.encode()); + println!("{:?} -> {:?}", enum_vec, enum_vec.encode()); + println!("{:?} -> {:?}", enum_tuple, enum_tuple.encode()); + println!("{:?} -> {:?}", enum_nested_struct, enum_nested_struct.encode()); + println!("{:?} -> {:?}", enum_nested_enum_struct, enum_nested_enum_struct.encode()); +} + +#[test] +fn dispatch_error_to_status_code_to_pop_api_error_works() { + // Create all the different `DispatchError` variants with its respective `PopApiError`. + let test_cases = vec![ + (DispatchError::CannotLookup, PopApiError::CannotLookup), + (DispatchError::BadOrigin, PopApiError::BadOrigin), + ( + DispatchError::Module(sp_runtime::ModuleError { + index: 1, + error: [2, 0, 0, 0], + message: Some("hallo"), + }), + PopApiError::Module { index: 1, error: 2 }, + ), + (DispatchError::ConsumerRemaining, PopApiError::ConsumerRemaining), + (DispatchError::NoProviders, PopApiError::NoProviders), + (DispatchError::TooManyConsumers, PopApiError::TooManyConsumers), + ( + DispatchError::Token(sp_runtime::TokenError::FundsUnavailable), + PopApiError::Token(TokenError::FundsUnavailable), + ), + ( + DispatchError::Arithmetic(sp_runtime::ArithmeticError::Overflow), + PopApiError::Arithmetic(ArithmeticError::Overflow), + ), + ( + DispatchError::Transactional(sp_runtime::TransactionalError::LimitReached), + PopApiError::Transactional(TransactionalError::LimitReached), + ), + (DispatchError::Exhausted, PopApiError::Exhausted), + (DispatchError::Corruption, PopApiError::Corruption), + (DispatchError::Unavailable, PopApiError::Unavailable), + (DispatchError::RootNotAllowed, PopApiError::RootNotAllowed), + ]; + for (error, pop_api_error) in test_cases { + // Show that the encoding and decoding of the PopApiError <> u32 (status code) works. + let status_code = crate::extensions::convert_to_status_code(error); + let error = pop_api::error::convert_to_pop_api_error(status_code); + assert_eq!(pop_api_error, error,); + } +} From f824801e092ac5a6224779bbf06f93ec3b04402b Mon Sep 17 00:00:00 2001 From: Daanvdplas Date: Thu, 20 Jun 2024 15:50:00 +0200 Subject: [PATCH 008/112] refactor: error handling --- pop-api/src/lib.rs | 2 +- pop-api/src/v0/assets/pallets/assets.rs | 3 ++- pop-api/src/v0/balances.rs | 3 ++- primitives/Cargo.toml | 5 ----- primitives/src/lib.rs | 7 +------ runtime/devnet/src/tests/local_fungibles.rs | 22 ++++++++------------- runtime/testnet/src/extensions.rs | 5 ++++- 7 files changed, 18 insertions(+), 29 deletions(-) diff --git a/pop-api/src/lib.rs b/pop-api/src/lib.rs index a785aebe..e78aff9e 100644 --- a/pop-api/src/lib.rs +++ b/pop-api/src/lib.rs @@ -13,7 +13,7 @@ pub mod primitives; pub mod v0; type AccountId = AccountId32; -// TODO: do the same as above and check expanded code. +// TODO: do the same as above and check expanded macro code. type Balance = ::Balance; type BlockNumber = ::BlockNumber; type StringLimit = u32; diff --git a/pop-api/src/v0/assets/pallets/assets.rs b/pop-api/src/v0/assets/pallets/assets.rs index 7a575e08..b28d3086 100644 --- a/pop-api/src/v0/assets/pallets/assets.rs +++ b/pop-api/src/v0/assets/pallets/assets.rs @@ -1,4 +1,3 @@ -// TODO: what to put in this file? #![allow(dead_code)] use crate::{Balance, RuntimeCall, *}; @@ -412,6 +411,8 @@ pub(crate) enum AssetsCall { Block { id: AssetIdParameter, who: MultiAddress }, } +// TODO: do we want add this. Not being used atm but necessary if we want to provide access to the +// rest of the pallet. #[derive(Debug, Copy, Clone, PartialEq, Eq, Encode, scale::Decode)] #[cfg_attr(feature = "std", derive(scale_info::TypeInfo))] pub enum AssetsError { diff --git a/pop-api/src/v0/balances.rs b/pop-api/src/v0/balances.rs index 5d38d851..c9759a45 100644 --- a/pop-api/src/v0/balances.rs +++ b/pop-api/src/v0/balances.rs @@ -1,4 +1,3 @@ -// TODO: what to put in this file? use crate::{dispatch, error::PopApiError, primitives::MultiAddress, v0::RuntimeCall, AccountId}; type Result = core::result::Result; @@ -24,6 +23,8 @@ pub enum BalancesCall { }, } +// TODO: do we want add this. Not being used atm but necessary if we want to provide access to the +// rest of the pallet. #[derive(Debug, Copy, Clone, PartialEq, Eq, scale::Encode, scale::Decode)] #[cfg_attr(feature = "std", derive(scale_info::TypeInfo))] pub enum BalancesError { diff --git a/primitives/Cargo.toml b/primitives/Cargo.toml index 1098b557..e7237b51 100644 --- a/primitives/Cargo.toml +++ b/primitives/Cargo.toml @@ -12,11 +12,6 @@ scale-decode = { version = "0.10.0", default-features = false, features = ["deri scale-encode = { version = "0.5.0", default-features = false, features = ["derive"], optional = true } scale-info = { version = "2.6", default-features = false, features = ["derive"], optional = true } -#scale = { workspace = true, features = ["max-encoded-len"] } -#scale-decode = { workspace = true, features = ["derive"], optional = true } -#scale-encode = { workspace = true, features = ["derive"], optional = true } -#scale-info = { workspace = true, features = ["derive"], optional = true } - [features] default = ["std"] std = [ diff --git a/primitives/src/lib.rs b/primitives/src/lib.rs index 7c1672b8..1e008c31 100644 --- a/primitives/src/lib.rs +++ b/primitives/src/lib.rs @@ -3,12 +3,7 @@ pub use bounded_collections::{BoundedBTreeMap, BoundedBTreeSet, BoundedVec, ConstU32}; use scale::{Decode, Encode, MaxEncodedLen}; #[cfg(feature = "std")] -use { - scale_decode::DecodeAsType, - scale_encode::EncodeAsType, - scale_info::TypeInfo, -}; - +use {scale_decode::DecodeAsType, scale_encode::EncodeAsType, scale_info::TypeInfo}; pub mod cross_chain; pub mod storage_keys; diff --git a/runtime/devnet/src/tests/local_fungibles.rs b/runtime/devnet/src/tests/local_fungibles.rs index bc13fbde..b1ddda2e 100644 --- a/runtime/devnet/src/tests/local_fungibles.rs +++ b/runtime/devnet/src/tests/local_fungibles.rs @@ -1,3 +1,11 @@ +// Todo - errors: +// - Badorigin: contract is always signed +// - Lookup: is a valid AccountId due to the contract +// - Many errors can occur from calling a dispatchable. As of now, most of the DispatchErrors are +// handled by the pop api but not all of them are tested. How should I approach this? I.e.: +// - Arithmetic errors +// - Token errors +// - others (besides Module errors) that I might haven't found yet. #![cfg(test)] use super::*; @@ -251,16 +259,6 @@ fn asset_exists_works() { }); } -// Todo - errors: -// - Badorigin: contract is always signed -// - Lookup: is a valid AccountId due to the contract -// - reserve(): Overflow, LiquidityRestrictions; frozen -// - Callback -// - StorageDepositLimitExhausted -// todo: errors: -// - TokenErrors -// - Arithmetic -// - https://github.com/paritytech/polkadot-sdk/blob/3977f389cce4a00fd7100f95262e0563622b9aa4/substrate/frame/assets/src/functions.rs#L125 #[test] #[ignore] fn create_works() { @@ -407,10 +405,6 @@ fn transfer_from_mint_works() { }); } -// Todo: error: -// - https://github.com/paritytech/polkadot-sdk/blob/2460cddf57660a88844d201f769eb17a7accce5a/substrate/frame/assets/src/functions.rs#L161 -// - ArithmeticError: Underflow, Overflow -// - https://github.com/paritytech/polkadot-sdk/blob/master/substrate/frame/assets/src/functions.rs#L125 #[test] #[ignore] fn transfer_works() { diff --git a/runtime/testnet/src/extensions.rs b/runtime/testnet/src/extensions.rs index 6bbfaa36..4e7402a7 100644 --- a/runtime/testnet/src/extensions.rs +++ b/runtime/testnet/src/extensions.rs @@ -86,6 +86,7 @@ impl TryFrom for v0::FuncId { 0x1 => Self::ReadState, _ => { log::error!("called an unregistered `func_id`: {:}", func_id); + // TODO: Other error. return Err(DispatchError::Other("unimplemented func_id")); }, }; @@ -206,6 +207,7 @@ where RuntimeStateKeys::ParachainSystem(key) => { read_parachain_system_state::(key, &mut env) }, + _ => Err(DispatchError::Other("Unknown state keys")), }? .encode(); @@ -215,7 +217,8 @@ where ); env.write(&result, false, None).map_err(|e| { log::trace!(target: LOG_TARGET, "{:?}", e); - DispatchError::Other("unable to write results to contract memory") + // TODO: Other error. + DispatchError::Other("Unable to write results to contract memory") }) } From 467050307884c6692bcbbbfa6b704f0c42f4ab16 Mon Sep 17 00:00:00 2001 From: Daanvdplas Date: Thu, 20 Jun 2024 18:49:18 +0200 Subject: [PATCH 009/112] refactor: clarify todos --- pop-api/src/lib.rs | 2 +- pop-api/src/v0/assets/pallets/assets.rs | 4 ++-- pop-api/src/v0/balances.rs | 4 ++-- runtime/devnet/src/extensions.rs | 2 ++ runtime/devnet/src/tests/local_fungibles.rs | 8 +++----- runtime/testnet/src/extensions.rs | 1 + 6 files changed, 11 insertions(+), 10 deletions(-) diff --git a/pop-api/src/lib.rs b/pop-api/src/lib.rs index e78aff9e..d00f1e9a 100644 --- a/pop-api/src/lib.rs +++ b/pop-api/src/lib.rs @@ -13,7 +13,7 @@ pub mod primitives; pub mod v0; type AccountId = AccountId32; -// TODO: do the same as above and check expanded macro code. +// TODO: do the same as the AccountId above and check expanded macro code. type Balance = ::Balance; type BlockNumber = ::BlockNumber; type StringLimit = u32; diff --git a/pop-api/src/v0/assets/pallets/assets.rs b/pop-api/src/v0/assets/pallets/assets.rs index b28d3086..87695b81 100644 --- a/pop-api/src/v0/assets/pallets/assets.rs +++ b/pop-api/src/v0/assets/pallets/assets.rs @@ -411,8 +411,8 @@ pub(crate) enum AssetsCall { Block { id: AssetIdParameter, who: MultiAddress }, } -// TODO: do we want add this. Not being used atm but necessary if we want to provide access to the -// rest of the pallet. +// TODO: Not being used atm but necessary if we want to provide access to the +// rest of the pallet, outside of the use cases. #[derive(Debug, Copy, Clone, PartialEq, Eq, Encode, scale::Decode)] #[cfg_attr(feature = "std", derive(scale_info::TypeInfo))] pub enum AssetsError { diff --git a/pop-api/src/v0/balances.rs b/pop-api/src/v0/balances.rs index c9759a45..56c3ca72 100644 --- a/pop-api/src/v0/balances.rs +++ b/pop-api/src/v0/balances.rs @@ -23,8 +23,8 @@ pub enum BalancesCall { }, } -// TODO: do we want add this. Not being used atm but necessary if we want to provide access to the -// rest of the pallet. +// TODO: Not being used atm but necessary if we want to provide access to the +// rest of the pallet, outside of the use cases. #[derive(Debug, Copy, Clone, PartialEq, Eq, scale::Encode, scale::Decode)] #[cfg_attr(feature = "std", derive(scale_info::TypeInfo))] pub enum BalancesError { diff --git a/runtime/devnet/src/extensions.rs b/runtime/devnet/src/extensions.rs index 014893f9..32667d16 100644 --- a/runtime/devnet/src/extensions.rs +++ b/runtime/devnet/src/extensions.rs @@ -103,6 +103,7 @@ impl TryFrom for v0::FuncId { 0x2 => Self::SendXcm, _ => { log::error!("called an unregistered `func_id`: {:}", func_id); + // TODO: Other error. return Err(DispatchError::Other("unimplemented func_id")); }, }; @@ -236,6 +237,7 @@ where ); env.write(&result, false, None).map_err(|e| { log::trace!(target: LOG_TARGET, "{:?}", e); + // TODO: Other error. DispatchError::Other("unable to write results to contract memory") }) } diff --git a/runtime/devnet/src/tests/local_fungibles.rs b/runtime/devnet/src/tests/local_fungibles.rs index b1ddda2e..9f208b15 100644 --- a/runtime/devnet/src/tests/local_fungibles.rs +++ b/runtime/devnet/src/tests/local_fungibles.rs @@ -1,11 +1,9 @@ // Todo - errors: // - Badorigin: contract is always signed // - Lookup: is a valid AccountId due to the contract -// - Many errors can occur from calling a dispatchable. As of now, most of the DispatchErrors are -// handled by the pop api but not all of them are tested. How should I approach this? I.e.: -// - Arithmetic errors -// - Token errors -// - others (besides Module errors) that I might haven't found yet. +// - Many errors can occur from calling a dispatchable. All the DispatchErrors are handled by the +// pop api but not all the possible errors for each dipatchable are tested. How should I approach +// this? #![cfg(test)] use super::*; diff --git a/runtime/testnet/src/extensions.rs b/runtime/testnet/src/extensions.rs index 4e7402a7..a3284ad4 100644 --- a/runtime/testnet/src/extensions.rs +++ b/runtime/testnet/src/extensions.rs @@ -207,6 +207,7 @@ where RuntimeStateKeys::ParachainSystem(key) => { read_parachain_system_state::(key, &mut env) }, + // TODO: devnet / testnet feature. _ => Err(DispatchError::Other("Unknown state keys")), }? .encode(); From 2283161fdf9334697cbc84b9437767b189b9ce06 Mon Sep 17 00:00:00 2001 From: Daanvdplas Date: Mon, 24 Jun 2024 17:38:28 +0200 Subject: [PATCH 010/112] refactor: error handling comments part 1 --- pop-api/Cargo.toml | 4 + pop-api/examples/fungibles/Cargo.toml | 2 +- pop-api/examples/fungibles/lib.rs | 25 +- pop-api/src/error.rs | 341 +++++++----- pop-api/src/lib.rs | 27 +- .../v0/assets/{use_cases => }/fungibles.rs | 74 ++- pop-api/src/v0/assets/mod.rs | 496 +++++++++++++++++- pop-api/src/v0/assets/pallets/assets.rs | 492 ----------------- pop-api/src/v0/assets/pallets/mod.rs | 1 - pop-api/src/v0/assets/use_cases/mod.rs | 1 - pop-api/src/v0/balances.rs | 6 +- pop-api/src/v0/cross_chain/mod.rs | 13 +- pop-api/src/v0/mod.rs | 26 +- pop-api/src/v0/nfts.rs | 8 +- pop-api/src/v0/state.rs | 3 +- runtime/devnet/Cargo.toml | 2 +- runtime/devnet/src/extensions.rs | 13 +- runtime/devnet/src/tests/local_fungibles.rs | 24 +- runtime/devnet/src/tests/mod.rs | 4 +- 19 files changed, 816 insertions(+), 746 deletions(-) rename pop-api/src/v0/assets/{use_cases => }/fungibles.rs (86%) delete mode 100644 pop-api/src/v0/assets/pallets/assets.rs delete mode 100644 pop-api/src/v0/assets/pallets/mod.rs delete mode 100644 pop-api/src/v0/assets/use_cases/mod.rs diff --git a/pop-api/Cargo.toml b/pop-api/Cargo.toml index 80818235..b80cb3b0 100644 --- a/pop-api/Cargo.toml +++ b/pop-api/Cargo.toml @@ -31,3 +31,7 @@ std = [ "sp-io/std", "sp-runtime/std", ] +assets = [] +balances = [] +nfts = [] +cross-chain = [] diff --git a/pop-api/examples/fungibles/Cargo.toml b/pop-api/examples/fungibles/Cargo.toml index 1fe32d6d..514f000f 100755 --- a/pop-api/examples/fungibles/Cargo.toml +++ b/pop-api/examples/fungibles/Cargo.toml @@ -6,7 +6,7 @@ edition = "2021" [dependencies] ink = { version = "5.0.0", default-features = false } -pop-api = { path = "../../../pop-api", default-features = false } +pop-api = { path = "../../../pop-api", default-features = false, features = ["assets"] } scale = { package = "parity-scale-codec", version = "3", default-features = false, features = ["derive"] } scale-info = { version = "2.6", default-features = false, features = ["derive"], optional = true } diff --git a/pop-api/examples/fungibles/lib.rs b/pop-api/examples/fungibles/lib.rs index 59040590..161c7fdd 100755 --- a/pop-api/examples/fungibles/lib.rs +++ b/pop-api/examples/fungibles/lib.rs @@ -7,12 +7,12 @@ /// use ink::prelude::vec::Vec; use pop_api::{ - assets::use_cases::fungibles as api, - error::PopApiError, + assets::fungibles::{self as api, FungiblesError}, + error::{PopApiError, StatusCode}, primitives::{AccountId as AccountId32, AssetId}, }; -pub type Result = core::result::Result; +pub type Result = core::result::Result; #[ink::contract(env = pop_api::Environment)] mod fungibles { @@ -41,12 +41,12 @@ mod fungibles { #[ink(message)] pub fn total_supply(&self, id: AssetId) -> Result { - api::total_supply(id) + api::total_supply(id).map_err(|e| e.into()) } #[ink(message)] pub fn balance_of(&self, id: AssetId, owner: AccountId32) -> Result { - api::balance_of(id, owner) + api::balance_of(id, owner).map_err(|e| e.into()) } #[ink(message)] @@ -56,7 +56,7 @@ mod fungibles { owner: AccountId32, spender: AccountId32, ) -> Result { - api::allowance(id, owner, spender) + api::allowance(id, owner, spender).map_err(|e| e.into()) } #[ink(message)] @@ -68,7 +68,7 @@ mod fungibles { value, ); - let result = api::transfer(id, to, value); + let result = api::transfer(id, to, value).map_err(|e| e.into()); ink::env::debug_println!("Result: {:?}", result); result } @@ -80,8 +80,7 @@ mod fungibles { from: Option, to: Option, value: Balance, - // In the standard a `[u8]`, but the size needs to be known at compile time ink's `Vec` - // has to be used. + // In the standard a `[u8]`, but the size needs to be known at compile time. data: Vec, ) -> Result<()> { ink::env::debug_println!( @@ -92,7 +91,7 @@ mod fungibles { value, ); - let result = api::transfer_from(id, from, to, value, &data); + let result = api::transfer_from(id, from, to, value, &data).map_err(|e| e.into()); ink::env::debug_println!("Result: {:?}", result); result } @@ -119,7 +118,7 @@ mod fungibles { admin, min_balance, ); - let result = api::create(id, admin, min_balance); + let result = api::create(id, admin, min_balance).map_err(|e| e.into()); ink::env::debug_println!("Result: {:?}", result); result } @@ -139,14 +138,14 @@ mod fungibles { symbol, decimals, ); - let result = api::set_metadata(id, name, symbol, decimals); + let result = api::set_metadata(id, name, symbol, decimals).map_err(|e| e.into()); ink::env::debug_println!("Result: {:?}", result); result } #[ink(message)] pub fn asset_exists(&self, id: AssetId) -> Result { - api::asset_exists(id) + api::asset_exists(id).map_err(|e| e.into()) } } diff --git a/pop-api/src/error.rs b/pop-api/src/error.rs index 92da4045..4d5a8fb9 100644 --- a/pop-api/src/error.rs +++ b/pop-api/src/error.rs @@ -1,8 +1,35 @@ -use crate::assets::use_cases::fungibles::{convert_to_fungibles_error, FungiblesError}; use ink::env::chain_extension::FromStatusCode; use scale::{Decode, Encode}; use PopApiError::*; +#[derive(Debug, Copy, Clone, PartialEq, Eq, Encode, Decode)] +#[cfg_attr(feature = "std", derive(scale_info::TypeInfo))] +pub struct StatusCode(pub u32); + +impl From for StatusCode { + fn from(value: u32) -> Self { + StatusCode(value) + } +} +impl FromStatusCode for StatusCode { + fn from_status_code(status_code: u32) -> Result<(), Self> { + match status_code { + 0 => Ok(()), + _ => { + let mut encoded = status_code.to_le_bytes(); + convert_unknown_errors(&mut encoded); + Err(StatusCode::from(u32::from_le_bytes(encoded))) + }, + } + } +} + +impl From for StatusCode { + fn from(_: scale::Error) -> Self { + DecodingFailed.into() + } +} + #[derive(Debug, Copy, Clone, PartialEq, Eq, Encode, Decode)] #[cfg_attr(feature = "std", derive(scale_info::TypeInfo))] #[repr(u8)] @@ -46,79 +73,87 @@ pub enum PopApiError { Unavailable = 12, /// Root origin is not allowed. RootNotAllowed = 13, - // TODO: make generic and add docs. - UseCaseError(FungiblesError) = 254, DecodingFailed = 255, } -impl FromStatusCode for PopApiError { - fn from_status_code(status_code: u32) -> core::result::Result<(), Self> { - match status_code { - 0 => Ok(()), - _ => Err(convert_to_pop_api_error(status_code)), - } +impl From for StatusCode { + fn from(value: PopApiError) -> Self { + let mut encoded_error = value.encode(); + // Resize the encoded value to 4 bytes in order to decode the value in a u32 (4 bytes). + encoded_error.resize(4, 0); + StatusCode::from( + u32::decode(&mut &encoded_error[..]).expect("qid, resized to 4 bytes line above"), + ) } } -// `pub` because it is used in `runtime/devnet/src/extensions/tests/mod.rs`'s test: -// `dispatch_error_to_status_code_to_pop_api_error_works` -// -// This function converts a given `status_code` (u32) into a `PopApiError`. First it encodes the -// status code into a 4-byte array and checks for unknown nested errors. If decoding into -// `PopApiError` fails (e.g. a breaking change in the `DispatchError`), it handles the error by -// converting it to the `Other` variant by shifting each byte one position forward (the last byte is -// not used for anything)and setting the first byte to 0. If decoding succeeds, it checks if the -// error is of the `Module` variant and performs any necessary conversion based on the use case. -pub fn convert_to_pop_api_error(status_code: u32) -> PopApiError { - let mut encoded: [u8; 4] = - status_code.encode().try_into().expect("qid u32 always encodes to 4 bytes"); - encoded = check_for_unknown_nesting(encoded); - let error = match PopApiError::decode(&mut &encoded[..]) { - Err(_) => { - encoded[3] = encoded[2]; - encoded[2] = encoded[1]; - encoded[1] = encoded[0]; - encoded[0] = 0; - PopApiError::decode(&mut &encoded[..]).unwrap().into() - }, - Ok(error) => { - if let crate::PopApiError::Module { index, error } = error { - // TODO: make generic. - convert_to_fungibles_error(index, error) - } else { - error - } - }, - }; - ink::env::debug_println!("PopApiError: {:?}", error); - error +impl From for PopApiError { + // `pub` because it is used in `runtime/devnet/src/extensions/tests/mod.rs`'s test: + // `dispatch_error_to_status_code_to_pop_api_error_works` + // + // This function converts a given `status_code` (u32) into a `PopApiError`. + fn from(value: StatusCode) -> Self { + let encoded: [u8; 4] = value.0.to_le_bytes(); + PopApiError::decode(&mut &encoded[..]).unwrap_or(DecodingFailed) + } } -// If a unknown nested variant of the `DispatchError` is detected meaning any of the subsequent -// bytes are non-zero (e.g. breaking change in the DispatchError), the error needs to be converted -// into `PopApiError::Other`'s encoded value. This conversion is done by shifting the bytes one -// position forward (the last byte is discarded as it is not being used) and replacing the first -// byte with the `Other` encoded value (0u8). This ensures that the error is correctly categorized -// as an `Other` variant. -fn check_for_unknown_nesting(encoded_error: [u8; 4]) -> [u8; 4] { - if non_nested_pop_api_errors().contains(&encoded_error[0]) - && encoded_error[1..].iter().any(|x| *x != 0u8) - { - [0u8, encoded_error[0], encoded_error[1], encoded_error[2]] - } else if singular_nested_pop_api_errors().contains(&encoded_error[0]) +// If an unknown nested variant of the `DispatchError` is detected (i.e., any of the subsequent +// bytes are non-zero, indicating a breaking change in the `DispatchError`), the error needs to be +// converted into the encoded value of `PopApiError::Other`. This conversion is performed by +// shifting the bytes one position forward (discarding the last byte as it is not used) and setting +// the first byte to the encoded value of `Other` (0u8). This ensures the error is correctly +// categorized as an `Other` variant. +// +// Byte layout explanation: +// - Byte 0: PopApiError +// - Byte 1: +// - Must be zero for `UNIT_ERRORS`. +// - Represents the nested error in `SINGLE_NESTED_ERRORS`. +// - Represents the first level of nesting in `DOUBLE_NESTED_ERRORS`. +// - Byte 2: +// - Represents the second level of nesting in `DOUBLE_NESTED_ERRORS`. +// - Byte 3: +// - Unused or represents further nested information. +// +// This mechanism ensures backward compatibility by correctly categorizing any unknown nested errors +// into the `Other` variant, thus preventing issues caused by new or unexpected error formats. +pub(crate) fn convert_unknown_nested_errors(encoded_error: &mut [u8; 4]) { + // Converts single nested errors that are known to the Pop API as unit errors into `Other`. + if UNIT_ERRORS.contains(&encoded_error[0]) && encoded_error[1..].iter().any(|x| *x != 0u8) { + encoded_error[..].rotate_right(1); + encoded_error[0] = 0u8; + // Converts double nested errors that are known to the Pop API as single nested errors into + // `Other`. + } else if SINGLE_NESTED_ERRORS.contains(&encoded_error[0]) && encoded_error[2..].iter().any(|x| *x != 0u8) { - [0u8, encoded_error[0], encoded_error[1], encoded_error[2]] - } else { - encoded_error + encoded_error[..].rotate_right(1); + encoded_error[0] = 0u8; + } else if DOUBLE_NESTED_ERRORS.contains(&encoded_error[0]) + && encoded_error[3..].iter().any(|x| *x != 0u8) + { + encoded_error[..].rotate_right(1); + encoded_error[0] = 0u8; } } -impl From for PopApiError { - fn from(_: scale::Error) -> Self { - DecodingFailed +pub(crate) fn convert_unknown_errors(encoded_error: &mut [u8; 4]) { + let all_errors = [ + UNIT_ERRORS.as_slice(), + SINGLE_NESTED_ERRORS.as_slice(), + DOUBLE_NESTED_ERRORS.as_slice(), + // `DecodingFailed`. + &[255u8], + ] + .concat(); + if !all_errors.contains(&encoded_error[0]) { + encoded_error[..].rotate_right(1); + encoded_error[0] = 0u8; } + convert_unknown_nested_errors(encoded_error); } + #[derive(Debug, Copy, Clone, PartialEq, Eq, scale::Encode, scale::Decode)] #[cfg_attr(feature = "std", derive(scale_info::TypeInfo))] pub enum TokenError { @@ -165,91 +200,129 @@ pub enum TransactionalError { NoLayer, } -fn singular_nested_pop_api_errors() -> [u8; 3] { - const TOKEN_ERROR: u8 = 7; - const ARITHMETIC_ERROR: u8 = 8; - const TRANSACTION_ERROR: u8 = 9; - [TOKEN_ERROR, ARITHMETIC_ERROR, TRANSACTION_ERROR] -} +// Unit `DispatchError` variants (variant: index): +// - CannotLookup: 1, +// - BadOrigin: 2, +// - ConsumerRemaining: 4, +// - NoProviders: 5, +// - TooManyConsumers: 6, +// - Exhausted: 10, +// - Corruption: 11, +// - Unavailable: 12, +// - RootNotAllowed: 13, +const UNIT_ERRORS: [u8; 9] = [1, 2, 4, 5, 6, 10, 11, 12, 13]; -fn non_nested_pop_api_errors() -> [u8; 9] { - const CANNOT_LOOKUP: u8 = 1; - const BAD_ORIGIN: u8 = 2; - const CONSUMER_REMAINING: u8 = 4; - const NO_PROVIDERS: u8 = 5; - const TOO_MANY_CONSUMERS: u8 = 6; - const EXHAUSTED: u8 = 10; - const CORRUPTION: u8 = 11; - const UNAVAILABLE: u8 = 12; - const ROOT_NOT_ALLOWED: u8 = 13; - [ - CANNOT_LOOKUP, - BAD_ORIGIN, - CONSUMER_REMAINING, - NO_PROVIDERS, - TOO_MANY_CONSUMERS, - EXHAUSTED, - CORRUPTION, - UNAVAILABLE, - ROOT_NOT_ALLOWED, - ] -} +// Single nested `DispatchError` variants (variant: index): +// - Token: 3, +// - Arithmetic: 8, +// - Transaction: 9, +const SINGLE_NESTED_ERRORS: [u8; 3] = [7, 8, 9]; -#[test] -fn u32_always_encodes_to_4_bytes() { - assert_eq!(0u32.encode().len(), 4); - assert_eq!(u32::MAX.encode().len(), 4); -} +const DOUBLE_NESTED_ERRORS: [u8; 1] = [3]; -// If decoding failed the encoded value is converted to the `PopApiError::Other`. This handles -// unknown errors coming from the runtime. This could happen if a contract is not upgraded to the -// latest Pop API version. -#[test] -fn test_non_existing_pop_api_errors() { - let encoded_error = [7u8, 100u8, 0u8, 0u8]; - let status_code = u32::decode(&mut &encoded_error[..]).unwrap(); - let pop_api_error = ::from_status_code(status_code); - assert_eq!(Err(Other { dispatch_error_index: 7, error_index: 100, error: 0 }), pop_api_error); -} +#[cfg(test)] +mod tests { + use super::*; + use crate::error::{ArithmeticError::*, TokenError::*, TransactionalError::*}; + + #[test] + fn u32_always_encodes_to_4_bytes() { + assert_eq!(0u32.encode().len(), 4); + assert_eq!(u32::MAX.encode().len(), 4); + } -// If the encoded value indicates a nested PopApiError which is not handled by the Pop API version, -// the encoded value is converted into `PopApiError::Other`. -#[test] -fn check_for_unknown_nested_pop_api_errors_works() { - for &error_code in &non_nested_pop_api_errors() { - let encoded_error = [error_code, 1, 2, 3]; - let result = check_for_unknown_nesting(encoded_error); - let decoded = PopApiError::decode(&mut &result[..]).unwrap(); + // Decodes into `StatusCode(u32)` and converts it into the `PopApiError`. + fn into_pop_api_error(encoded_error: [u8; 4]) -> PopApiError { + let status_code = + StatusCode::from_status_code(u32::decode(&mut &encoded_error[..]).unwrap()) + .unwrap_err(); + status_code.into() + } + // Tests for the `From` implementation for `PopApiError`. + // + // If the encoded value indicates a nested `PopApiError` which is not handled by the Pop API + // version, the encoded value is converted into `PopApiError::Other`. + #[test] + fn test_unit_pop_api_error_variants() { + let errors = vec![ + CannotLookup, + BadOrigin, + ConsumerRemaining, + NoProviders, + TooManyConsumers, + Exhausted, + Corruption, + Unavailable, + RootNotAllowed, + ]; + for (i, &error_code) in UNIT_ERRORS.iter().enumerate() { + assert_eq!(into_pop_api_error([error_code, 0, 0, 0]), errors[i]); + assert_eq!( + into_pop_api_error([error_code, 1, 0, 0]), + Other { dispatch_error_index: error_code, error_index: 1, error: 0 }, + ); + assert_eq!( + into_pop_api_error([error_code, 1, 1, 0]), + Other { dispatch_error_index: error_code, error_index: 1, error: 1 }, + ); + assert_eq!( + into_pop_api_error([error_code, 1, 1, 1]), + Other { dispatch_error_index: error_code, error_index: 1, error: 1 }, + ); + } + } + + #[test] + fn test_single_nested_pop_api_error_variants() { + let errors = vec![ + [Token(FundsUnavailable), Token(OnlyProvider)], + [Arithmetic(Underflow), Arithmetic(Overflow)], + [Transactional(LimitReached), Transactional(NoLayer)], + ]; + for (i, &error_code) in SINGLE_NESTED_ERRORS.iter().enumerate() { + assert_eq!(into_pop_api_error([error_code, 0, 0, 0]), errors[i][0]); + assert_eq!(into_pop_api_error([error_code, 1, 0, 0]), errors[i][1]); + assert_eq!( + into_pop_api_error([error_code, 1, 1, 0]), + Other { dispatch_error_index: error_code, error_index: 1, error: 1 }, + ); + assert_eq!( + into_pop_api_error([error_code, 1, 1, 1]), + Other { dispatch_error_index: error_code, error_index: 1, error: 1 }, + ); + } + } + + #[test] + fn test_double_nested_pop_api_error_variants() { + assert_eq!(into_pop_api_error([3, 0, 0, 0]), Module { index: 0, error: 0 }); + assert_eq!(into_pop_api_error([3, 1, 0, 0]), Module { index: 1, error: 0 }); + assert_eq!(into_pop_api_error([3, 1, 1, 0]), Module { index: 1, error: 1 }); + // TODO: doesn't make sense. assert_eq!( - decoded, - Other { dispatch_error_index: error_code, error_index: 1, error: 2 }, - "Failed for error code: {}", - error_code + into_pop_api_error([3, 1, 1, 1]), + Other { dispatch_error_index: 3, error_index: 1, error: 1 }, ); } - for &error_code in &singular_nested_pop_api_errors() { - let encoded_error = [error_code, 1, 2, 3]; - let result = check_for_unknown_nesting(encoded_error); - let decoded = PopApiError::decode(&mut &result[..]).unwrap(); + #[test] + fn test_decoding_failed() { + assert_eq!(into_pop_api_error([255, 0, 0, 0]), DecodingFailed); + assert_eq!(into_pop_api_error([255, 255, 0, 0]), DecodingFailed); + assert_eq!(into_pop_api_error([255, 255, 255, 0]), DecodingFailed); + assert_eq!(into_pop_api_error([255, 255, 255, 255]), DecodingFailed); + } + + #[test] + fn test_random_encoded_values() { + assert_eq!( + into_pop_api_error([100, 100, 100, 100]), + Other { dispatch_error_index: 100, error_index: 100, error: 100 } + ); assert_eq!( - decoded, - Other { dispatch_error_index: error_code, error_index: 1, error: 2 }, - "Failed for error code: {}", - error_code + into_pop_api_error([200, 200, 200, 200]), + Other { dispatch_error_index: 200, error_index: 200, error: 200 } ); } } - -// This test ensures that a non-zero value for unused bytes does not interfere with the correct -// decoding of the error. It verifies that even with an additional byte, the errors are correctly -// decoded and represented in its correct variant. -#[test] -fn extra_byte_does_not_mess_up_decoding() { - // Module error - let encoded_error = [3u8, 4u8, 5u8, 6u8]; - let status_code = u32::decode(&mut &encoded_error[..]).unwrap(); - let pop_api_error = ::from_status_code(status_code); - assert_eq!(Err(Module { index: 4, error: 5 }), pop_api_error); -} diff --git a/pop-api/src/lib.rs b/pop-api/src/lib.rs index d00f1e9a..90c81998 100644 --- a/pop-api/src/lib.rs +++ b/pop-api/src/lib.rs @@ -1,12 +1,19 @@ #![cfg_attr(not(feature = "std"), no_std, no_main)] -use crate::error::PopApiError; use ink::{prelude::vec::Vec, ChainExtensionInstance}; -use primitives::{cross_chain::*, storage_keys::*, AccountId as AccountId32}; -use scale::Encode; pub use sp_runtime::{BoundedVec, MultiAddress, MultiSignature}; -use v0::RuntimeCall; -pub use v0::{assets, balances, cross_chain, nfts, relay_chain_block_number, state}; + +use crate::error::{PopApiError, StatusCode}; +use primitives::{storage_keys::*, AccountId as AccountId32}; +#[cfg(feature = "assets")] +pub use v0::assets; +#[cfg(feature = "balances")] +pub use v0::balances; +#[cfg(feature = "cross-chain")] +pub use v0::cross_chain; +#[cfg(feature = "nfts")] +pub use v0::nfts; +use v0::{state, RuntimeCall}; pub mod error; pub mod primitives; @@ -15,11 +22,7 @@ pub mod v0; type AccountId = AccountId32; // TODO: do the same as the AccountId above and check expanded macro code. type Balance = ::Balance; -type BlockNumber = ::BlockNumber; -type StringLimit = u32; -type MaxTips = u32; - -pub type Result = core::result::Result; +pub type Result = core::result::Result; #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "std", derive(scale_info::TypeInfo))] @@ -40,7 +43,7 @@ impl ink::env::Environment for Environment { #[ink::chain_extension(extension = 909)] pub trait PopApi { - type ErrorCode = PopApiError; + type ErrorCode = StatusCode; #[ink(function = 0)] #[allow(private_interfaces)] @@ -50,6 +53,7 @@ pub trait PopApi { #[allow(private_interfaces)] fn read_state(key: RuntimeStateKeys) -> Result>; + #[cfg(feature = "cross-chain")] #[ink(function = 2)] #[allow(private_interfaces)] fn send_xcm(xcm: CrossChainMessage) -> Result<()>; @@ -67,6 +71,7 @@ fn read_state(key: RuntimeStateKeys) -> Result> { .read_state(key) } +#[cfg(feature = "cross-chain")] fn send_xcm(xcm: CrossChainMessage) -> Result<()> { <::ChainExtension as ChainExtensionInstance>::instantiate( ) diff --git a/pop-api/src/v0/assets/use_cases/fungibles.rs b/pop-api/src/v0/assets/fungibles.rs similarity index 86% rename from pop-api/src/v0/assets/use_cases/fungibles.rs rename to pop-api/src/v0/assets/fungibles.rs index 4af5d97e..b1bb86a7 100644 --- a/pop-api/src/v0/assets/use_cases/fungibles.rs +++ b/pop-api/src/v0/assets/fungibles.rs @@ -1,12 +1,8 @@ -use crate::{ - assets::pallets, - error::PopApiError::{self, *}, - AccountId, Balance, *, -}; +use crate::{assets, primitives::AssetId, AccountId, Balance, MultiAddress, StatusCode}; use ink::prelude::vec::Vec; -use primitives::AssetId; +use scale::Encode; -type Result = core::result::Result; +type Result = core::result::Result; /// Local Fungibles: /// 1. PSP-22 Interface @@ -31,7 +27,7 @@ type Result = core::result::Result; /// # Returns /// The total supply of the token, or an error if the operation fails. pub fn total_supply(id: AssetId) -> Result { - pallets::assets::total_supply(id) + assets::total_supply(id) } /// Returns the account balance for the specified `owner` for a given asset ID. Returns `0` if @@ -44,7 +40,7 @@ pub fn total_supply(id: AssetId) -> Result { /// # Returns /// The balance of the specified account, or an error if the operation fails. pub fn balance_of(id: AssetId, owner: AccountId) -> Result { - pallets::assets::balance_of(id, owner) + assets::balance_of(id, owner) } /// Returns the amount which `spender` is still allowed to withdraw from `owner` for a given @@ -58,7 +54,7 @@ pub fn balance_of(id: AssetId, owner: AccountId) -> Result { /// # Returns /// The remaining allowance, or an error if the operation fails. pub fn allowance(id: AssetId, owner: AccountId, spender: AccountId) -> Result { - pallets::assets::allowance(id, owner, spender) + assets::allowance(id, owner, spender) } /// Transfers `value` amount of tokens from the caller's account to account `to`, with additional @@ -76,7 +72,7 @@ pub fn transfer( to: impl Into>, value: Balance, ) -> Result<()> { - pallets::assets::transfer(id, to, value) + assets::transfer(id, to, value) } /// Transfers `value` tokens on behalf of `from` to account `to` with additional `data` @@ -99,9 +95,9 @@ pub fn transfer_from( _data: &[u8], ) -> Result<()> { match (from, to) { - (None, Some(to)) => pallets::assets::mint(id, to, value), - (Some(from), None) => pallets::assets::burn(id, from, value), - (Some(from), Some(to)) => pallets::assets::transfer_approved(id, from, to, value), + (None, Some(to)) => assets::mint(id, to, value), + (Some(from), None) => assets::burn(id, from, value), + (Some(from), Some(to)) => assets::transfer_approved(id, from, to, value), _ => Ok(()), } } @@ -232,7 +228,7 @@ pub fn create( admin: impl Into>, min_balance: Balance, ) -> Result<()> { - pallets::assets::create(id, admin, min_balance) + assets::create(id, admin, min_balance) } /// Start the process of destroying a token with a given asset ID. @@ -295,7 +291,7 @@ pub fn create( /// # Returns /// Returns `Ok(())` if successful, or an error if the operation fails. pub fn set_metadata(id: AssetId, name: Vec, symbol: Vec, decimals: u8) -> Result<()> { - pallets::assets::set_metadata(id, name, symbol, decimals) + assets::set_metadata(id, name, symbol, decimals) } /// Clear the metadata for a token with a given asset ID. @@ -312,12 +308,13 @@ pub fn set_metadata(id: AssetId, name: Vec, symbol: Vec, decimals: u8) - // } pub fn asset_exists(id: AssetId) -> Result { - pallets::assets::asset_exists(id) + assets::asset_exists(id) } #[derive(Debug, Copy, Clone, PartialEq, Eq, Encode, scale::Decode)] #[cfg_attr(feature = "std", derive(scale_info::TypeInfo))] pub enum FungiblesError { + Other(StatusCode), /// The asset is not live; either frozen or being destroyed. AssetNotLive, /// Not enough allowance to fulfill a request is available. @@ -341,32 +338,21 @@ pub enum FungiblesError { NoBalance, } -// TODO: make generic. -pub(crate) fn convert_to_fungibles_error(index: u8, error: u8) -> PopApiError { - match index { - 10 => balance_into(error), - 52 => assets_into(error), - _ => Module { index, error }, - } -} - -fn balance_into(error: u8) -> PopApiError { - match error { - 2 => UseCaseError(FungiblesError::NoBalance), - _ => Module { index: 10, error }, - } -} - -fn assets_into(error: u8) -> PopApiError { - match error { - 0 => UseCaseError(FungiblesError::InsufficientBalance), - 1 => UseCaseError(FungiblesError::NoAccount), - 2 => UseCaseError(FungiblesError::NoPermission), - 3 => UseCaseError(FungiblesError::Unknown), - 5 => UseCaseError(FungiblesError::InUse), - 7 => UseCaseError(FungiblesError::MinBalanceZero), - 10 => UseCaseError(FungiblesError::InsufficientAllowance), - 16 => UseCaseError(FungiblesError::AssetNotLive), - _ => Module { index: 52, error }, +impl From for FungiblesError { + fn from(value: StatusCode) -> Self { + let encoded = value.0.to_le_bytes(); + match encoded { + // Balances. + [3, 10, 2, _] => FungiblesError::NoBalance, + // Assets. + [3, 52, 0, _] => FungiblesError::NoAccount, + [3, 52, 1, _] => FungiblesError::NoPermission, + [3, 52, 2, _] => FungiblesError::Unknown, + [3, 52, 3, _] => FungiblesError::InUse, + [3, 52, 5, _] => FungiblesError::MinBalanceZero, + [3, 52, 7, _] => FungiblesError::InsufficientAllowance, + [3, 52, 10, _] => FungiblesError::AssetNotLive, + _ => FungiblesError::Other(value), + } } } diff --git a/pop-api/src/v0/assets/mod.rs b/pop-api/src/v0/assets/mod.rs index 736ccc0e..4ce68219 100644 --- a/pop-api/src/v0/assets/mod.rs +++ b/pop-api/src/v0/assets/mod.rs @@ -1,2 +1,494 @@ -pub(crate) mod pallets; -pub mod use_cases; +#![allow(dead_code)] + +use crate::{Balance, RuntimeCall, *}; +use ink::prelude::vec::Vec; +use primitives::{AssetId, MultiAddress}; +use scale::{Compact, Encode}; + +pub mod fungibles; + +type Result = core::result::Result; + +/// [Pallet Assets](https://github.com/paritytech/polkadot-sdk/blob/master/substrate/frame/assets/src/lib.rs): +/// 1. Dispatchables +/// 2. Read state functions +/// +/// 1. Dispatchables within pallet assets (TrustBackedAssets instance) that can be used via the pop api on Pop Network: +/// - create +/// - start_destroy +/// - destroy_accounts +/// - destroy_approvals +/// - finish_destroy +/// - mint +/// - burn +/// - transfer +/// - transfer_keep_alive +/// - force_transfer +/// - freeze +/// - thaw +/// - freeze_asset +/// - thaw_asset +/// - transfer_ownership +/// - set_team +/// - set_metadata +/// - clear_metadata +/// - approve_transfer +/// - cancel_approval +/// - force_cancel_approval +/// - transfer_approved +/// - touch +/// - refund +/// - set_min_balance +/// - touch_other +/// - refund_other +/// - block + +/// Issue a new class of fungible assets from a public origin. +pub(crate) fn create( + id: AssetId, + admin: impl Into>, + min_balance: Balance, +) -> Result<()> { + dispatch(RuntimeCall::Assets(AssetsCall::Create { + id: id.into(), + admin: admin.into(), + min_balance, + })) +} + +/// Start the process of destroying a fungible asset class. +pub(crate) fn start_destroy(id: AssetId) -> Result<()> { + dispatch(RuntimeCall::Assets(AssetsCall::StartDestroy { id: id.into() })) +} + +/// Destroy all accounts associated with a given asset. +pub(crate) fn destroy_accounts(id: AssetId) -> Result<()> { + dispatch(RuntimeCall::Assets(AssetsCall::DestroyAccounts { id: id.into() })) +} + +/// Destroy all approvals associated with a given asset up to the max (see runtime configuration Assets `RemoveItemsLimit`). +pub(crate) fn destroy_approvals(id: AssetId) -> Result<()> { + dispatch(RuntimeCall::Assets(AssetsCall::DestroyApprovals { id: id.into() })) +} + +/// Complete destroying asset and unreserve currency. +pub(crate) fn finish_destroy(id: AssetId) -> Result<()> { + dispatch(RuntimeCall::Assets(AssetsCall::FinishDestroy { id: id.into() })) +} + +/// Mint assets of a particular class. +pub(crate) fn mint( + id: AssetId, + beneficiary: impl Into>, + amount: Balance, +) -> Result<()> { + dispatch(RuntimeCall::Assets(AssetsCall::Mint { + id: id.into(), + beneficiary: beneficiary.into(), + amount: Compact(amount), + })) +} + +/// Reduce the balance of `who` by as much as possible up to `amount` assets of `id`. +pub(crate) fn burn( + id: AssetId, + who: impl Into>, + amount: Balance, +) -> Result<()> { + dispatch(RuntimeCall::Assets(AssetsCall::Burn { + id: id.into(), + who: who.into(), + amount: Compact(amount), + })) +} + +/// Move some assets from the sender account to another. +pub(crate) fn transfer( + id: AssetId, + target: impl Into>, + amount: Balance, +) -> Result<()> { + dispatch(RuntimeCall::Assets(AssetsCall::TransferKeepAlive { + id: id.into(), + target: target.into(), + amount: Compact(amount), + })) +} + +/// Move some assets from the sender account to another, keeping the sender account alive. +pub(crate) fn transfer_keep_alive( + id: AssetId, + target: impl Into>, + amount: Balance, +) -> Result<()> { + dispatch(RuntimeCall::Assets(AssetsCall::TransferKeepAlive { + id: id.into(), + target: target.into(), + amount: Compact(amount), + })) +} + +/// Move some assets from one account to another. Sender should be the Admin of the asset `id`. +pub(crate) fn force_transfer( + id: AssetId, + source: impl Into>, + dest: impl Into>, + amount: Balance, +) -> Result<()> { + dispatch(RuntimeCall::Assets(AssetsCall::ForceTransfer { + id: id.into(), + source: source.into(), + dest: dest.into(), + amount: Compact(amount), + })) +} + +/// Disallow further unprivileged transfers of an asset `id` from an account `who`. `who` +/// must already exist as an entry in `Account`s of the asset. If you want to freeze an +/// account that does not have an entry, use `touch_other` first. +pub(crate) fn freeze(id: AssetId, who: impl Into>) -> Result<()> { + dispatch(RuntimeCall::Assets(AssetsCall::Freeze { id: id.into(), who: who.into() })) +} + +/// Allow unprivileged transfers to and from an account again. +pub(crate) fn thaw(id: AssetId, who: impl Into>) -> Result<()> { + dispatch(RuntimeCall::Assets(AssetsCall::Thaw { id: id.into(), who: who.into() })) +} + +/// Disallow further unprivileged transfers for the asset class. +pub(crate) fn freeze_asset(id: AssetId) -> Result<()> { + dispatch(RuntimeCall::Assets(AssetsCall::FreezeAsset { id: id.into() })) +} + +/// Allow unprivileged transfers for the asset again. +pub(crate) fn thaw_asset(id: AssetId) -> Result<()> { + dispatch(RuntimeCall::Assets(AssetsCall::ThawAsset { id: id.into() })) +} + +/// Change the Owner of an asset. +pub(crate) fn transfer_ownership( + id: AssetId, + owner: impl Into>, +) -> Result<()> { + dispatch(RuntimeCall::Assets(AssetsCall::TransferOwnership { + id: id.into(), + owner: owner.into(), + })) +} + +/// Change the Issuer, Admin and Freezer of an asset. +pub(crate) fn set_team( + id: AssetId, + issuer: impl Into>, + admin: impl Into>, + freezer: impl Into>, +) -> Result<()> { + dispatch(RuntimeCall::Assets(AssetsCall::SetTeam { + id: id.into(), + issuer: issuer.into(), + admin: admin.into(), + freezer: freezer.into(), + })) +} + +/// Set the metadata for an asset. +pub(crate) fn set_metadata( + id: AssetId, + name: Vec, + symbol: Vec, + decimals: u8, +) -> Result<()> { + dispatch(RuntimeCall::Assets(AssetsCall::SetMetadata { id: id.into(), name, symbol, decimals })) +} + +/// Clear the metadata for an asset. +pub(crate) fn clear_metadata(id: AssetId) -> Result<()> { + dispatch(RuntimeCall::Assets(AssetsCall::ClearMetadata { id: id.into() })) +} + +/// Approve an amount of asset for transfer by a delegated third-party account. +pub(crate) fn approve_transfer( + id: AssetId, + delegate: impl Into>, + amount: Balance, +) -> Result<()> { + dispatch(RuntimeCall::Assets(AssetsCall::ApproveTransfer { + id: id.into(), + delegate: delegate.into(), + amount: Compact(amount), + })) +} + +/// Cancel all of some asset approved for delegated transfer by a third-party account. +pub(crate) fn cancel_approval( + id: AssetId, + delegate: impl Into>, +) -> Result<()> { + dispatch(RuntimeCall::Assets(AssetsCall::CancelApproval { + id: id.into(), + delegate: delegate.into(), + })) +} + +/// Cancel all of some asset approved for delegated transfer by a third-party account. +pub(crate) fn force_cancel_approval( + id: AssetId, + owner: impl Into>, + delegate: impl Into>, +) -> Result<()> { + dispatch(RuntimeCall::Assets(AssetsCall::ForceCancelApproval { + id: id.into(), + owner: owner.into(), + delegate: delegate.into(), + })) +} + +/// Transfer some asset balance from a previously delegated account to some third-party +/// account. +pub(crate) fn transfer_approved( + id: AssetId, + owner: impl Into>, + destination: impl Into>, + amount: Balance, +) -> Result<()> { + dispatch(RuntimeCall::Assets(AssetsCall::TransferApproved { + id: id.into(), + owner: owner.into(), + destination: destination.into(), + amount: Compact(amount), + })) +} + +/// Create an asset account for non-provider assets. +pub(crate) fn touch(id: AssetId) -> Result<()> { + dispatch(RuntimeCall::Assets(AssetsCall::Touch { id: id.into() })) +} + +/// Return the deposit (if any) of an asset account or a consumer reference (if any) of an +/// account. +pub(crate) fn refund(id: AssetId, allow_burn: bool) -> Result<()> { + dispatch(RuntimeCall::Assets(AssetsCall::Refund { id: id.into(), allow_burn })) +} + +/// Sets the minimum balance of an asset. +pub(crate) fn set_min_balance(id: AssetId, min_balance: Balance) -> Result<()> { + dispatch(RuntimeCall::Assets(AssetsCall::SetMinBalance { + id: id.into(), + min_balance: Compact(min_balance), + })) +} + +/// Create an asset account for `who`. +pub(crate) fn touch_other(id: AssetId, who: impl Into>) -> Result<()> { + dispatch(RuntimeCall::Assets(AssetsCall::TouchOther { id: id.into(), who: who.into() })) +} + +/// Return the deposit (if any) of a target asset account. Useful if you are the depositor. +pub(crate) fn refund_other(id: AssetId, who: impl Into>) -> Result<()> { + dispatch(RuntimeCall::Assets(AssetsCall::RefundOther { id: id.into(), who: who.into() })) +} + +/// Disallow further unprivileged transfers of an asset `id` to and from an account `who`. +pub(crate) fn block(id: AssetId, who: impl Into>) -> Result<()> { + dispatch(RuntimeCall::Assets(AssetsCall::Block { id: id.into(), who: who.into() })) +} + +/// 2. Read state functions +/// - total_supply +/// - + +pub(crate) fn total_supply(id: AssetId) -> Result { + state::read(RuntimeStateKeys::Assets(AssetsKeys::TotalSupply(id))).into() +} + +pub(crate) fn balance_of(id: AssetId, owner: AccountId) -> Result { + state::read(RuntimeStateKeys::Assets(AssetsKeys::BalanceOf(id, owner))).into() +} + +pub(crate) fn allowance(id: AssetId, owner: AccountId, spender: AccountId) -> Result { + state::read(RuntimeStateKeys::Assets(AssetsKeys::Allowance(id, owner, spender))).into() +} +pub(crate) fn asset_exists(id: AssetId) -> Result { + state::read(RuntimeStateKeys::Assets(AssetsKeys::AssetExists(id))).into() +} + +// Parameters to extrinsics representing an asset id (`AssetIdParameter`) and a balance amount (`Balance`) are expected +// to be compact encoded. The pop api handles that for the developer. +// +// reference: https://substrate.stackexchange.com/questions/1873/what-is-the-meaning-of-palletcompact-in-pallet-development +// +// Asset id that is compact encoded. +type AssetIdParameter = Compact; +// Balance amount that is compact encoded. +type BalanceParameter = Compact; + +#[derive(Encode)] +pub(crate) enum AssetsCall { + #[codec(index = 0)] + Create { id: AssetIdParameter, admin: MultiAddress, min_balance: Balance }, + #[codec(index = 2)] + StartDestroy { id: AssetIdParameter }, + #[codec(index = 3)] + DestroyAccounts { id: AssetIdParameter }, + #[codec(index = 4)] + DestroyApprovals { id: AssetIdParameter }, + #[codec(index = 5)] + FinishDestroy { id: AssetIdParameter }, + #[codec(index = 6)] + Mint { + id: AssetIdParameter, + beneficiary: MultiAddress, + amount: BalanceParameter, + }, + #[codec(index = 7)] + Burn { id: AssetIdParameter, who: MultiAddress, amount: BalanceParameter }, + #[codec(index = 8)] + Transfer { id: AssetIdParameter, target: MultiAddress, amount: BalanceParameter }, + #[codec(index = 9)] + TransferKeepAlive { + id: AssetIdParameter, + target: MultiAddress, + amount: BalanceParameter, + }, + #[codec(index = 10)] + ForceTransfer { + id: AssetIdParameter, + source: MultiAddress, + dest: MultiAddress, + amount: BalanceParameter, + }, + #[codec(index = 11)] + Freeze { id: AssetIdParameter, who: MultiAddress }, + #[codec(index = 12)] + Thaw { id: AssetIdParameter, who: MultiAddress }, + #[codec(index = 13)] + FreezeAsset { id: AssetIdParameter }, + #[codec(index = 14)] + ThawAsset { id: AssetIdParameter }, + #[codec(index = 15)] + TransferOwnership { id: AssetIdParameter, owner: MultiAddress }, + #[codec(index = 16)] + SetTeam { + id: AssetIdParameter, + issuer: MultiAddress, + admin: MultiAddress, + freezer: MultiAddress, + }, + #[codec(index = 17)] + SetMetadata { id: AssetIdParameter, name: Vec, symbol: Vec, decimals: u8 }, + #[codec(index = 18)] + ClearMetadata { id: AssetIdParameter }, + #[codec(index = 22)] + ApproveTransfer { + id: AssetIdParameter, + delegate: MultiAddress, + amount: BalanceParameter, + }, + #[codec(index = 23)] + CancelApproval { id: AssetIdParameter, delegate: MultiAddress }, + #[codec(index = 24)] + ForceCancelApproval { + id: AssetIdParameter, + owner: MultiAddress, + delegate: MultiAddress, + }, + #[codec(index = 25)] + TransferApproved { + id: AssetIdParameter, + owner: MultiAddress, + destination: MultiAddress, + amount: BalanceParameter, + }, + #[codec(index = 26)] + Touch { id: AssetIdParameter }, + #[codec(index = 27)] + Refund { id: AssetIdParameter, allow_burn: bool }, + #[codec(index = 28)] + SetMinBalance { id: AssetIdParameter, min_balance: BalanceParameter }, + #[codec(index = 29)] + TouchOther { id: AssetIdParameter, who: MultiAddress }, + #[codec(index = 30)] + RefundOther { id: AssetIdParameter, who: MultiAddress }, + #[codec(index = 31)] + Block { id: AssetIdParameter, who: MultiAddress }, +} + +// TODO: Not being used atm but necessary if we want to provide access to the +// rest of the pallet, outside of the use cases. +#[derive(Debug, Copy, Clone, PartialEq, Eq, Encode, scale::Decode)] +#[cfg_attr(feature = "std", derive(scale_info::TypeInfo))] +pub enum AssetsError { + /// Account balance must be greater than or equal to the transfer amount. + BalanceLow, + /// The account to alter does not exist. + NoAccount, + /// The signing account has no permission to do the operation. + NoPermission, + /// The given asset ID is unknown. + Unknown, + /// The origin account is frozen. + Frozen, + /// The asset ID is already taken. + InUse, + /// Invalid witness data given. + BadWitness, + /// Minimum balance should be non-zero. + MinBalanceZero, + /// Unable to increment the consumer reference counters on the account. Either no provider + /// reference exists to allow a non-zero balance of a non-self-sufficient asset, or one + /// fewer then the maximum number of consumers has been reached. + UnavailableConsumer, + /// Invalid metadata given. + BadMetadata, + /// No approval exists that would allow the transfer. + Unapproved, + /// The source account would not survive the transfer and it needs to stay alive. + WouldDie, + /// The asset-account already exists. + AlreadyExists, + /// The asset-account doesn't have an associated deposit. + NoDeposit, + /// The operation would result in funds being burned. + WouldBurn, + /// The asset is a live asset and is actively being used. Usually emit for operations such + /// as `start_destroy` which require the asset to be in a destroying state. + LiveAsset, + /// The asset is not live, and likely being destroyed. + AssetNotLive, + /// The asset status is not the expected status. + IncorrectStatus, + /// The asset should be frozen before the given operation. + NotFrozen, + /// Callback action resulted in error. + CallbackFailed, +} + +impl TryFrom for AssetsError { + type Error = PopApiError; + + fn try_from(status_code: u32) -> core::result::Result { + use AssetsError::*; + match status_code { + 0 => Ok(BalanceLow), + 1 => Ok(NoAccount), + 2 => Ok(NoPermission), + 3 => Ok(Unknown), + 4 => Ok(Frozen), + 5 => Ok(InUse), + 6 => Ok(BadWitness), + 7 => Ok(MinBalanceZero), + 8 => Ok(UnavailableConsumer), + 9 => Ok(BadMetadata), + 10 => Ok(Unapproved), + 11 => Ok(WouldDie), + 12 => Ok(AlreadyExists), + 13 => Ok(NoDeposit), + 14 => Ok(WouldBurn), + 15 => Ok(LiveAsset), + 16 => Ok(AssetNotLive), + 17 => Ok(IncorrectStatus), + 18 => Ok(NotFrozen), + _ => todo!(), + } + } +} diff --git a/pop-api/src/v0/assets/pallets/assets.rs b/pop-api/src/v0/assets/pallets/assets.rs deleted file mode 100644 index 87695b81..00000000 --- a/pop-api/src/v0/assets/pallets/assets.rs +++ /dev/null @@ -1,492 +0,0 @@ -#![allow(dead_code)] - -use crate::{Balance, RuntimeCall, *}; -use ink::prelude::vec::Vec; -use primitives::{AssetId, MultiAddress}; -use scale::{Compact, Encode}; - -type Result = core::result::Result; - -/// [Pallet Assets](https://github.com/paritytech/polkadot-sdk/blob/master/substrate/frame/assets/src/lib.rs): -/// 1. Dispatchables -/// 2. Read state functions -/// -/// 1. Dispatchables within pallet assets (TrustBackedAssets instance) that can be used via the pop api on Pop Network: -/// - create -/// - start_destroy -/// - destroy_accounts -/// - destroy_approvals -/// - finish_destroy -/// - mint -/// - burn -/// - transfer -/// - transfer_keep_alive -/// - force_transfer -/// - freeze -/// - thaw -/// - freeze_asset -/// - thaw_asset -/// - transfer_ownership -/// - set_team -/// - set_metadata -/// - clear_metadata -/// - approve_transfer -/// - cancel_approval -/// - force_cancel_approval -/// - transfer_approved -/// - touch -/// - refund -/// - set_min_balance -/// - touch_other -/// - refund_other -/// - block - -/// Issue a new class of fungible assets from a public origin. -pub(crate) fn create( - id: AssetId, - admin: impl Into>, - min_balance: Balance, -) -> Result<()> { - dispatch(RuntimeCall::Assets(AssetsCall::Create { - id: id.into(), - admin: admin.into(), - min_balance, - })) -} - -/// Start the process of destroying a fungible asset class. -pub(crate) fn start_destroy(id: AssetId) -> Result<()> { - dispatch(RuntimeCall::Assets(AssetsCall::StartDestroy { id: id.into() })) -} - -/// Destroy all accounts associated with a given asset. -pub(crate) fn destroy_accounts(id: AssetId) -> Result<()> { - dispatch(RuntimeCall::Assets(AssetsCall::DestroyAccounts { id: id.into() })) -} - -/// Destroy all approvals associated with a given asset up to the max (see runtime configuration Assets `RemoveItemsLimit`). -pub(crate) fn destroy_approvals(id: AssetId) -> Result<()> { - dispatch(RuntimeCall::Assets(AssetsCall::DestroyApprovals { id: id.into() })) -} - -/// Complete destroying asset and unreserve currency. -pub(crate) fn finish_destroy(id: AssetId) -> Result<()> { - dispatch(RuntimeCall::Assets(AssetsCall::FinishDestroy { id: id.into() })) -} - -/// Mint assets of a particular class. -pub(crate) fn mint( - id: AssetId, - beneficiary: impl Into>, - amount: Balance, -) -> Result<()> { - dispatch(RuntimeCall::Assets(AssetsCall::Mint { - id: id.into(), - beneficiary: beneficiary.into(), - amount: Compact(amount), - })) -} - -/// Reduce the balance of `who` by as much as possible up to `amount` assets of `id`. -pub(crate) fn burn( - id: AssetId, - who: impl Into>, - amount: Balance, -) -> Result<()> { - dispatch(RuntimeCall::Assets(AssetsCall::Burn { - id: id.into(), - who: who.into(), - amount: Compact(amount), - })) -} - -/// Move some assets from the sender account to another. -pub(crate) fn transfer( - id: AssetId, - target: impl Into>, - amount: Balance, -) -> Result<()> { - dispatch(RuntimeCall::Assets(AssetsCall::TransferKeepAlive { - id: id.into(), - target: target.into(), - amount: Compact(amount), - })) -} - -/// Move some assets from the sender account to another, keeping the sender account alive. -pub(crate) fn transfer_keep_alive( - id: AssetId, - target: impl Into>, - amount: Balance, -) -> Result<()> { - dispatch(RuntimeCall::Assets(AssetsCall::TransferKeepAlive { - id: id.into(), - target: target.into(), - amount: Compact(amount), - })) -} - -/// Move some assets from one account to another. Sender should be the Admin of the asset `id`. -pub(crate) fn force_transfer( - id: AssetId, - source: impl Into>, - dest: impl Into>, - amount: Balance, -) -> Result<()> { - dispatch(RuntimeCall::Assets(AssetsCall::ForceTransfer { - id: id.into(), - source: source.into(), - dest: dest.into(), - amount: Compact(amount), - })) -} - -/// Disallow further unprivileged transfers of an asset `id` from an account `who`. `who` -/// must already exist as an entry in `Account`s of the asset. If you want to freeze an -/// account that does not have an entry, use `touch_other` first. -pub(crate) fn freeze(id: AssetId, who: impl Into>) -> Result<()> { - dispatch(RuntimeCall::Assets(AssetsCall::Freeze { id: id.into(), who: who.into() })) -} - -/// Allow unprivileged transfers to and from an account again. -pub(crate) fn thaw(id: AssetId, who: impl Into>) -> Result<()> { - dispatch(RuntimeCall::Assets(AssetsCall::Thaw { id: id.into(), who: who.into() })) -} - -/// Disallow further unprivileged transfers for the asset class. -pub(crate) fn freeze_asset(id: AssetId) -> Result<()> { - dispatch(RuntimeCall::Assets(AssetsCall::FreezeAsset { id: id.into() })) -} - -/// Allow unprivileged transfers for the asset again. -pub(crate) fn thaw_asset(id: AssetId) -> Result<()> { - dispatch(RuntimeCall::Assets(AssetsCall::ThawAsset { id: id.into() })) -} - -/// Change the Owner of an asset. -pub(crate) fn transfer_ownership( - id: AssetId, - owner: impl Into>, -) -> Result<()> { - dispatch(RuntimeCall::Assets(AssetsCall::TransferOwnership { - id: id.into(), - owner: owner.into(), - })) -} - -/// Change the Issuer, Admin and Freezer of an asset. -pub(crate) fn set_team( - id: AssetId, - issuer: impl Into>, - admin: impl Into>, - freezer: impl Into>, -) -> Result<()> { - dispatch(RuntimeCall::Assets(AssetsCall::SetTeam { - id: id.into(), - issuer: issuer.into(), - admin: admin.into(), - freezer: freezer.into(), - })) -} - -/// Set the metadata for an asset. -pub(crate) fn set_metadata( - id: AssetId, - name: Vec, - symbol: Vec, - decimals: u8, -) -> Result<()> { - dispatch(RuntimeCall::Assets(AssetsCall::SetMetadata { id: id.into(), name, symbol, decimals })) -} - -/// Clear the metadata for an asset. -pub(crate) fn clear_metadata(id: AssetId) -> Result<()> { - dispatch(RuntimeCall::Assets(AssetsCall::ClearMetadata { id: id.into() })) -} - -/// Approve an amount of asset for transfer by a delegated third-party account. -pub(crate) fn approve_transfer( - id: AssetId, - delegate: impl Into>, - amount: Balance, -) -> Result<()> { - dispatch(RuntimeCall::Assets(AssetsCall::ApproveTransfer { - id: id.into(), - delegate: delegate.into(), - amount: Compact(amount), - })) -} - -/// Cancel all of some asset approved for delegated transfer by a third-party account. -pub(crate) fn cancel_approval( - id: AssetId, - delegate: impl Into>, -) -> Result<()> { - dispatch(RuntimeCall::Assets(AssetsCall::CancelApproval { - id: id.into(), - delegate: delegate.into(), - })) -} - -/// Cancel all of some asset approved for delegated transfer by a third-party account. -pub(crate) fn force_cancel_approval( - id: AssetId, - owner: impl Into>, - delegate: impl Into>, -) -> Result<()> { - dispatch(RuntimeCall::Assets(AssetsCall::ForceCancelApproval { - id: id.into(), - owner: owner.into(), - delegate: delegate.into(), - })) -} - -/// Transfer some asset balance from a previously delegated account to some third-party -/// account. -pub(crate) fn transfer_approved( - id: AssetId, - owner: impl Into>, - destination: impl Into>, - amount: Balance, -) -> Result<()> { - dispatch(RuntimeCall::Assets(AssetsCall::TransferApproved { - id: id.into(), - owner: owner.into(), - destination: destination.into(), - amount: Compact(amount), - })) -} - -/// Create an asset account for non-provider assets. -pub(crate) fn touch(id: AssetId) -> Result<()> { - dispatch(RuntimeCall::Assets(AssetsCall::Touch { id: id.into() })) -} - -/// Return the deposit (if any) of an asset account or a consumer reference (if any) of an -/// account. -pub(crate) fn refund(id: AssetId, allow_burn: bool) -> Result<()> { - dispatch(RuntimeCall::Assets(AssetsCall::Refund { id: id.into(), allow_burn })) -} - -/// Sets the minimum balance of an asset. -pub(crate) fn set_min_balance(id: AssetId, min_balance: Balance) -> Result<()> { - dispatch(RuntimeCall::Assets(AssetsCall::SetMinBalance { - id: id.into(), - min_balance: Compact(min_balance), - })) -} - -/// Create an asset account for `who`. -pub(crate) fn touch_other(id: AssetId, who: impl Into>) -> Result<()> { - dispatch(RuntimeCall::Assets(AssetsCall::TouchOther { id: id.into(), who: who.into() })) -} - -/// Return the deposit (if any) of a target asset account. Useful if you are the depositor. -pub(crate) fn refund_other(id: AssetId, who: impl Into>) -> Result<()> { - dispatch(RuntimeCall::Assets(AssetsCall::RefundOther { id: id.into(), who: who.into() })) -} - -/// Disallow further unprivileged transfers of an asset `id` to and from an account `who`. -pub(crate) fn block(id: AssetId, who: impl Into>) -> Result<()> { - dispatch(RuntimeCall::Assets(AssetsCall::Block { id: id.into(), who: who.into() })) -} - -/// 2. Read state functions -/// - total_supply -/// - - -pub(crate) fn total_supply(id: AssetId) -> Result { - state::read(RuntimeStateKeys::Assets(AssetsKeys::TotalSupply(id))).into() -} - -pub(crate) fn balance_of(id: AssetId, owner: AccountId) -> Result { - state::read(RuntimeStateKeys::Assets(AssetsKeys::BalanceOf(id, owner))).into() -} - -pub(crate) fn allowance(id: AssetId, owner: AccountId, spender: AccountId) -> Result { - state::read(RuntimeStateKeys::Assets(AssetsKeys::Allowance(id, owner, spender))).into() -} -pub(crate) fn asset_exists(id: AssetId) -> Result { - state::read(RuntimeStateKeys::Assets(AssetsKeys::AssetExists(id))).into() -} - -// Parameters to extrinsics representing an asset id (`AssetIdParameter`) and a balance amount (`Balance`) are expected -// to be compact encoded. The pop api handles that for the developer. -// -// reference: https://substrate.stackexchange.com/questions/1873/what-is-the-meaning-of-palletcompact-in-pallet-development -// -// Asset id that is compact encoded. -type AssetIdParameter = Compact; -// Balance amount that is compact encoded. -type BalanceParameter = Compact; - -#[derive(Encode)] -pub(crate) enum AssetsCall { - #[codec(index = 0)] - Create { id: AssetIdParameter, admin: MultiAddress, min_balance: Balance }, - #[codec(index = 2)] - StartDestroy { id: AssetIdParameter }, - #[codec(index = 3)] - DestroyAccounts { id: AssetIdParameter }, - #[codec(index = 4)] - DestroyApprovals { id: AssetIdParameter }, - #[codec(index = 5)] - FinishDestroy { id: AssetIdParameter }, - #[codec(index = 6)] - Mint { - id: AssetIdParameter, - beneficiary: MultiAddress, - amount: BalanceParameter, - }, - #[codec(index = 7)] - Burn { id: AssetIdParameter, who: MultiAddress, amount: BalanceParameter }, - #[codec(index = 8)] - Transfer { id: AssetIdParameter, target: MultiAddress, amount: BalanceParameter }, - #[codec(index = 9)] - TransferKeepAlive { - id: AssetIdParameter, - target: MultiAddress, - amount: BalanceParameter, - }, - #[codec(index = 10)] - ForceTransfer { - id: AssetIdParameter, - source: MultiAddress, - dest: MultiAddress, - amount: BalanceParameter, - }, - #[codec(index = 11)] - Freeze { id: AssetIdParameter, who: MultiAddress }, - #[codec(index = 12)] - Thaw { id: AssetIdParameter, who: MultiAddress }, - #[codec(index = 13)] - FreezeAsset { id: AssetIdParameter }, - #[codec(index = 14)] - ThawAsset { id: AssetIdParameter }, - #[codec(index = 15)] - TransferOwnership { id: AssetIdParameter, owner: MultiAddress }, - #[codec(index = 16)] - SetTeam { - id: AssetIdParameter, - issuer: MultiAddress, - admin: MultiAddress, - freezer: MultiAddress, - }, - #[codec(index = 17)] - SetMetadata { id: AssetIdParameter, name: Vec, symbol: Vec, decimals: u8 }, - #[codec(index = 18)] - ClearMetadata { id: AssetIdParameter }, - #[codec(index = 22)] - ApproveTransfer { - id: AssetIdParameter, - delegate: MultiAddress, - amount: BalanceParameter, - }, - #[codec(index = 23)] - CancelApproval { id: AssetIdParameter, delegate: MultiAddress }, - #[codec(index = 24)] - ForceCancelApproval { - id: AssetIdParameter, - owner: MultiAddress, - delegate: MultiAddress, - }, - #[codec(index = 25)] - TransferApproved { - id: AssetIdParameter, - owner: MultiAddress, - destination: MultiAddress, - amount: BalanceParameter, - }, - #[codec(index = 26)] - Touch { id: AssetIdParameter }, - #[codec(index = 27)] - Refund { id: AssetIdParameter, allow_burn: bool }, - #[codec(index = 28)] - SetMinBalance { id: AssetIdParameter, min_balance: BalanceParameter }, - #[codec(index = 29)] - TouchOther { id: AssetIdParameter, who: MultiAddress }, - #[codec(index = 30)] - RefundOther { id: AssetIdParameter, who: MultiAddress }, - #[codec(index = 31)] - Block { id: AssetIdParameter, who: MultiAddress }, -} - -// TODO: Not being used atm but necessary if we want to provide access to the -// rest of the pallet, outside of the use cases. -#[derive(Debug, Copy, Clone, PartialEq, Eq, Encode, scale::Decode)] -#[cfg_attr(feature = "std", derive(scale_info::TypeInfo))] -pub enum AssetsError { - /// Account balance must be greater than or equal to the transfer amount. - BalanceLow, - /// The account to alter does not exist. - NoAccount, - /// The signing account has no permission to do the operation. - NoPermission, - /// The given asset ID is unknown. - Unknown, - /// The origin account is frozen. - Frozen, - /// The asset ID is already taken. - InUse, - /// Invalid witness data given. - BadWitness, - /// Minimum balance should be non-zero. - MinBalanceZero, - /// Unable to increment the consumer reference counters on the account. Either no provider - /// reference exists to allow a non-zero balance of a non-self-sufficient asset, or one - /// fewer then the maximum number of consumers has been reached. - UnavailableConsumer, - /// Invalid metadata given. - BadMetadata, - /// No approval exists that would allow the transfer. - Unapproved, - /// The source account would not survive the transfer and it needs to stay alive. - WouldDie, - /// The asset-account already exists. - AlreadyExists, - /// The asset-account doesn't have an associated deposit. - NoDeposit, - /// The operation would result in funds being burned. - WouldBurn, - /// The asset is a live asset and is actively being used. Usually emit for operations such - /// as `start_destroy` which require the asset to be in a destroying state. - LiveAsset, - /// The asset is not live, and likely being destroyed. - AssetNotLive, - /// The asset status is not the expected status. - IncorrectStatus, - /// The asset should be frozen before the given operation. - NotFrozen, - /// Callback action resulted in error. - CallbackFailed, -} - -impl TryFrom for AssetsError { - type Error = PopApiError; - - fn try_from(status_code: u32) -> core::result::Result { - use AssetsError::*; - match status_code { - 0 => Ok(BalanceLow), - 1 => Ok(NoAccount), - 2 => Ok(NoPermission), - 3 => Ok(Unknown), - 4 => Ok(Frozen), - 5 => Ok(InUse), - 6 => Ok(BadWitness), - 7 => Ok(MinBalanceZero), - 8 => Ok(UnavailableConsumer), - 9 => Ok(BadMetadata), - 10 => Ok(Unapproved), - 11 => Ok(WouldDie), - 12 => Ok(AlreadyExists), - 13 => Ok(NoDeposit), - 14 => Ok(WouldBurn), - 15 => Ok(LiveAsset), - 16 => Ok(AssetNotLive), - 17 => Ok(IncorrectStatus), - 18 => Ok(NotFrozen), - _ => todo!(), - } - } -} diff --git a/pop-api/src/v0/assets/pallets/mod.rs b/pop-api/src/v0/assets/pallets/mod.rs deleted file mode 100644 index 0b8a53a0..00000000 --- a/pop-api/src/v0/assets/pallets/mod.rs +++ /dev/null @@ -1 +0,0 @@ -pub(crate) mod assets; diff --git a/pop-api/src/v0/assets/use_cases/mod.rs b/pop-api/src/v0/assets/use_cases/mod.rs deleted file mode 100644 index 182590df..00000000 --- a/pop-api/src/v0/assets/use_cases/mod.rs +++ /dev/null @@ -1 +0,0 @@ -pub mod fungibles; diff --git a/pop-api/src/v0/balances.rs b/pop-api/src/v0/balances.rs index 56c3ca72..ae2709e7 100644 --- a/pop-api/src/v0/balances.rs +++ b/pop-api/src/v0/balances.rs @@ -1,6 +1,8 @@ -use crate::{dispatch, error::PopApiError, primitives::MultiAddress, v0::RuntimeCall, AccountId}; +use crate::{ + dispatch, primitives::MultiAddress, v0::RuntimeCall, AccountId, PopApiError, StatusCode, +}; -type Result = core::result::Result; +type Result = core::result::Result; pub fn transfer_keep_alive( dest: impl Into>, diff --git a/pop-api/src/v0/cross_chain/mod.rs b/pop-api/src/v0/cross_chain/mod.rs index 1d3c5b7d..583447b1 100644 --- a/pop-api/src/v0/cross_chain/mod.rs +++ b/pop-api/src/v0/cross_chain/mod.rs @@ -1,8 +1,15 @@ pub mod coretime; -use crate::error::PopApiError; +use crate::StatusCode; -type Result = core::result::Result; +type Result = core::result::Result; +type BlockNumber = ::BlockNumber; + +pub fn relay_chain_block_number() -> std::result::Result { + crate::v0::state::read(RuntimeStateKeys::ParachainSystem( + ParachainSystemKeys::LastRelayChainBlockNumber, + )) +} #[derive(Debug, Copy, Clone, PartialEq, Eq, scale::Encode, scale::Decode)] #[cfg_attr(feature = "std", derive(scale_info::TypeInfo))] @@ -63,7 +70,7 @@ pub enum Error { } impl TryFrom for Error { - type Error = PopApiError; + type Error = Error; fn try_from(status_code: u32) -> core::result::Result { use Error::*; diff --git a/pop-api/src/v0/mod.rs b/pop-api/src/v0/mod.rs index 75bcb878..41574cfb 100644 --- a/pop-api/src/v0/mod.rs +++ b/pop-api/src/v0/mod.rs @@ -1,24 +1,22 @@ -use crate::{ - primitives::storage_keys::{ParachainSystemKeys, RuntimeStateKeys}, - BlockNumber, PopApiError, -}; - +#[cfg(feature = "assets")] pub mod assets; +#[cfg(feature = "balances")] pub mod balances; +#[cfg(feature = "cross-chain")] pub mod cross_chain; +#[cfg(feature = "nfts")] pub mod nfts; pub mod state; -pub fn relay_chain_block_number() -> Result { - state::read(RuntimeStateKeys::ParachainSystem(ParachainSystemKeys::LastRelayChainBlockNumber)) -} - #[derive(scale::Encode)] pub(crate) enum RuntimeCall { - #[codec(index = 10)] - Balances(balances::BalancesCall), - #[codec(index = 50)] - Nfts(nfts::NftCalls), + // #[codec(index = 10)] + // #[cfg(feature = "balances")] + // Balances(balances::BalancesCall), + // #[codec(index = 50)] + // #[cfg(feature = "nfts")] + // Nfts(nfts::NftCalls), #[codec(index = 52)] - Assets(assets::pallets::assets::AssetsCall), + #[cfg(feature = "assets")] + Assets(assets::AssetsCall), } diff --git a/pop-api/src/v0/nfts.rs b/pop-api/src/v0/nfts.rs index 2de306a9..1e4406e5 100644 --- a/pop-api/src/v0/nfts.rs +++ b/pop-api/src/v0/nfts.rs @@ -1,12 +1,14 @@ use super::RuntimeCall; -use crate::{PopApiError, *}; +use crate::*; use ink::prelude::vec::Vec; use primitives::{ApprovalsLimit, BoundedBTreeMap, KeyLimit, MultiAddress}; pub use primitives::{CollectionId, ItemId}; use scale::Encode; pub use types::*; -type Result = core::result::Result; +type Result = core::result::Result; +type StringLimit = u32; +type MaxTips = u32; /// Issue a new collection of non-fungible items pub fn create( @@ -610,7 +612,7 @@ pub enum Error { } impl TryFrom for Error { - type Error = PopApiError; + type Error = Error; fn try_from(status_code: u32) -> core::result::Result { use Error::*; diff --git a/pop-api/src/v0/state.rs b/pop-api/src/v0/state.rs index 9f5e4c0c..1aca01cf 100644 --- a/pop-api/src/v0/state.rs +++ b/pop-api/src/v0/state.rs @@ -2,5 +2,6 @@ use crate::{primitives::storage_keys::RuntimeStateKeys, read_state, PopApiError} use scale::Decode; pub fn read(key: RuntimeStateKeys) -> crate::Result { - read_state(key).and_then(|v| T::decode(&mut &v[..]).map_err(|_e| PopApiError::DecodingFailed)) + read_state(key) + .and_then(|v| T::decode(&mut &v[..]).map_err(|_e| PopApiError::DecodingFailed.into())) } diff --git a/runtime/devnet/Cargo.toml b/runtime/devnet/Cargo.toml index 46208d8f..daa5457e 100644 --- a/runtime/devnet/Cargo.toml +++ b/runtime/devnet/Cargo.toml @@ -91,7 +91,7 @@ parachain-info.workspace = true env_logger = "0.11.2" hex = "0.4.3" enumflags2 = "0.7.9" -pop-api = { path = "../../pop-api", default-features = false } +pop-api = { path = "../../pop-api", defeult-features = false, features = ["assets"] } [features] default = ["std"] diff --git a/runtime/devnet/src/extensions.rs b/runtime/devnet/src/extensions.rs index 32667d16..b4c6ba84 100644 --- a/runtime/devnet/src/extensions.rs +++ b/runtime/devnet/src/extensions.rs @@ -72,16 +72,11 @@ where } } } - pub(crate) fn convert_to_status_code(error: DispatchError) -> u32 { - match error { - _ => { - let mut encoded_error = error.encode(); - // Resize the encoded value to 4 bytes in order to decode the value in a u32 (4 bytes). - encoded_error.resize(4, 0); - u32::decode(&mut &encoded_error[..]).unwrap() - }, - } + let mut encoded_error = error.encode(); + // Resize the encoded value to 4 bytes in order to decode the value in a u32 (4 bytes). + encoded_error.resize(4, 0); + u32::decode(&mut &encoded_error[..]).expect("qid, resized to 4 bytes line above") } pub mod v0 { diff --git a/runtime/devnet/src/tests/local_fungibles.rs b/runtime/devnet/src/tests/local_fungibles.rs index 9f208b15..154e9897 100644 --- a/runtime/devnet/src/tests/local_fungibles.rs +++ b/runtime/devnet/src/tests/local_fungibles.rs @@ -269,7 +269,7 @@ fn create_works() { // No balance to pay for fees. assert_eq!( decoded::(create(addr.clone(), ASSET_ID, addr.clone(), 1)), - UseCaseError(NoBalance) + Module { index: 10, error: 2 }, ); // Instantiate a contract without balance (relay token). let addr = @@ -278,7 +278,7 @@ fn create_works() { // No balance to pay fe deposit. assert_eq!( decoded::(create(addr.clone(), ASSET_ID, addr.clone(), 1)), - UseCaseError(NoBalance) + Module { index: 10, error: 2 }, ); // Instantiate a contract with balance. let addr = instantiate( @@ -290,12 +290,12 @@ fn create_works() { // Asset ID is already taken. assert_eq!( decoded::(create(addr.clone(), ASSET_ID, BOB, 1)), - UseCaseError(InUse) + Module { index: 52, error: 5 }, ); // The minimal balance for an asset must be non zero. assert_eq!( decoded::(create(addr.clone(), new_asset, BOB, 0)), - UseCaseError(MinBalanceZero) + Module { index: 52, error: 7 }, ); let result = create(addr.clone(), new_asset, BOB, 1); assert!(!result.did_revert(), "Contract reverted!"); @@ -347,7 +347,7 @@ fn transfer_from_mint_works() { amount, &[0u8] )), - UseCaseError(NoPermission) + Module { index: 52, error: 2 }, ); // Minimum balance of an asset can not be zero. assert_eq!( @@ -366,7 +366,7 @@ fn transfer_from_mint_works() { amount, &[0u8] )), - UseCaseError(AssetNotLive) + Module { index: 52, error: 16 }, ); thaw_asset(asset, addr.clone()); // Successful mint. @@ -398,7 +398,7 @@ fn transfer_from_mint_works() { amount, &[0u8] )), - UseCaseError(AssetNotLive) + Module { index: 52, error: 16 }, ); }); } @@ -418,7 +418,7 @@ fn transfer_works() { // Asset does not exist. assert_eq!( decoded::(transfer(addr.clone(), 1, BOB, amount,)), - UseCaseError(Unknown) + Module { index: 52, error: 3 }, ); // Create asset with Alice as owner and mint `amount` to contract address. let asset = create_asset_and_mint_to(ALICE, 1, addr.clone(), amount); @@ -426,18 +426,18 @@ fn transfer_works() { freeze_asset(asset, ALICE); assert_eq!( decoded::(transfer(addr.clone(), asset, BOB, amount,)), - UseCaseError(AssetNotLive) + Module { index: 52, error: 16 }, ); thaw_asset(asset, ALICE); // Not enough balance. assert_eq!( decoded::(transfer(addr.clone(), asset, BOB, amount + 1 * UNIT)), - UseCaseError(InsufficientBalance) + Module { index: 52, error: 0 }, ); // Not enough balance due to ED. assert_eq!( decoded::(transfer(addr.clone(), asset, BOB, amount)), - UseCaseError(InsufficientBalance) + Module { index: 52, error: 0 }, ); // Successful transfer. let bob_balance_before_mint = Assets::balance(asset, &BOB); @@ -454,7 +454,7 @@ fn transfer_works() { start_destroy_asset(asset, ALICE); assert_eq!( decoded::(transfer(addr.clone(), asset, BOB, amount / 4)), - UseCaseError(AssetNotLive) + Module { index: 52, error: 16 }, ); }); } diff --git a/runtime/devnet/src/tests/mod.rs b/runtime/devnet/src/tests/mod.rs index c13030a3..dcb97ae1 100644 --- a/runtime/devnet/src/tests/mod.rs +++ b/runtime/devnet/src/tests/mod.rs @@ -256,7 +256,7 @@ fn dispatch_error_to_status_code_to_pop_api_error_works() { for (error, pop_api_error) in test_cases { // Show that the encoding and decoding of the PopApiError <> u32 (status code) works. let status_code = crate::extensions::convert_to_status_code(error); - let error = pop_api::error::convert_to_pop_api_error(status_code); - assert_eq!(pop_api_error, error,); + // let error = pop_api::error::convert_to_pop_api_error(status_code); + // assert_eq!(pop_api_error, error,); } } From f88dd89b8fbbfebc28126f0262fc8b5397b903d6 Mon Sep 17 00:00:00 2001 From: Daanvdplas Date: Tue, 25 Jun 2024 16:58:18 +0200 Subject: [PATCH 011/112] refactor: apply comments part 2 --- pop-api/Cargo.toml | 6 +- .../{balance-transfer => }/.gitignore | 2 +- pop-api/examples/fungibles/.gitignore | 9 - pop-api/examples/fungibles/lib.rs | 2 +- pop-api/examples/nfts/.gitignore | 9 - pop-api/examples/place-spot-order/.gitignore | 9 - .../examples/read-runtime-state/.gitignore | 9 - pop-api/src/error.rs | 317 ++++++++++------- pop-api/src/lib.rs | 12 +- pop-api/src/primitives.rs | 1 - pop-api/src/v0/assets/fungibles.rs | 64 ++++ pop-api/src/v0/assets/mod.rs | 8 +- pop-api/src/v0/balances.rs | 6 +- pop-api/src/v0/cross_chain/mod.rs | 9 +- pop-api/src/v0/mod.rs | 12 +- pop-api/src/v0/nfts.rs | 318 +++++++++--------- pop-api/src/v0/state.rs | 5 +- primitives/Cargo.toml | 5 +- primitives/src/lib.rs | 25 +- primitives/src/storage_keys.rs | 10 +- runtime/devnet/Cargo.toml | 4 +- runtime/devnet/src/extensions.rs | 19 +- runtime/devnet/src/lib.rs | 4 +- runtime/devnet/src/tests/local_fungibles.rs | 57 +--- runtime/devnet/src/tests/mod.rs | 311 ++++++++--------- runtime/testnet/Cargo.toml | 2 +- runtime/testnet/src/extensions.rs | 6 +- runtime/testnet/src/lib.rs | 4 +- 28 files changed, 677 insertions(+), 568 deletions(-) rename pop-api/examples/{balance-transfer => }/.gitignore (93%) delete mode 100755 pop-api/examples/fungibles/.gitignore delete mode 100755 pop-api/examples/nfts/.gitignore delete mode 100755 pop-api/examples/place-spot-order/.gitignore delete mode 100755 pop-api/examples/read-runtime-state/.gitignore diff --git a/pop-api/Cargo.toml b/pop-api/Cargo.toml index b80cb3b0..9a868cfa 100644 --- a/pop-api/Cargo.toml +++ b/pop-api/Cargo.toml @@ -31,7 +31,7 @@ std = [ "sp-io/std", "sp-runtime/std", ] -assets = [] +assets = ["pop-primitives/assets"] balances = [] -nfts = [] -cross-chain = [] +nfts = ["pop-primitives/nfts"] +cross-chain = ["pop-primitives/cross-chain"] diff --git a/pop-api/examples/balance-transfer/.gitignore b/pop-api/examples/.gitignore similarity index 93% rename from pop-api/examples/balance-transfer/.gitignore rename to pop-api/examples/.gitignore index 8de8f877..e0caa493 100755 --- a/pop-api/examples/balance-transfer/.gitignore +++ b/pop-api/examples/.gitignore @@ -1,5 +1,5 @@ # Ignore build artifacts from the local tests sub-crate. -/target/ +/fungibles/target/ # Ignore backup files creates by cargo fmt. **/*.rs.bk diff --git a/pop-api/examples/fungibles/.gitignore b/pop-api/examples/fungibles/.gitignore deleted file mode 100755 index 8de8f877..00000000 --- a/pop-api/examples/fungibles/.gitignore +++ /dev/null @@ -1,9 +0,0 @@ -# Ignore build artifacts from the local tests sub-crate. -/target/ - -# Ignore backup files creates by cargo fmt. -**/*.rs.bk - -# Remove Cargo.lock when creating an executable, leave it for libraries -# More information here http://doc.crates.io/guide.html#cargotoml-vs-cargolock -Cargo.lock diff --git a/pop-api/examples/fungibles/lib.rs b/pop-api/examples/fungibles/lib.rs index 161c7fdd..41ea1b14 100755 --- a/pop-api/examples/fungibles/lib.rs +++ b/pop-api/examples/fungibles/lib.rs @@ -8,7 +8,7 @@ use ink::prelude::vec::Vec; use pop_api::{ assets::fungibles::{self as api, FungiblesError}, - error::{PopApiError, StatusCode}, + error::{Error, StatusCode}, primitives::{AccountId as AccountId32, AssetId}, }; diff --git a/pop-api/examples/nfts/.gitignore b/pop-api/examples/nfts/.gitignore deleted file mode 100755 index 8de8f877..00000000 --- a/pop-api/examples/nfts/.gitignore +++ /dev/null @@ -1,9 +0,0 @@ -# Ignore build artifacts from the local tests sub-crate. -/target/ - -# Ignore backup files creates by cargo fmt. -**/*.rs.bk - -# Remove Cargo.lock when creating an executable, leave it for libraries -# More information here http://doc.crates.io/guide.html#cargotoml-vs-cargolock -Cargo.lock diff --git a/pop-api/examples/place-spot-order/.gitignore b/pop-api/examples/place-spot-order/.gitignore deleted file mode 100755 index 8de8f877..00000000 --- a/pop-api/examples/place-spot-order/.gitignore +++ /dev/null @@ -1,9 +0,0 @@ -# Ignore build artifacts from the local tests sub-crate. -/target/ - -# Ignore backup files creates by cargo fmt. -**/*.rs.bk - -# Remove Cargo.lock when creating an executable, leave it for libraries -# More information here http://doc.crates.io/guide.html#cargotoml-vs-cargolock -Cargo.lock diff --git a/pop-api/examples/read-runtime-state/.gitignore b/pop-api/examples/read-runtime-state/.gitignore deleted file mode 100755 index 8de8f877..00000000 --- a/pop-api/examples/read-runtime-state/.gitignore +++ /dev/null @@ -1,9 +0,0 @@ -# Ignore build artifacts from the local tests sub-crate. -/target/ - -# Ignore backup files creates by cargo fmt. -**/*.rs.bk - -# Remove Cargo.lock when creating an executable, leave it for libraries -# More information here http://doc.crates.io/guide.html#cargotoml-vs-cargolock -Cargo.lock diff --git a/pop-api/src/error.rs b/pop-api/src/error.rs index 4d5a8fb9..b8a56f55 100644 --- a/pop-api/src/error.rs +++ b/pop-api/src/error.rs @@ -1,6 +1,7 @@ use ink::env::chain_extension::FromStatusCode; use scale::{Decode, Encode}; -use PopApiError::*; + +use Error::*; #[derive(Debug, Copy, Clone, PartialEq, Eq, Encode, Decode)] #[cfg_attr(feature = "std", derive(scale_info::TypeInfo))] @@ -30,10 +31,69 @@ impl From for StatusCode { } } +// If an unknown variant of the `DispatchError` is detected the error needs to be converted +// into the encoded value of `Error::Other`. This conversion is performed by shifting the bytes one +// position forward (discarding the last byte as it is not used) and setting the first byte to the +// encoded value of `Other` (0u8). This ensures the error is correctly categorized as an `Other` +// variant which provides all the necessary information to debug which error occurred in the runtime. +// +// Byte layout explanation: +// - Byte 0: index of the variant within `Error` +// - Byte 1: +// - Must be zero for `UNIT_ERRORS`. +// - Represents the nested error in `SINGLE_NESTED_ERRORS`. +// - Represents the first level of nesting in `DOUBLE_NESTED_ERRORS`. +// - Byte 2: +// - Represents the second level of nesting in `DOUBLE_NESTED_ERRORS`. +// - Byte 3: +// - Unused or represents further nested information. +// +// This mechanism ensures backward compatibility by correctly categorizing any unknown errors +// into the `Other` variant, thus preventing issues caused by breaking changes. +fn convert_unknown_errors(encoded_error: &mut [u8; 4]) { + let all_errors = [ + UNIT_ERRORS.as_slice(), + SINGLE_NESTED_ERRORS.as_slice(), + DOUBLE_NESTED_ERRORS.as_slice(), + // `DecodingFailed`. + &[255u8], + ] + .concat(); + // Unknown errors, i.e. an encoded value where the first byte is non-zero (indicating a variant + // in `Error`) but unknown. + if !all_errors.contains(&encoded_error[0]) { + encoded_error[..].rotate_right(1); + encoded_error[0] = 0u8; + } + convert_unknown_nested_errors(encoded_error); +} + +// If an unknown nested variant of the `DispatchError` is detected (i.e. when any of the subsequent +// bytes are non-zero). +fn convert_unknown_nested_errors(encoded_error: &mut [u8; 4]) { + // Converts single nested errors that are known to the Pop API as unit errors into `Other`. + if UNIT_ERRORS.contains(&encoded_error[0]) && encoded_error[1..].iter().any(|x| *x != 0u8) { + encoded_error[..].rotate_right(1); + encoded_error[0] = 0u8; + // Converts double nested errors that are known to the Pop API as single nested errors into + // `Other`. + } else if SINGLE_NESTED_ERRORS.contains(&encoded_error[0]) + && encoded_error[2..].iter().any(|x| *x != 0u8) + { + encoded_error[..].rotate_right(1); + encoded_error[0] = 0u8; + } else if DOUBLE_NESTED_ERRORS.contains(&encoded_error[0]) + && encoded_error[3..].iter().any(|x| *x != 0u8) + { + encoded_error[..].rotate_right(1); + encoded_error[0] = 0u8; + } +} + #[derive(Debug, Copy, Clone, PartialEq, Eq, Encode, Decode)] #[cfg_attr(feature = "std", derive(scale_info::TypeInfo))] #[repr(u8)] -pub enum PopApiError { +pub enum Error { /// Some unknown error occurred. Go to the Pop API docs section `Pop API error`. Other { // Index within the `DispatchError` @@ -76,8 +136,34 @@ pub enum PopApiError { DecodingFailed = 255, } -impl From for StatusCode { - fn from(value: PopApiError) -> Self { +// Unit `Error` variants. +// (variant: index): +// - CannotLookup: 1, +// - BadOrigin: 2, +// - ConsumerRemaining: 4, +// - NoProviders: 5, +// - TooManyConsumers: 6, +// - Exhausted: 10, +// - Corruption: 11, +// - Unavailable: 12, +// - RootNotAllowed: 13, +// - DecodingFailed: 255, +const UNIT_ERRORS: [u8; 10] = [1, 2, 4, 5, 6, 10, 11, 12, 13, 255]; + +// Single nested `Error` variants. +// (variant: index): +// - Token: 7, +// - Arithmetic: 8, +// - Transaction: 9, +const SINGLE_NESTED_ERRORS: [u8; 3] = [7, 8, 9]; + +// Double nested `Error` variants +// (variant: index): +// - Module: 3, +const DOUBLE_NESTED_ERRORS: [u8; 1] = [3]; + +impl From for StatusCode { + fn from(value: Error) -> Self { let mut encoded_error = value.encode(); // Resize the encoded value to 4 bytes in order to decode the value in a u32 (4 bytes). encoded_error.resize(4, 0); @@ -87,71 +173,11 @@ impl From for StatusCode { } } -impl From for PopApiError { - // `pub` because it is used in `runtime/devnet/src/extensions/tests/mod.rs`'s test: - // `dispatch_error_to_status_code_to_pop_api_error_works` - // - // This function converts a given `status_code` (u32) into a `PopApiError`. +impl From for Error { fn from(value: StatusCode) -> Self { let encoded: [u8; 4] = value.0.to_le_bytes(); - PopApiError::decode(&mut &encoded[..]).unwrap_or(DecodingFailed) - } -} - -// If an unknown nested variant of the `DispatchError` is detected (i.e., any of the subsequent -// bytes are non-zero, indicating a breaking change in the `DispatchError`), the error needs to be -// converted into the encoded value of `PopApiError::Other`. This conversion is performed by -// shifting the bytes one position forward (discarding the last byte as it is not used) and setting -// the first byte to the encoded value of `Other` (0u8). This ensures the error is correctly -// categorized as an `Other` variant. -// -// Byte layout explanation: -// - Byte 0: PopApiError -// - Byte 1: -// - Must be zero for `UNIT_ERRORS`. -// - Represents the nested error in `SINGLE_NESTED_ERRORS`. -// - Represents the first level of nesting in `DOUBLE_NESTED_ERRORS`. -// - Byte 2: -// - Represents the second level of nesting in `DOUBLE_NESTED_ERRORS`. -// - Byte 3: -// - Unused or represents further nested information. -// -// This mechanism ensures backward compatibility by correctly categorizing any unknown nested errors -// into the `Other` variant, thus preventing issues caused by new or unexpected error formats. -pub(crate) fn convert_unknown_nested_errors(encoded_error: &mut [u8; 4]) { - // Converts single nested errors that are known to the Pop API as unit errors into `Other`. - if UNIT_ERRORS.contains(&encoded_error[0]) && encoded_error[1..].iter().any(|x| *x != 0u8) { - encoded_error[..].rotate_right(1); - encoded_error[0] = 0u8; - // Converts double nested errors that are known to the Pop API as single nested errors into - // `Other`. - } else if SINGLE_NESTED_ERRORS.contains(&encoded_error[0]) - && encoded_error[2..].iter().any(|x| *x != 0u8) - { - encoded_error[..].rotate_right(1); - encoded_error[0] = 0u8; - } else if DOUBLE_NESTED_ERRORS.contains(&encoded_error[0]) - && encoded_error[3..].iter().any(|x| *x != 0u8) - { - encoded_error[..].rotate_right(1); - encoded_error[0] = 0u8; - } -} - -pub(crate) fn convert_unknown_errors(encoded_error: &mut [u8; 4]) { - let all_errors = [ - UNIT_ERRORS.as_slice(), - SINGLE_NESTED_ERRORS.as_slice(), - DOUBLE_NESTED_ERRORS.as_slice(), - // `DecodingFailed`. - &[255u8], - ] - .concat(); - if !all_errors.contains(&encoded_error[0]) { - encoded_error[..].rotate_right(1); - encoded_error[0] = 0u8; + Error::decode(&mut &encoded[..]).unwrap_or(DecodingFailed) } - convert_unknown_nested_errors(encoded_error); } #[derive(Debug, Copy, Clone, PartialEq, Eq, scale::Encode, scale::Decode)] @@ -200,26 +226,6 @@ pub enum TransactionalError { NoLayer, } -// Unit `DispatchError` variants (variant: index): -// - CannotLookup: 1, -// - BadOrigin: 2, -// - ConsumerRemaining: 4, -// - NoProviders: 5, -// - TooManyConsumers: 6, -// - Exhausted: 10, -// - Corruption: 11, -// - Unavailable: 12, -// - RootNotAllowed: 13, -const UNIT_ERRORS: [u8; 9] = [1, 2, 4, 5, 6, 10, 11, 12, 13]; - -// Single nested `DispatchError` variants (variant: index): -// - Token: 3, -// - Arithmetic: 8, -// - Transaction: 9, -const SINGLE_NESTED_ERRORS: [u8; 3] = [7, 8, 9]; - -const DOUBLE_NESTED_ERRORS: [u8; 1] = [3]; - #[cfg(test)] mod tests { use super::*; @@ -231,20 +237,30 @@ mod tests { assert_eq!(u32::MAX.encode().len(), 4); } - // Decodes into `StatusCode(u32)` and converts it into the `PopApiError`. - fn into_pop_api_error(encoded_error: [u8; 4]) -> PopApiError { - let status_code = - StatusCode::from_status_code(u32::decode(&mut &encoded_error[..]).unwrap()) - .unwrap_err(); + // Decodes 4 bytes into a `u32` and converts it into `StatusCode`. + fn into_status_code(encoded_error: [u8; 4]) -> StatusCode { + let decoded_u32 = u32::decode(&mut &encoded_error[..]).unwrap(); + StatusCode::from_status_code(decoded_u32).unwrap_err() + } + + // Decodes 4 bytes into a `u32` and converts it into `Error`. + fn into_error(encoded_error: [u8; 4]) -> Error { + let decoded_u32 = u32::decode(&mut &encoded_error[..]).unwrap(); + let status_code = StatusCode::from_status_code(decoded_u32).unwrap_err(); status_code.into() } - // Tests for the `From` implementation for `PopApiError`. + // Tests the `From` implementation for `Error`. // - // If the encoded value indicates a nested `PopApiError` which is not handled by the Pop API - // version, the encoded value is converted into `PopApiError::Other`. + // Unit variants: + // If the encoded value indicates a nested `Error` which is known by the Pop API version as a + // unit variant, the encoded value is converted into `Error::Other`. + // + // Example: the error `BadOrigin` (encoded: `[2, 0, 0, 0]`) with a non-zero value for one + // of the bytes [1..4]: `[2, 0, 1, 0]` is converted into `[0, 2, 0, 1]`. This is decoded to + // `Error::Other { dispatch_error: 2, index: 0, error: 1 }`. #[test] - fn test_unit_pop_api_error_variants() { + fn unit_error_variants() { let errors = vec![ CannotLookup, BadOrigin, @@ -255,73 +271,134 @@ mod tests { Corruption, Unavailable, RootNotAllowed, + DecodingFailed, ]; + // Four scenarios, 2 tests each: + // 1. Compare a `StatusCode`, which is converted from an encoded value, with a `StatusCode` + // converted from an `Error`. + // 2. Compare an `Error, which is converted from an encoded value, with the expected `Error`. for (i, &error_code) in UNIT_ERRORS.iter().enumerate() { - assert_eq!(into_pop_api_error([error_code, 0, 0, 0]), errors[i]); + // No nesting and unit variant correctly returned. + assert_eq!(into_status_code([error_code, 0, 0, 0]), errors[i].into()); + assert_eq!(into_error([error_code, 0, 0, 0]), errors[i]); + // Unexpected second byte nested. + assert_eq!( + into_status_code([error_code, 1, 0, 0]), + (Other { dispatch_error_index: error_code, error_index: 1, error: 0 }).into(), + ); assert_eq!( - into_pop_api_error([error_code, 1, 0, 0]), + into_error([error_code, 1, 0, 0]), Other { dispatch_error_index: error_code, error_index: 1, error: 0 }, ); + // Unexpected third byte nested. + assert_eq!( + into_status_code([error_code, 1, 1, 0]), + (Other { dispatch_error_index: error_code, error_index: 1, error: 1 }).into(), + ); assert_eq!( - into_pop_api_error([error_code, 1, 1, 0]), + into_error([error_code, 1, 1, 0]), Other { dispatch_error_index: error_code, error_index: 1, error: 1 }, ); + // Unexpected fourth byte nested. assert_eq!( - into_pop_api_error([error_code, 1, 1, 1]), + into_status_code([error_code, 1, 1, 1]), + (Other { dispatch_error_index: error_code, error_index: 1, error: 1 }).into(), + ); + assert_eq!( + into_error([error_code, 1, 1, 1]), Other { dispatch_error_index: error_code, error_index: 1, error: 1 }, ); } } + // Single nested variants: + // If the encoded value indicates a double nested `Error` which is known by the Pop API version + // as a single nested variant, the encoded value is converted into `Error::Other`. + // + // Example: the error `Arithmetic(Overflow)` (encoded: `[8, 1, 0, 0]`) with a non-zero + // value for one of the bytes [2..4]: `[8, 1, 1, 0]` is converted into `[0, 8, 1, 1]`. This is + // decoded to `Error::Other { dispatch_error: 8, index: 1, error: 1 }`. #[test] - fn test_single_nested_pop_api_error_variants() { + fn single_nested_error_variants() { let errors = vec![ [Token(FundsUnavailable), Token(OnlyProvider)], [Arithmetic(Underflow), Arithmetic(Overflow)], [Transactional(LimitReached), Transactional(NoLayer)], ]; + // Four scenarios, 2 tests each: + // 1. Compare a `StatusCode`, which is converted from an encoded value, with a `StatusCode` + // converted from an `Error`. + // 2. Compare an `Error, which is converted from an encoded value, with the expected `Error`. for (i, &error_code) in SINGLE_NESTED_ERRORS.iter().enumerate() { - assert_eq!(into_pop_api_error([error_code, 0, 0, 0]), errors[i][0]); - assert_eq!(into_pop_api_error([error_code, 1, 0, 0]), errors[i][1]); + // No nesting and unit variant correctly returned. + assert_eq!(into_status_code([error_code, 0, 0, 0]), errors[i][0].into()); + assert_eq!(into_error([error_code, 0, 0, 0]), errors[i][0]); + // Allowed single nesting variant correctly returned. + assert_eq!(into_status_code([error_code, 1, 0, 0]), errors[i][1].into()); + assert_eq!(into_error([error_code, 1, 0, 0]), errors[i][1]); + // Unexpected third byte nested. + assert_eq!( + into_status_code([error_code, 1, 1, 0]), + (Other { dispatch_error_index: error_code, error_index: 1, error: 1 }).into(), + ); assert_eq!( - into_pop_api_error([error_code, 1, 1, 0]), + into_error([error_code, 1, 1, 0]), Other { dispatch_error_index: error_code, error_index: 1, error: 1 }, ); + // Unexpected fourth byte nested. + assert_eq!( + into_status_code([error_code, 1, 1, 1]), + (Other { dispatch_error_index: error_code, error_index: 1, error: 1 }).into(), + ); assert_eq!( - into_pop_api_error([error_code, 1, 1, 1]), + into_error([error_code, 1, 1, 1]), Other { dispatch_error_index: error_code, error_index: 1, error: 1 }, ); } } + // Double nested variants: + // If the encoded value indicates a triple nested `Error` which is known by the Pop API version + // as a double nested variant, the encoded value is converted into `Error::Other`. + // + // Example: the error `Module { index: 10, error 5 }` (encoded: `[3, 10, 5, 0]`) with a non-zero + // value for the last byte: `[3, 10, 5, 3]` is converted into `[0, 3, 10, 5]`. This is + // decoded to `Error::Other { dispatch_error: 3, index: 10, error: 5 }`. #[test] - fn test_double_nested_pop_api_error_variants() { - assert_eq!(into_pop_api_error([3, 0, 0, 0]), Module { index: 0, error: 0 }); - assert_eq!(into_pop_api_error([3, 1, 0, 0]), Module { index: 1, error: 0 }); - assert_eq!(into_pop_api_error([3, 1, 1, 0]), Module { index: 1, error: 1 }); - // TODO: doesn't make sense. + fn double_nested_error_variants() { + // Four scenarios, 2 tests each: + // 1. Compare a `StatusCode`, which is converted from an encoded value, with a `StatusCode` + // converted from an `Error`. + // 2. Compare an `Error, which is converted from an encoded value, with the expected `Error`. + // + // No nesting and unit variant correctly returned. + assert_eq!(into_status_code([3, 0, 0, 0]), (Module { index: 0, error: 0 }).into()); + assert_eq!(into_error([3, 0, 0, 0]), Module { index: 0, error: 0 }); + // Allowed single nesting and variant correctly returned. + assert_eq!(into_status_code([3, 1, 0, 0]), (Module { index: 1, error: 0 }).into()); + assert_eq!(into_error([3, 1, 0, 0]), Module { index: 1, error: 0 }); + // Allowed double nesting and variant correctly returned. + assert_eq!(into_status_code([3, 1, 1, 0]), (Module { index: 1, error: 1 }).into()); + assert_eq!(into_error([3, 1, 1, 0]), Module { index: 1, error: 1 }); + // Unexpected fourth byte nested. assert_eq!( - into_pop_api_error([3, 1, 1, 1]), + into_status_code([3, 1, 1, 1]), + (Other { dispatch_error_index: 3, error_index: 1, error: 1 }).into(), + ); + assert_eq!( + into_error([3, 1, 1, 1]), Other { dispatch_error_index: 3, error_index: 1, error: 1 }, ); } - #[test] - fn test_decoding_failed() { - assert_eq!(into_pop_api_error([255, 0, 0, 0]), DecodingFailed); - assert_eq!(into_pop_api_error([255, 255, 0, 0]), DecodingFailed); - assert_eq!(into_pop_api_error([255, 255, 255, 0]), DecodingFailed); - assert_eq!(into_pop_api_error([255, 255, 255, 255]), DecodingFailed); - } - #[test] fn test_random_encoded_values() { assert_eq!( - into_pop_api_error([100, 100, 100, 100]), + into_error([100, 100, 100, 100]), Other { dispatch_error_index: 100, error_index: 100, error: 100 } ); assert_eq!( - into_pop_api_error([200, 200, 200, 200]), + into_error([200, 200, 200, 200]), Other { dispatch_error_index: 200, error_index: 200, error: 200 } ); } diff --git a/pop-api/src/lib.rs b/pop-api/src/lib.rs index 90c81998..3e9ead7f 100644 --- a/pop-api/src/lib.rs +++ b/pop-api/src/lib.rs @@ -3,7 +3,7 @@ use ink::{prelude::vec::Vec, ChainExtensionInstance}; pub use sp_runtime::{BoundedVec, MultiAddress, MultiSignature}; -use crate::error::{PopApiError, StatusCode}; +use crate::error::{Error, StatusCode}; use primitives::{storage_keys::*, AccountId as AccountId32}; #[cfg(feature = "assets")] pub use v0::assets; @@ -21,7 +21,11 @@ pub mod v0; type AccountId = AccountId32; // TODO: do the same as the AccountId above and check expanded macro code. -type Balance = ::Balance; +// type Balance = ::Balance; +type Balance = u128; +#[cfg(any(feature = "nfts", feature = "cross-chain"))] +type BlockNumber = ::BlockNumber; + pub type Result = core::result::Result; #[derive(Debug, Clone, PartialEq, Eq)] @@ -56,7 +60,7 @@ pub trait PopApi { #[cfg(feature = "cross-chain")] #[ink(function = 2)] #[allow(private_interfaces)] - fn send_xcm(xcm: CrossChainMessage) -> Result<()>; + fn send_xcm(xcm: primitives::cross_chain::CrossChainMessage) -> Result<()>; } fn dispatch(call: RuntimeCall) -> Result<()> { @@ -72,7 +76,7 @@ fn read_state(key: RuntimeStateKeys) -> Result> { } #[cfg(feature = "cross-chain")] -fn send_xcm(xcm: CrossChainMessage) -> Result<()> { +fn send_xcm(xcm: primitives::cross_chain::CrossChainMessage) -> Result<()> { <::ChainExtension as ChainExtensionInstance>::instantiate( ) .send_xcm(xcm) diff --git a/pop-api/src/primitives.rs b/pop-api/src/primitives.rs index e8098f69..e174a111 100644 --- a/pop-api/src/primitives.rs +++ b/pop-api/src/primitives.rs @@ -1,2 +1 @@ pub use pop_primitives::*; -pub use sp_runtime::{BoundedVec, MultiAddress}; diff --git a/pop-api/src/v0/assets/fungibles.rs b/pop-api/src/v0/assets/fungibles.rs index b1bb86a7..eaf1c6f5 100644 --- a/pop-api/src/v0/assets/fungibles.rs +++ b/pop-api/src/v0/assets/fungibles.rs @@ -356,3 +356,67 @@ impl From for FungiblesError { } } } + +#[cfg(test)] +mod tests { + use super::FungiblesError; + use crate::error::{ + ArithmeticError::*, + Error::{self, *}, + StatusCode, + TokenError::*, + TransactionalError::*, + }; + + fn into_fungibles_error(error: Error) -> FungiblesError { + let status_code: StatusCode = error.into(); + status_code.into() + } + + #[test] + fn conversion_status_code_into_fungibles_error_works() { + let errors = vec![ + Other { dispatch_error_index: 5, error_index: 5, error: 1 }, + CannotLookup, + BadOrigin, + Module { index: 2, error: 5 }, + ConsumerRemaining, + NoProviders, + TooManyConsumers, + Token(OnlyProvider), + Arithmetic(Overflow), + Transactional(NoLayer), + Exhausted, + Corruption, + Unavailable, + RootNotAllowed, + DecodingFailed, + ]; + for error in errors { + let status_code: StatusCode = error.into(); + let fungibles_error: FungiblesError = status_code.into(); + assert_eq!(fungibles_error, FungiblesError::Other(status_code)) + } + + assert_eq!(into_fungibles_error(Module { index: 10, error: 2 }), FungiblesError::NoBalance); + assert_eq!(into_fungibles_error(Module { index: 52, error: 0 }), FungiblesError::NoAccount); + assert_eq!( + into_fungibles_error(Module { index: 52, error: 1 }), + FungiblesError::NoPermission + ); + assert_eq!(into_fungibles_error(Module { index: 52, error: 2 }), FungiblesError::Unknown); + assert_eq!(into_fungibles_error(Module { index: 52, error: 3 }), FungiblesError::InUse); + assert_eq!( + into_fungibles_error(Module { index: 52, error: 5 }), + FungiblesError::MinBalanceZero + ); + assert_eq!( + into_fungibles_error(Module { index: 52, error: 7 }), + FungiblesError::InsufficientAllowance + ); + assert_eq!( + into_fungibles_error(Module { index: 52, error: 10 }), + FungiblesError::AssetNotLive + ); + } +} diff --git a/pop-api/src/v0/assets/mod.rs b/pop-api/src/v0/assets/mod.rs index 4ce68219..d67d30bd 100644 --- a/pop-api/src/v0/assets/mod.rs +++ b/pop-api/src/v0/assets/mod.rs @@ -1,8 +1,8 @@ #![allow(dead_code)] -use crate::{Balance, RuntimeCall, *}; +use crate::{Balance, MultiAddress, RuntimeCall, *}; use ink::prelude::vec::Vec; -use primitives::{AssetId, MultiAddress}; +use primitives::AssetId; use scale::{Compact, Encode}; pub mod fungibles; @@ -13,7 +13,7 @@ type Result = core::result::Result; /// 1. Dispatchables /// 2. Read state functions /// -/// 1. Dispatchables within pallet assets (TrustBackedAssets instance) that can be used via the pop api on Pop Network: +/// 1. Dispatchables within pallet assets (TrustBackedAssets instance): /// - create /// - start_destroy /// - destroy_accounts @@ -464,7 +464,7 @@ pub enum AssetsError { } impl TryFrom for AssetsError { - type Error = PopApiError; + type Error = Error; fn try_from(status_code: u32) -> core::result::Result { use AssetsError::*; diff --git a/pop-api/src/v0/balances.rs b/pop-api/src/v0/balances.rs index ae2709e7..e14e6e32 100644 --- a/pop-api/src/v0/balances.rs +++ b/pop-api/src/v0/balances.rs @@ -1,6 +1,4 @@ -use crate::{ - dispatch, primitives::MultiAddress, v0::RuntimeCall, AccountId, PopApiError, StatusCode, -}; +use crate::{dispatch, primitives::MultiAddress, v0::RuntimeCall, AccountId, Error, StatusCode}; type Result = core::result::Result; @@ -57,7 +55,7 @@ pub enum BalancesError { } impl TryFrom for BalancesError { - type Error = PopApiError; + type Error = Error; fn try_from(status_code: u32) -> core::result::Result { use BalancesError::*; diff --git a/pop-api/src/v0/cross_chain/mod.rs b/pop-api/src/v0/cross_chain/mod.rs index 583447b1..5a0dda6c 100644 --- a/pop-api/src/v0/cross_chain/mod.rs +++ b/pop-api/src/v0/cross_chain/mod.rs @@ -1,11 +1,8 @@ -pub mod coretime; - -use crate::StatusCode; +use crate::{BlockNumber, ParachainSystemKeys, Result, RuntimeStateKeys}; -type Result = core::result::Result; -type BlockNumber = ::BlockNumber; +pub mod coretime; -pub fn relay_chain_block_number() -> std::result::Result { +pub fn relay_chain_block_number() -> Result { crate::v0::state::read(RuntimeStateKeys::ParachainSystem( ParachainSystemKeys::LastRelayChainBlockNumber, )) diff --git a/pop-api/src/v0/mod.rs b/pop-api/src/v0/mod.rs index 41574cfb..20dc6476 100644 --- a/pop-api/src/v0/mod.rs +++ b/pop-api/src/v0/mod.rs @@ -10,12 +10,12 @@ pub mod state; #[derive(scale::Encode)] pub(crate) enum RuntimeCall { - // #[codec(index = 10)] - // #[cfg(feature = "balances")] - // Balances(balances::BalancesCall), - // #[codec(index = 50)] - // #[cfg(feature = "nfts")] - // Nfts(nfts::NftCalls), + #[codec(index = 10)] + #[cfg(feature = "balances")] + Balances(balances::BalancesCall), + #[codec(index = 50)] + #[cfg(feature = "nfts")] + Nfts(nfts::NftCalls), #[codec(index = 52)] #[cfg(feature = "assets")] Assets(assets::AssetsCall), diff --git a/pop-api/src/v0/nfts.rs b/pop-api/src/v0/nfts.rs index 1e4406e5..29219c66 100644 --- a/pop-api/src/v0/nfts.rs +++ b/pop-api/src/v0/nfts.rs @@ -1,9 +1,15 @@ -use super::RuntimeCall; -use crate::*; use ink::prelude::vec::Vec; -use primitives::{ApprovalsLimit, BoundedBTreeMap, KeyLimit, MultiAddress}; -pub use primitives::{CollectionId, ItemId}; use scale::Encode; + +use crate::{ + dispatch, + primitives::{ + nfts::{ApprovalsLimit, CollectionId, ItemId, KeyLimit}, + BoundedBTreeMap, + }, + state, AccountId, Balance, BlockNumber, BoundedVec, MultiAddress, NftsKeys, RuntimeCall, + RuntimeStateKeys, StatusCode, +}; pub use types::*; type Result = core::result::Result; @@ -515,163 +521,163 @@ pub(crate) enum NftCalls { receive_item: ItemId, }, } - -#[derive(Debug, Copy, Clone, PartialEq, Eq, Encode, scale::Decode)] -#[cfg_attr(feature = "std", derive(scale_info::TypeInfo))] -pub enum Error { - /// The signing account has no permission to do the operation. - NoPermission, - /// The given item ID is unknown. - UnknownCollection, - /// The item ID has already been used for an item. - AlreadyExists, - /// The approval had a deadline that expired, so the approval isn't valid anymore. - ApprovalExpired, - /// The owner turned out to be different to what was expected. - WrongOwner, - /// The witness data given does not match the current state of the chain. - BadWitness, - /// Collection ID is already taken. - CollectionIdInUse, - /// Items within that collection are non-transferable. - ItemsNonTransferable, - /// The provided account is not a delegate. - NotDelegate, - /// The delegate turned out to be different to what was expected. - WrongDelegate, - /// No approval exists that would allow the transfer. - Unapproved, - /// The named owner has not signed ownership acceptance of the collection. - Unaccepted, - /// The item is locked (non-transferable). - ItemLocked, - /// Item's attributes are locked. - LockedItemAttributes, - /// Collection's attributes are locked. - LockedCollectionAttributes, - /// Item's metadata is locked. - LockedItemMetadata, - /// Collection's metadata is locked. - LockedCollectionMetadata, - /// All items have been minted. - MaxSupplyReached, - /// The max supply is locked and can't be changed. - MaxSupplyLocked, - /// The provided max supply is less than the number of items a collection already has. - MaxSupplyTooSmall, - /// The given item ID is unknown. - UnknownItem, - /// Swap doesn't exist. - UnknownSwap, - /// The given item has no metadata set. - MetadataNotFound, - /// The provided attribute can't be found. - AttributeNotFound, - /// Item is not for sale. - NotForSale, - /// The provided bid is too low. - BidTooLow, - /// The item has reached its approval limit. - ReachedApprovalLimit, - /// The deadline has already expired. - DeadlineExpired, - /// The duration provided should be less than or equal to `MaxDeadlineDuration`. - WrongDuration, - /// The method is disabled by system settings. - MethodDisabled, - /// The provided setting can't be set. - WrongSetting, - /// Item's config already exists and should be equal to the provided one. - InconsistentItemConfig, - /// Config for a collection or an item can't be found. - NoConfig, - /// Some roles were not cleared. - RolesNotCleared, - /// Mint has not started yet. - MintNotStarted, - /// Mint has already ended. - MintEnded, - /// The provided Item was already used for claiming. - AlreadyClaimed, - /// The provided data is incorrect. - IncorrectData, - /// The extrinsic was sent by the wrong origin. - WrongOrigin, - /// The provided signature is incorrect. - WrongSignature, - /// The provided metadata might be too long. - IncorrectMetadata, - /// Can't set more attributes per one call. - MaxAttributesLimitReached, - /// The provided namespace isn't supported in this call. - WrongNamespace, - /// Can't delete non-empty collections. - CollectionNotEmpty, - /// The witness data should be provided. - WitnessRequired, -} - -impl TryFrom for Error { - type Error = Error; - - fn try_from(status_code: u32) -> core::result::Result { - use Error::*; - match status_code { - 0 => Ok(NoPermission), - 1 => Ok(UnknownCollection), - 2 => Ok(AlreadyExists), - 3 => Ok(ApprovalExpired), - 4 => Ok(WrongOwner), - 5 => Ok(BadWitness), - 6 => Ok(CollectionIdInUse), - 7 => Ok(ItemsNonTransferable), - 8 => Ok(NotDelegate), - 9 => Ok(WrongDelegate), - 10 => Ok(Unapproved), - 11 => Ok(Unaccepted), - 12 => Ok(ItemLocked), - 13 => Ok(LockedItemAttributes), - 14 => Ok(LockedCollectionAttributes), - 15 => Ok(LockedItemMetadata), - 16 => Ok(LockedCollectionMetadata), - 17 => Ok(MaxSupplyReached), - 18 => Ok(MaxSupplyLocked), - 19 => Ok(MaxSupplyTooSmall), - 20 => Ok(UnknownItem), - 21 => Ok(UnknownSwap), - 22 => Ok(MetadataNotFound), - 23 => Ok(AttributeNotFound), - 24 => Ok(NotForSale), - 25 => Ok(BidTooLow), - 26 => Ok(ReachedApprovalLimit), - 27 => Ok(DeadlineExpired), - 28 => Ok(WrongDuration), - 29 => Ok(MethodDisabled), - 30 => Ok(WrongSetting), - 31 => Ok(InconsistentItemConfig), - 32 => Ok(NoConfig), - 33 => Ok(RolesNotCleared), - 34 => Ok(MintNotStarted), - 35 => Ok(MintEnded), - 36 => Ok(AlreadyClaimed), - 37 => Ok(IncorrectData), - 38 => Ok(WrongOrigin), - 39 => Ok(WrongSignature), - 40 => Ok(IncorrectMetadata), - 41 => Ok(MaxAttributesLimitReached), - 42 => Ok(WrongNamespace), - 43 => Ok(CollectionNotEmpty), - 44 => Ok(WitnessRequired), - _ => todo!(), - } - } -} +// +// #[derive(Debug, Copy, Clone, PartialEq, Eq, Encode, scale::Decode)] +// #[cfg_attr(feature = "std", derive(scale_info::TypeInfo))] +// pub enum Error { +// /// The signing account has no permission to do the operation. +// NoPermission, +// /// The given item ID is unknown. +// UnknownCollection, +// /// The item ID has already been used for an item. +// AlreadyExists, +// /// The approval had a deadline that expired, so the approval isn't valid anymore. +// ApprovalExpired, +// /// The owner turned out to be different to what was expected. +// WrongOwner, +// /// The witness data given does not match the current state of the chain. +// BadWitness, +// /// Collection ID is already taken. +// CollectionIdInUse, +// /// Items within that collection are non-transferable. +// ItemsNonTransferable, +// /// The provided account is not a delegate. +// NotDelegate, +// /// The delegate turned out to be different to what was expected. +// WrongDelegate, +// /// No approval exists that would allow the transfer. +// Unapproved, +// /// The named owner has not signed ownership acceptance of the collection. +// Unaccepted, +// /// The item is locked (non-transferable). +// ItemLocked, +// /// Item's attributes are locked. +// LockedItemAttributes, +// /// Collection's attributes are locked. +// LockedCollectionAttributes, +// /// Item's metadata is locked. +// LockedItemMetadata, +// /// Collection's metadata is locked. +// LockedCollectionMetadata, +// /// All items have been minted. +// MaxSupplyReached, +// /// The max supply is locked and can't be changed. +// MaxSupplyLocked, +// /// The provided max supply is less than the number of items a collection already has. +// MaxSupplyTooSmall, +// /// The given item ID is unknown. +// UnknownItem, +// /// Swap doesn't exist. +// UnknownSwap, +// /// The given item has no metadata set. +// MetadataNotFound, +// /// The provided attribute can't be found. +// AttributeNotFound, +// /// Item is not for sale. +// NotForSale, +// /// The provided bid is too low. +// BidTooLow, +// /// The item has reached its approval limit. +// ReachedApprovalLimit, +// /// The deadline has already expired. +// DeadlineExpired, +// /// The duration provided should be less than or equal to `MaxDeadlineDuration`. +// WrongDuration, +// /// The method is disabled by system settings. +// MethodDisabled, +// /// The provided setting can't be set. +// WrongSetting, +// /// Item's config already exists and should be equal to the provided one. +// InconsistentItemConfig, +// /// Config for a collection or an item can't be found. +// NoConfig, +// /// Some roles were not cleared. +// RolesNotCleared, +// /// Mint has not started yet. +// MintNotStarted, +// /// Mint has already ended. +// MintEnded, +// /// The provided Item was already used for claiming. +// AlreadyClaimed, +// /// The provided data is incorrect. +// IncorrectData, +// /// The extrinsic was sent by the wrong origin. +// WrongOrigin, +// /// The provided signature is incorrect. +// WrongSignature, +// /// The provided metadata might be too long. +// IncorrectMetadata, +// /// Can't set more attributes per one call. +// MaxAttributesLimitReached, +// /// The provided namespace isn't supported in this call. +// WrongNamespace, +// /// Can't delete non-empty collections. +// CollectionNotEmpty, +// /// The witness data should be provided. +// WitnessRequired, +// } +// +// impl TryFrom for Error { +// type Error = Error; +// +// fn try_from(status_code: u32) -> core::result::Result { +// use Error::*; +// match status_code { +// 0 => Ok(NoPermission), +// 1 => Ok(UnknownCollection), +// 2 => Ok(AlreadyExists), +// 3 => Ok(ApprovalExpired), +// 4 => Ok(WrongOwner), +// 5 => Ok(BadWitness), +// 6 => Ok(CollectionIdInUse), +// 7 => Ok(ItemsNonTransferable), +// 8 => Ok(NotDelegate), +// 9 => Ok(WrongDelegate), +// 10 => Ok(Unapproved), +// 11 => Ok(Unaccepted), +// 12 => Ok(ItemLocked), +// 13 => Ok(LockedItemAttributes), +// 14 => Ok(LockedCollectionAttributes), +// 15 => Ok(LockedItemMetadata), +// 16 => Ok(LockedCollectionMetadata), +// 17 => Ok(MaxSupplyReached), +// 18 => Ok(MaxSupplyLocked), +// 19 => Ok(MaxSupplyTooSmall), +// 20 => Ok(UnknownItem), +// 21 => Ok(UnknownSwap), +// 22 => Ok(MetadataNotFound), +// 23 => Ok(AttributeNotFound), +// 24 => Ok(NotForSale), +// 25 => Ok(BidTooLow), +// 26 => Ok(ReachedApprovalLimit), +// 27 => Ok(DeadlineExpired), +// 28 => Ok(WrongDuration), +// 29 => Ok(MethodDisabled), +// 30 => Ok(WrongSetting), +// 31 => Ok(InconsistentItemConfig), +// 32 => Ok(NoConfig), +// 33 => Ok(RolesNotCleared), +// 34 => Ok(MintNotStarted), +// 35 => Ok(MintEnded), +// 36 => Ok(AlreadyClaimed), +// 37 => Ok(IncorrectData), +// 38 => Ok(WrongOrigin), +// 39 => Ok(WrongSignature), +// 40 => Ok(IncorrectMetadata), +// 41 => Ok(MaxAttributesLimitReached), +// 42 => Ok(WrongNamespace), +// 43 => Ok(CollectionNotEmpty), +// 44 => Ok(WitnessRequired), +// _ => todo!(), +// } +// } +// } // Local implementations of pallet-nfts types mod types { use super::*; use crate::{ - primitives::{CollectionId, ItemId}, + primitives::nfts::{CollectionId, ItemId}, Balance, BlockNumber, }; pub use enumflags2::{bitflags, BitFlags}; diff --git a/pop-api/src/v0/state.rs b/pop-api/src/v0/state.rs index 1aca01cf..e3d38129 100644 --- a/pop-api/src/v0/state.rs +++ b/pop-api/src/v0/state.rs @@ -1,7 +1,6 @@ -use crate::{primitives::storage_keys::RuntimeStateKeys, read_state, PopApiError}; +use crate::{primitives::storage_keys::RuntimeStateKeys, read_state, Error}; use scale::Decode; pub fn read(key: RuntimeStateKeys) -> crate::Result { - read_state(key) - .and_then(|v| T::decode(&mut &v[..]).map_err(|_e| PopApiError::DecodingFailed.into())) + read_state(key).and_then(|v| T::decode(&mut &v[..]).map_err(|_e| Error::DecodingFailed.into())) } diff --git a/primitives/Cargo.toml b/primitives/Cargo.toml index e7237b51..6ba3fea7 100644 --- a/primitives/Cargo.toml +++ b/primitives/Cargo.toml @@ -22,4 +22,7 @@ std = [ "scale-info/std", ] devnet = [] -testnet = [] \ No newline at end of file +testnet = [] +assets = [] +cross-chain = [] +nfts = [] diff --git a/primitives/src/lib.rs b/primitives/src/lib.rs index 1e008c31..3b91f713 100644 --- a/primitives/src/lib.rs +++ b/primitives/src/lib.rs @@ -1,10 +1,11 @@ #![cfg_attr(not(feature = "std"), no_std, no_main)] -pub use bounded_collections::{BoundedBTreeMap, BoundedBTreeSet, BoundedVec, ConstU32}; +pub use bounded_collections::{BoundedBTreeMap, BoundedBTreeSet, BoundedVec}; use scale::{Decode, Encode, MaxEncodedLen}; #[cfg(feature = "std")] use {scale_decode::DecodeAsType, scale_encode::EncodeAsType, scale_info::TypeInfo}; +#[cfg(feature = "cross-chain")] pub mod cross_chain; pub mod storage_keys; @@ -14,11 +15,17 @@ pub struct AccountId(pub [u8; 32]); // Identifier for the class of asset. pub type AssetId = u32; -// Id used for identifying non-fungible collections. -pub type CollectionId = u32; -// Id used for identifying non-fungible items. -pub type ItemId = u32; -/// The maximum length of an attribute key. -pub type KeyLimit = ConstU32<64>; -/// The maximum approvals an item could have. -pub type ApprovalsLimit = ConstU32<20>; + +#[cfg(feature = "nfts")] +pub mod nfts { + use bounded_collections::ConstU32; + + // Id used for identifying non-fungible collections. + pub type CollectionId = u32; + // Id used for identifying non-fungible items. + pub type ItemId = u32; + /// The maximum length of an attribute key. + pub type KeyLimit = ConstU32<64>; + /// The maximum approvals an item could have. + pub type ApprovalsLimit = ConstU32<20>; +} diff --git a/primitives/src/storage_keys.rs b/primitives/src/storage_keys.rs index fc7234aa..4be95986 100644 --- a/primitives/src/storage_keys.rs +++ b/primitives/src/storage_keys.rs @@ -1,13 +1,18 @@ +#[cfg(feature = "nfts")] +use super::nfts::*; use super::*; #[derive(Encode, Decode, Debug, MaxEncodedLen)] pub enum RuntimeStateKeys { + #[cfg(feature = "nfts")] Nfts(NftsKeys), + #[cfg(feature = "cross-chain")] ParachainSystem(ParachainSystemKeys), - #[cfg(feature = "devnet")] + #[cfg(feature = "assets")] Assets(AssetsKeys), } +#[cfg(feature = "cross-chain")] #[derive(Encode, Decode, Debug, MaxEncodedLen)] pub enum ParachainSystemKeys { /// Get the last relay chain block number seen by the parachain. @@ -15,6 +20,7 @@ pub enum ParachainSystemKeys { } // https://github.com/paritytech/polkadot-sdk/blob/master/substrate/frame/nfts/src/impl_nonfungibles.rs +#[cfg(feature = "nfts")] #[derive(Encode, Decode, Debug, MaxEncodedLen)] pub enum NftsKeys { // Get the details of a collection. @@ -34,7 +40,7 @@ pub enum NftsKeys { } /// The required input for state queries in pallet assets. -#[cfg(feature = "devnet")] +#[cfg(feature = "assets")] #[derive(Encode, Decode, Debug, MaxEncodedLen)] pub enum AssetsKeys { Allowance(AssetId, AccountId, AccountId), diff --git a/runtime/devnet/Cargo.toml b/runtime/devnet/Cargo.toml index daa5457e..b72bf4f7 100644 --- a/runtime/devnet/Cargo.toml +++ b/runtime/devnet/Cargo.toml @@ -22,7 +22,7 @@ scale-info.workspace = true smallvec.workspace = true # Local -pop-primitives = { workspace = true, default-features = false, features = ["devnet"] } +pop-primitives = { workspace = true, default-features = false, features = ["assets", "cross-chain", "nfts"] } pop-runtime-common = { workspace = true, default-features = false } # Substrate @@ -91,7 +91,7 @@ parachain-info.workspace = true env_logger = "0.11.2" hex = "0.4.3" enumflags2 = "0.7.9" -pop-api = { path = "../../pop-api", defeult-features = false, features = ["assets"] } +pop-api = { path = "../../pop-api", features = ["assets", "cross-chain", "nfts"] } [features] default = ["std"] diff --git a/runtime/devnet/src/extensions.rs b/runtime/devnet/src/extensions.rs index b4c6ba84..9db31e83 100644 --- a/runtime/devnet/src/extensions.rs +++ b/runtime/devnet/src/extensions.rs @@ -11,11 +11,6 @@ use frame_support::{ use pallet_contracts::chain_extension::{ BufInBufOutState, ChainExtension, ChargedAmount, Environment, Ext, InitState, RetVal, }; -use pop_primitives::{ - cross_chain::CrossChainMessage, - storage_keys::{AssetsKeys, NftsKeys, ParachainSystemKeys, RuntimeStateKeys}, - AssetId, CollectionId, ItemId, -}; use sp_core::crypto::UncheckedFrom; use sp_runtime::traits::{BlockNumberProvider, Dispatchable}; use sp_std::{boxed::Box, vec::Vec}; @@ -25,9 +20,15 @@ use xcm::{ }; use crate::{ - config::assets::TrustBackedAssetsInstance, AccountId, AllowedPopApiCalls, RuntimeCall, + config::assets::TrustBackedAssetsInstance, AccountId, AllowedApiCalls, RuntimeCall, RuntimeOrigin, UNIT, }; +use pop_primitives::{ + cross_chain::CrossChainMessage, + nfts::{CollectionId, ItemId}, + storage_keys::{AssetsKeys, NftsKeys, ParachainSystemKeys, RuntimeStateKeys}, + AssetId, +}; const LOG_TARGET: &str = "pop-api::extension"; @@ -122,7 +123,7 @@ where log::debug!(target:LOG_TARGET, "{} Inputted RuntimeCall: {:?}", log_prefix, call); - origin.add_filter(AllowedPopApiCalls::contains); + origin.add_filter(AllowedApiCalls::contains); match call.dispatch(origin) { Ok(info) => { @@ -222,7 +223,7 @@ where RuntimeStateKeys::ParachainSystem(key) => { read_parachain_system_state::(key, &mut env) }, - RuntimeStateKeys::Assets(key) => read_trust_backed_assets_state::(key, &mut env), + RuntimeStateKeys::Assets(key) => read_assets_state::(key, &mut env), }? .encode(); @@ -299,7 +300,7 @@ where } } -fn read_trust_backed_assets_state( +fn read_assets_state( key: AssetsKeys, env: &mut Environment, ) -> Result, DispatchError> diff --git a/runtime/devnet/src/lib.rs b/runtime/devnet/src/lib.rs index 416a3298..b03bdac6 100644 --- a/runtime/devnet/src/lib.rs +++ b/runtime/devnet/src/lib.rs @@ -253,8 +253,8 @@ impl Contains for FilteredCalls { } /// A type to identify allowed calls to the Runtime from contracts. Used by Pop API -pub struct AllowedPopApiCalls; -impl Contains for crate::AllowedPopApiCalls { +pub struct AllowedApiCalls; +impl Contains for crate::AllowedApiCalls { fn contains(c: &RuntimeCall) -> bool { use config::assets::AssetsCall; use pallet_nfts::Call as NftsCall; diff --git a/runtime/devnet/src/tests/local_fungibles.rs b/runtime/devnet/src/tests/local_fungibles.rs index 154e9897..ac2b8ca0 100644 --- a/runtime/devnet/src/tests/local_fungibles.rs +++ b/runtime/devnet/src/tests/local_fungibles.rs @@ -9,8 +9,8 @@ use super::*; use pop_api::{ - error::{ArithmeticError::*, PopApiError::*, TokenError::*}, - v0::assets::use_cases::fungibles::FungiblesError::*, + error::{ArithmeticError::*, Error::*, TokenError::*}, + v0::assets::fungibles::FungiblesError::*, }; const ASSET_ID: AssetId = 1; @@ -268,7 +268,7 @@ fn create_works() { instantiate("../../pop-api/examples/fungibles/target/ink/fungibles.wasm", 0, vec![0]); // No balance to pay for fees. assert_eq!( - decoded::(create(addr.clone(), ASSET_ID, addr.clone(), 1)), + decoded::(create(addr.clone(), ASSET_ID, addr.clone(), 1)), Module { index: 10, error: 2 }, ); // Instantiate a contract without balance (relay token). @@ -277,7 +277,7 @@ fn create_works() { // TODO: make sure it has enough for the fees but not for the deposit. // No balance to pay fe deposit. assert_eq!( - decoded::(create(addr.clone(), ASSET_ID, addr.clone(), 1)), + decoded::(create(addr.clone(), ASSET_ID, addr.clone(), 1)), Module { index: 10, error: 2 }, ); // Instantiate a contract with balance. @@ -289,12 +289,12 @@ fn create_works() { create_asset(ALICE, ASSET_ID, 1); // Asset ID is already taken. assert_eq!( - decoded::(create(addr.clone(), ASSET_ID, BOB, 1)), + decoded::(create(addr.clone(), ASSET_ID, BOB, 1)), Module { index: 52, error: 5 }, ); // The minimal balance for an asset must be non zero. assert_eq!( - decoded::(create(addr.clone(), new_asset, BOB, 0)), + decoded::(create(addr.clone(), new_asset, BOB, 0)), Module { index: 52, error: 7 }, ); let result = create(addr.clone(), new_asset, BOB, 1); @@ -333,39 +333,25 @@ fn transfer_from_mint_works() { // Asset does not exist. assert_eq!( - decoded::(transfer_from(addr.clone(), 1, None, Some(BOB), amount, &[0u8])), + decoded::(transfer_from(addr.clone(), 1, None, Some(BOB), amount, &[0u8])), Token(UnknownAsset) ); let asset = create_asset(ALICE, 1, 2); // Minting can only be done by the owner. assert_eq!( - decoded::(transfer_from( - addr.clone(), - asset, - None, - Some(BOB), - amount, - &[0u8] - )), + decoded::(transfer_from(addr.clone(), asset, None, Some(BOB), amount, &[0u8])), Module { index: 52, error: 2 }, ); // Minimum balance of an asset can not be zero. assert_eq!( - decoded::(transfer_from(addr.clone(), asset, None, Some(BOB), 1, &[0u8])), + decoded::(transfer_from(addr.clone(), asset, None, Some(BOB), 1, &[0u8])), Token(BelowMinimum) ); let asset = create_asset(addr.clone(), 2, 2); // Asset is not live, i.e. frozen or being destroyed. freeze_asset(asset, addr.clone()); assert_eq!( - decoded::(transfer_from( - addr.clone(), - asset, - None, - Some(BOB), - amount, - &[0u8] - )), + decoded::(transfer_from(addr.clone(), asset, None, Some(BOB), amount, &[0u8])), Module { index: 52, error: 16 }, ); thaw_asset(asset, addr.clone()); @@ -377,7 +363,7 @@ fn transfer_from_mint_works() { assert_eq!(bob_balance_after_mint, bob_balance_before_mint + amount); // Can not mint more tokens than Balance::MAX. assert_eq!( - decoded::(transfer_from( + decoded::(transfer_from( addr.clone(), asset, None, @@ -390,14 +376,7 @@ fn transfer_from_mint_works() { // Asset is not live, i.e. frozen or being destroyed. start_destroy_asset(asset, addr.clone()); assert_eq!( - decoded::(transfer_from( - addr.clone(), - asset, - None, - Some(BOB), - amount, - &[0u8] - )), + decoded::(transfer_from(addr.clone(), asset, None, Some(BOB), amount, &[0u8])), Module { index: 52, error: 16 }, ); }); @@ -417,7 +396,7 @@ fn transfer_works() { // Asset does not exist. assert_eq!( - decoded::(transfer(addr.clone(), 1, BOB, amount,)), + decoded::(transfer(addr.clone(), 1, BOB, amount,)), Module { index: 52, error: 3 }, ); // Create asset with Alice as owner and mint `amount` to contract address. @@ -425,18 +404,18 @@ fn transfer_works() { // Asset is not live, i.e. frozen or being destroyed. freeze_asset(asset, ALICE); assert_eq!( - decoded::(transfer(addr.clone(), asset, BOB, amount,)), + decoded::(transfer(addr.clone(), asset, BOB, amount,)), Module { index: 52, error: 16 }, ); thaw_asset(asset, ALICE); // Not enough balance. assert_eq!( - decoded::(transfer(addr.clone(), asset, BOB, amount + 1 * UNIT)), + decoded::(transfer(addr.clone(), asset, BOB, amount + 1 * UNIT)), Module { index: 52, error: 0 }, ); // Not enough balance due to ED. assert_eq!( - decoded::(transfer(addr.clone(), asset, BOB, amount)), + decoded::(transfer(addr.clone(), asset, BOB, amount)), Module { index: 52, error: 0 }, ); // Successful transfer. @@ -447,13 +426,13 @@ fn transfer_works() { assert_eq!(bob_balance_after_mint, bob_balance_before_mint + amount / 2); // Transfer asset to account that does not exist. assert_eq!( - decoded::(transfer(addr.clone(), asset, FERDIE, amount / 4)), + decoded::(transfer(addr.clone(), asset, FERDIE, amount / 4)), Token(CannotCreate) ); // Asset is not live, i.e. frozen or being destroyed. start_destroy_asset(asset, ALICE); assert_eq!( - decoded::(transfer(addr.clone(), asset, BOB, amount / 4)), + decoded::(transfer(addr.clone(), asset, BOB, amount / 4)), Module { index: 52, error: 16 }, ); }); diff --git a/runtime/devnet/src/tests/mod.rs b/runtime/devnet/src/tests/mod.rs index dcb97ae1..828aa06b 100644 --- a/runtime/devnet/src/tests/mod.rs +++ b/runtime/devnet/src/tests/mod.rs @@ -1,16 +1,13 @@ #![cfg(test)] -use crate::{ - config::assets::TrustBackedAssetsInstance, Assets, Contracts, Runtime, RuntimeOrigin, System, - Weight, UNIT, -}; use codec::{Decode, Encode}; use frame_support::traits::fungibles::{approvals::Inspect as ApprovalInspect, Inspect}; use frame_system::Config; use pallet_contracts::{Code, CollectEvents, Determinism, ExecReturnValue}; -use pop_api::error::{ArithmeticError, PopApiError, TokenError, TransactionalError}; use sp_runtime::{traits::Hash, AccountId32, BuildStorage, DispatchError}; +use crate::{Assets, Contracts, Runtime, RuntimeOrigin, System, Weight, UNIT}; + mod local_fungibles; type Balance = u128; @@ -97,166 +94,174 @@ fn instantiate(contract: &str, init_value: u128, salt: Vec) -> AccountId32 { result.account_id } -pub fn get_pallet_index() -> u8 { - // Get the index of the pallet (module) - <::PalletInfo as frame_support::traits::PalletInfo>::index::() - .expect("Every active module has an index in the runtime; qed") as u8 -} - -#[test] -fn encoding_decoding_dispatch_error() { - use codec::{Decode, Encode}; - use sp_runtime::{ArithmeticError, DispatchError, ModuleError, TokenError}; +mod encoding { + use super::*; + use crate::config::assets::TrustBackedAssetsInstance; + use crate::Runtime; + use sp_runtime::DispatchError; - new_test_ext().execute_with(|| { - let error = DispatchError::Module(ModuleError { - index: 255, - error: [2, 0, 0, 0], - message: Some("error message"), - }); - let encoded = error.encode(); - let decoded = DispatchError::decode(&mut &encoded[..]).unwrap(); - assert_eq!(encoded, vec![3, 255, 2, 0, 0, 0]); - assert_eq!( - decoded, - // `message` is skipped for encoding. - DispatchError::Module(ModuleError { index: 255, error: [2, 0, 0, 0], message: None }) - ); - println!("Encoded Module Error: {:?}", encoded); + #[test] + fn encoding_decoding_dispatch_error() { + use codec::{Decode, Encode}; + use sp_runtime::{ArithmeticError, DispatchError, ModuleError, TokenError}; - // Example pallet assets Error into ModuleError - let index = get_pallet_index::(); - let mut error = - pallet_assets::Error::NotFrozen::.encode(); - error.resize(sp_runtime::MAX_MODULE_ERROR_ENCODED_SIZE, 0); - let message = None; - let error = DispatchError::Module(ModuleError { - index, - error: TryInto::try_into(error).expect("should work"), - message, - }); - let encoded = error.encode(); - let decoded = DispatchError::decode(&mut &encoded[..]).unwrap(); - assert_eq!(encoded, vec![3, 52, 18, 0, 0, 0]); - assert_eq!( - decoded, - DispatchError::Module(ModuleError { index: 52, error: [18, 0, 0, 0], message: None }) - ); - println!("Encoded Module Error: {:?}", encoded); + new_test_ext().execute_with(|| { + let error = DispatchError::Module(ModuleError { + index: 255, + error: [2, 0, 0, 0], + message: Some("error message"), + }); + let encoded = error.encode(); + let decoded = DispatchError::decode(&mut &encoded[..]).unwrap(); + assert_eq!(encoded, vec![3, 255, 2, 0, 0, 0]); + assert_eq!( + decoded, + // `message` is skipped for encoding. + DispatchError::Module(ModuleError { + index: 255, + error: [2, 0, 0, 0], + message: None + }) + ); + println!("Encoded Module Error: {:?}", encoded); - // Example DispatchError::Token - let error = DispatchError::Token(TokenError::UnknownAsset); - let encoded = error.encode(); - assert_eq!(encoded, vec![7, 4]); - println!("Encoded Token Error: {:?}", encoded); + // Example pallet assets Error into ModuleError. + let index = + <::PalletInfo as frame_support::traits::PalletInfo>::index::< + Assets, + >() + .expect("Every active module has an index in the runtime; qed") as u8; - // Example DispatchError::Arithmetic - let error = DispatchError::Arithmetic(ArithmeticError::Overflow); - let encoded = error.encode(); - assert_eq!(encoded, vec![8, 1]); - println!("Encoded Arithmetic Error: {:?}", encoded); - }); -} + let mut error = + pallet_assets::Error::NotFrozen::.encode(); + error.resize(sp_runtime::MAX_MODULE_ERROR_ENCODED_SIZE, 0); + let error = DispatchError::Module(ModuleError { + index, + error: TryInto::try_into(error).expect("should work"), + message: None, + }); + let encoded = error.encode(); + let decoded = DispatchError::decode(&mut &encoded[..]).unwrap(); + assert_eq!(encoded, vec![3, 52, 18, 0, 0, 0]); + assert_eq!( + decoded, + DispatchError::Module(ModuleError { + index: 52, + error: [18, 0, 0, 0], + message: None + }) + ); + println!("Encoded Module Error: {:?}", encoded); -#[test] -fn encoding_of_enum() { - use codec::{Decode, Encode}; + // Example DispatchError::Token + let error = DispatchError::Token(TokenError::UnknownAsset); + let encoded = error.encode(); + assert_eq!(encoded, vec![7, 4]); + println!("Encoded Token Error: {:?}", encoded); - // Comprehensive enum with all different type of variants. - #[derive(Debug, PartialEq, Encode, Decode)] - enum ComprehensiveEnum { - SimpleVariant, - DataVariant(u8), - NamedFields { w: u8 }, - NestedEnum(InnerEnum), - OptionVariant(Option), - VecVariant(Vec), - TupleVariant(u8, u8), - NestedStructVariant(NestedStruct), - NestedEnumStructVariant(NestedEnumStruct), + // Example DispatchError::Arithmetic + let error = DispatchError::Arithmetic(ArithmeticError::Overflow); + let encoded = error.encode(); + assert_eq!(encoded, vec![8, 1]); + println!("Encoded Arithmetic Error: {:?}", encoded); + }); } - #[derive(Debug, PartialEq, Encode, Decode)] - enum InnerEnum { - A, - B { inner_data: u8 }, - C(u8), - } + #[test] + fn encoding_of_enum() { + use codec::{Decode, Encode}; - #[derive(Debug, PartialEq, Encode, Decode)] - struct NestedStruct { - x: u8, - y: u8, - } + // Comprehensive enum with all different type of variants. + #[derive(Debug, PartialEq, Encode, Decode)] + enum ComprehensiveEnum { + SimpleVariant, + DataVariant(u8), + NamedFields { w: u8 }, + NestedEnum(InnerEnum), + OptionVariant(Option), + VecVariant(Vec), + TupleVariant(u8, u8), + NestedStructVariant(NestedStruct), + NestedEnumStructVariant(NestedEnumStruct), + } - #[derive(Debug, PartialEq, Encode, Decode)] - struct NestedEnumStruct { - inner_enum: InnerEnum, - } + #[derive(Debug, PartialEq, Encode, Decode)] + enum InnerEnum { + A, + B { inner_data: u8 }, + C(u8), + } - // Creating each possible variant for an enum. - let enum_simple = ComprehensiveEnum::SimpleVariant; - let enum_data = ComprehensiveEnum::DataVariant(42); - let enum_named = ComprehensiveEnum::NamedFields { w: 42 }; - let enum_nested = ComprehensiveEnum::NestedEnum(InnerEnum::B { inner_data: 42 }); - let enum_option = ComprehensiveEnum::OptionVariant(Some(42)); - let enum_vec = ComprehensiveEnum::VecVariant(vec![1, 2, 3, 4, 5]); - let enum_tuple = ComprehensiveEnum::TupleVariant(42, 42); - let enum_nested_struct = ComprehensiveEnum::NestedStructVariant(NestedStruct { x: 42, y: 42 }); - let enum_nested_enum_struct = ComprehensiveEnum::NestedEnumStructVariant(NestedEnumStruct { - inner_enum: InnerEnum::C(42), - }); + #[derive(Debug, PartialEq, Encode, Decode)] + struct NestedStruct { + x: u8, + y: u8, + } - // Encode and print each variant individually to see their encoded values. - println!("{:?} -> {:?}", enum_simple, enum_simple.encode()); - println!("{:?} -> {:?}", enum_data, enum_data.encode()); - println!("{:?} -> {:?}", enum_named, enum_named.encode()); - println!("{:?} -> {:?}", enum_nested, enum_nested.encode()); - println!("{:?} -> {:?}", enum_option, enum_option.encode()); - println!("{:?} -> {:?}", enum_vec, enum_vec.encode()); - println!("{:?} -> {:?}", enum_tuple, enum_tuple.encode()); - println!("{:?} -> {:?}", enum_nested_struct, enum_nested_struct.encode()); - println!("{:?} -> {:?}", enum_nested_enum_struct, enum_nested_enum_struct.encode()); -} + #[derive(Debug, PartialEq, Encode, Decode)] + struct NestedEnumStruct { + inner_enum: InnerEnum, + } -#[test] -fn dispatch_error_to_status_code_to_pop_api_error_works() { - // Create all the different `DispatchError` variants with its respective `PopApiError`. - let test_cases = vec![ - (DispatchError::CannotLookup, PopApiError::CannotLookup), - (DispatchError::BadOrigin, PopApiError::BadOrigin), - ( - DispatchError::Module(sp_runtime::ModuleError { - index: 1, - error: [2, 0, 0, 0], - message: Some("hallo"), - }), - PopApiError::Module { index: 1, error: 2 }, - ), - (DispatchError::ConsumerRemaining, PopApiError::ConsumerRemaining), - (DispatchError::NoProviders, PopApiError::NoProviders), - (DispatchError::TooManyConsumers, PopApiError::TooManyConsumers), - ( - DispatchError::Token(sp_runtime::TokenError::FundsUnavailable), - PopApiError::Token(TokenError::FundsUnavailable), - ), - ( - DispatchError::Arithmetic(sp_runtime::ArithmeticError::Overflow), - PopApiError::Arithmetic(ArithmeticError::Overflow), - ), - ( - DispatchError::Transactional(sp_runtime::TransactionalError::LimitReached), - PopApiError::Transactional(TransactionalError::LimitReached), - ), - (DispatchError::Exhausted, PopApiError::Exhausted), - (DispatchError::Corruption, PopApiError::Corruption), - (DispatchError::Unavailable, PopApiError::Unavailable), - (DispatchError::RootNotAllowed, PopApiError::RootNotAllowed), - ]; - for (error, pop_api_error) in test_cases { - // Show that the encoding and decoding of the PopApiError <> u32 (status code) works. - let status_code = crate::extensions::convert_to_status_code(error); - // let error = pop_api::error::convert_to_pop_api_error(status_code); - // assert_eq!(pop_api_error, error,); + // Creating each possible variant for an enum. + let enum_simple = ComprehensiveEnum::SimpleVariant; + let enum_data = ComprehensiveEnum::DataVariant(42); + let enum_named = ComprehensiveEnum::NamedFields { w: 42 }; + let enum_nested = ComprehensiveEnum::NestedEnum(InnerEnum::B { inner_data: 42 }); + let enum_option = ComprehensiveEnum::OptionVariant(Some(42)); + let enum_vec = ComprehensiveEnum::VecVariant(vec![1, 2, 3, 4, 5]); + let enum_tuple = ComprehensiveEnum::TupleVariant(42, 42); + let enum_nested_struct = + ComprehensiveEnum::NestedStructVariant(NestedStruct { x: 42, y: 42 }); + let enum_nested_enum_struct = + ComprehensiveEnum::NestedEnumStructVariant(NestedEnumStruct { + inner_enum: InnerEnum::C(42), + }); + + // Encode and print each variant individually to see their encoded values. + println!("{:?} -> {:?}", enum_simple, enum_simple.encode()); + println!("{:?} -> {:?}", enum_data, enum_data.encode()); + println!("{:?} -> {:?}", enum_named, enum_named.encode()); + println!("{:?} -> {:?}", enum_nested, enum_nested.encode()); + println!("{:?} -> {:?}", enum_option, enum_option.encode()); + println!("{:?} -> {:?}", enum_vec, enum_vec.encode()); + println!("{:?} -> {:?}", enum_tuple, enum_tuple.encode()); + println!("{:?} -> {:?}", enum_nested_struct, enum_nested_struct.encode()); + println!("{:?} -> {:?}", enum_nested_enum_struct, enum_nested_enum_struct.encode()); + } + + #[test] + fn dispatch_error_to_status_code() { + // Create all the different `DispatchError` variants with its respective `PopApiError`. + let test_cases = vec![ + (DispatchError::Other("hallo"), [0, 0, 0, 0]), + (DispatchError::CannotLookup, [1, 0, 0, 0]), + (DispatchError::BadOrigin, [2, 0, 0, 0]), + ( + DispatchError::Module(sp_runtime::ModuleError { + index: 1, + error: [2, 0, 0, 0], + message: Some("hallo"), + }), + [3, 1, 2, 0], + ), + (DispatchError::ConsumerRemaining, [4, 0, 0, 0]), + (DispatchError::NoProviders, [5, 0, 0, 0]), + (DispatchError::TooManyConsumers, [6, 0, 0, 0]), + (DispatchError::Token(sp_runtime::TokenError::BelowMinimum), [7, 2, 0, 0]), + (DispatchError::Arithmetic(sp_runtime::ArithmeticError::Overflow), [8, 1, 0, 0]), + ( + DispatchError::Transactional(sp_runtime::TransactionalError::LimitReached), + [9, 0, 0, 0], + ), + (DispatchError::Exhausted, [10, 0, 0, 0]), + (DispatchError::Corruption, [11, 0, 0, 0]), + (DispatchError::Unavailable, [12, 0, 0, 0]), + (DispatchError::RootNotAllowed, [13, 0, 0, 0]), + ]; + for (error, encoded_error) in test_cases { + let status_code = crate::extensions::convert_to_status_code(error); + assert_eq!(status_code, u32::decode(&mut &encoded_error[..]).unwrap()); + } } } diff --git a/runtime/testnet/Cargo.toml b/runtime/testnet/Cargo.toml index 43b1e310..b7aa7b76 100644 --- a/runtime/testnet/Cargo.toml +++ b/runtime/testnet/Cargo.toml @@ -22,7 +22,7 @@ scale-info.workspace = true smallvec.workspace = true # Local -pop-primitives = { workspace = true, features = ["testnet"] } +pop-primitives = { workspace = true, features = ["assets", "nfts", "cross-chain"] } pop-runtime-common = { workspace = true, default-features = false } # Substrate diff --git a/runtime/testnet/src/extensions.rs b/runtime/testnet/src/extensions.rs index a3284ad4..dd2c52bb 100644 --- a/runtime/testnet/src/extensions.rs +++ b/runtime/testnet/src/extensions.rs @@ -9,8 +9,8 @@ use pallet_contracts::chain_extension::{ BufInBufOutState, ChainExtension, ChargedAmount, Environment, Ext, InitState, RetVal, }; use pop_primitives::{ + nfts::{CollectionId, ItemId}, storage_keys::{NftsKeys, ParachainSystemKeys, RuntimeStateKeys}, - CollectionId, ItemId, }; use sp_core::crypto::UncheckedFrom; use sp_runtime::{ @@ -19,7 +19,7 @@ use sp_runtime::{ }; use sp_std::vec::Vec; -use crate::{AccountId, AllowedPopApiCalls, RuntimeCall, RuntimeOrigin}; +use crate::{AccountId, AllowedApiCalls, RuntimeCall, RuntimeOrigin}; const LOG_TARGET: &str = "pop-api::extension"; @@ -110,7 +110,7 @@ where log::debug!(target:LOG_TARGET, "{} inputted RuntimeCall: {:?}", log_prefix, call); - origin.add_filter(AllowedPopApiCalls::contains); + origin.add_filter(AllowedApiCalls::contains); match call.dispatch(origin) { Ok(info) => { diff --git a/runtime/testnet/src/lib.rs b/runtime/testnet/src/lib.rs index 66a5092c..c4178011 100644 --- a/runtime/testnet/src/lib.rs +++ b/runtime/testnet/src/lib.rs @@ -250,8 +250,8 @@ impl Contains for FilteredCalls { } /// A type to identify allowed calls to the Runtime from contracts. Used by Pop API -pub struct AllowedPopApiCalls; -impl Contains for crate::AllowedPopApiCalls { +pub struct AllowedApiCalls; +impl Contains for AllowedApiCalls { fn contains(c: &RuntimeCall) -> bool { use pallet_nfts::Call as NftsCall; matches!( From 61b3a17d39b9bbbc76f87665a9546da9e0b58f89 Mon Sep 17 00:00:00 2001 From: Daanvdplas Date: Wed, 26 Jun 2024 10:48:23 +0200 Subject: [PATCH 012/112] refactor: tests local fungibles --- Cargo.lock | 2787 ++++++----------- Cargo.toml | 28 +- pop-api/Cargo.toml | 6 +- pop-api/examples/.gitignore | 4 +- pop-api/examples/fungibles/lib.rs | 18 +- pop-api/integration-tests/Cargo.toml | 31 + pop-api/integration-tests/src/lib.rs | 95 + .../integration-tests/src}/local_fungibles.rs | 71 +- pop-api/src/lib.rs | 3 +- pop-api/src/v0/assets/mod.rs | 8 +- primitives/Cargo.toml | 4 +- primitives/src/storage_keys.rs | 4 +- runtime/devnet/Cargo.toml | 2 - runtime/devnet/src/extensions.rs | 180 ++ runtime/devnet/src/lib.rs | 2 - runtime/devnet/src/tests/mod.rs | 267 -- 16 files changed, 1331 insertions(+), 2179 deletions(-) create mode 100644 pop-api/integration-tests/Cargo.toml create mode 100644 pop-api/integration-tests/src/lib.rs rename {runtime/devnet/src/tests => pop-api/integration-tests/src}/local_fungibles.rs (88%) delete mode 100644 runtime/devnet/src/tests/mod.rs diff --git a/Cargo.lock b/Cargo.lock index 77c563fb..d798562b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -343,7 +343,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94893f1e0c6eeab764ade8dc4c0db24caf4fe7cbbaafc0eba0a9030f447b5185" dependencies = [ "num-traits", - "rand 0.8.5", + "rand", ] [[package]] @@ -358,12 +358,6 @@ version = "6.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6f840fb7195bcfc5e17ea40c26e5ce6d5b9ce5d584466e17703209657e459ae0" -[[package]] -name = "array-init" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d62b7694a562cdf5a74227903507c56ab2cc8bdd1f781ed5cb4cf9c9f810bfc" - [[package]] name = "arrayref" version = "0.3.7" @@ -379,12 +373,6 @@ dependencies = [ "nodrop", ] -[[package]] -name = "arrayvec" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" - [[package]] name = "arrayvec" version = "0.7.4" @@ -416,7 +404,7 @@ dependencies = [ "proc-macro2", "quote", "syn 1.0.109", - "synstructure 0.12.6", + "synstructure", ] [[package]] @@ -498,17 +486,17 @@ dependencies = [ "sp-api", "sp-block-builder", "sp-consensus-aura", - "sp-core 29.0.0", + "sp-core", "sp-genesis-builder", "sp-inherents", "sp-offchain", - "sp-runtime 32.0.0", + "sp-runtime", "sp-session", - "sp-std 14.0.0", - "sp-storage 20.0.0", + "sp-std", + "sp-storage", "sp-transaction-pool", "sp-version", - "sp-weights 28.0.0", + "sp-weights", "staging-parachain-info", "staging-xcm", "staging-xcm-builder", @@ -537,9 +525,9 @@ dependencies = [ "parachains-common", "parachains-runtimes-test-utils", "parity-scale-codec", - "sp-io 31.0.0", - "sp-runtime 32.0.0", - "sp-std 14.0.0", + "sp-io", + "sp-runtime", + "sp-std", "staging-parachain-info", "staging-xcm", "staging-xcm-builder", @@ -563,8 +551,8 @@ dependencies = [ "parity-scale-codec", "scale-info", "sp-api", - "sp-runtime 32.0.0", - "sp-std 14.0.0", + "sp-runtime", + "sp-std", "staging-xcm", "staging-xcm-builder", "staging-xcm-executor", @@ -921,7 +909,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "93f2635620bf0b9d4576eb7bb9a38a55df78bd1205d26fa994b25911a69f212f" dependencies = [ "bitcoin_hashes", - "rand 0.8.5", + "rand", "rand_core 0.6.4", "serde", "unicode-normalization", @@ -1024,18 +1012,6 @@ dependencies = [ "constant_time_eq 0.3.0", ] -[[package]] -name = "block-buffer" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0940dc441f31689269e10ac70eb1002a3a1d3ad1390e030043662eb7fe4688b" -dependencies = [ - "block-padding", - "byte-tools", - "byteorder", - "generic-array 0.12.4", -] - [[package]] name = "block-buffer" version = "0.9.0" @@ -1054,15 +1030,6 @@ dependencies = [ "generic-array 0.14.7", ] -[[package]] -name = "block-padding" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa79dedbb091f449f1f39e53edf88d5dbe95f895dae6135a8d7b881fb5af73f5" -dependencies = [ - "byte-tools", -] - [[package]] name = "blocking" version = "1.5.1" @@ -1149,7 +1116,7 @@ dependencies = [ "frame-system", "polkadot-primitives", "sp-api", - "sp-std 14.0.0", + "sp-std", ] [[package]] @@ -1163,8 +1130,8 @@ dependencies = [ "bp-runtime", "frame-support", "sp-api", - "sp-runtime 32.0.0", - "sp-std 14.0.0", + "sp-runtime", + "sp-std", ] [[package]] @@ -1178,8 +1145,8 @@ dependencies = [ "bp-runtime", "frame-support", "sp-api", - "sp-runtime 32.0.0", - "sp-std 14.0.0", + "sp-runtime", + "sp-std", ] [[package]] @@ -1195,9 +1162,9 @@ dependencies = [ "scale-info", "serde", "sp-consensus-grandpa", - "sp-core 29.0.0", - "sp-runtime 32.0.0", - "sp-std 14.0.0", + "sp-core", + "sp-runtime", + "sp-std", ] [[package]] @@ -1212,8 +1179,8 @@ dependencies = [ "parity-scale-codec", "scale-info", "serde", - "sp-core 29.0.0", - "sp-std 14.0.0", + "sp-core", + "sp-std", ] [[package]] @@ -1229,9 +1196,9 @@ dependencies = [ "impl-trait-for-tuples", "parity-scale-codec", "scale-info", - "sp-core 29.0.0", - "sp-runtime 32.0.0", - "sp-std 14.0.0", + "sp-core", + "sp-runtime", + "sp-std", ] [[package]] @@ -1248,9 +1215,9 @@ dependencies = [ "parity-util-mem", "scale-info", "serde", - "sp-core 29.0.0", - "sp-runtime 32.0.0", - "sp-std 14.0.0", + "sp-core", + "sp-runtime", + "sp-std", ] [[package]] @@ -1264,8 +1231,8 @@ dependencies = [ "frame-support", "parity-scale-codec", "scale-info", - "sp-runtime 32.0.0", - "sp-std 14.0.0", + "sp-runtime", + "sp-std", ] [[package]] @@ -1283,13 +1250,13 @@ dependencies = [ "parity-scale-codec", "scale-info", "serde", - "sp-core 29.0.0", - "sp-io 31.0.0", - "sp-runtime 32.0.0", - "sp-state-machine 0.36.0", - "sp-std 14.0.0", - "sp-trie 30.0.0", - "trie-db 0.28.0", + "sp-core", + "sp-io", + "sp-runtime", + "sp-state-machine", + "sp-std", + "sp-trie", + "trie-db", ] [[package]] @@ -1302,15 +1269,15 @@ dependencies = [ "bp-parachains", "bp-polkadot-core", "bp-runtime", - "ed25519-dalek 2.1.1", + "ed25519-dalek", "finality-grandpa", "parity-scale-codec", - "sp-application-crypto 31.0.0", + "sp-application-crypto", "sp-consensus-grandpa", - "sp-core 29.0.0", - "sp-runtime 32.0.0", - "sp-std 14.0.0", - "sp-trie 30.0.0", + "sp-core", + "sp-runtime", + "sp-std", + "sp-trie", ] [[package]] @@ -1319,7 +1286,7 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6663e0179d475e30cfcf28cf597cdc8f4bb1c2c39a557b4cbe0057db0657fb67" dependencies = [ - "sp-std 14.0.0", + "sp-std", ] [[package]] @@ -1330,8 +1297,8 @@ checksum = "86ff4abe93be7bc1663adc41817b1aa3476fbec953ce361537419924310d5dd4" dependencies = [ "parity-scale-codec", "scale-info", - "sp-core 29.0.0", - "sp-runtime 32.0.0", + "sp-core", + "sp-runtime", ] [[package]] @@ -1361,11 +1328,11 @@ dependencies = [ "parity-scale-codec", "scale-info", "sp-api", - "sp-core 29.0.0", - "sp-io 31.0.0", - "sp-runtime 32.0.0", - "sp-std 14.0.0", - "sp-trie 30.0.0", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", + "sp-trie", "staging-xcm", "staging-xcm-builder", ] @@ -1778,26 +1745,6 @@ dependencies = [ "tiny-keccak", ] -[[package]] -name = "const_env" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e9e4f72c6e3398ca6da372abd9affd8f89781fe728869bbf986206e9af9627e" -dependencies = [ - "const_env_impl", -] - -[[package]] -name = "const_env_impl" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a4f51209740b5e1589e702b3044cdd4562cef41b6da404904192ffffb852d62" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - [[package]] name = "constant_time_eq" version = "0.1.5" @@ -2097,8 +2044,8 @@ dependencies = [ "sc-client-api", "sc-service", "sp-blockchain", - "sp-core 29.0.0", - "sp-runtime 32.0.0", + "sp-core", + "sp-runtime", "url", ] @@ -2121,8 +2068,8 @@ dependencies = [ "sc-client-api", "sp-api", "sp-consensus", - "sp-core 29.0.0", - "sp-runtime 32.0.0", + "sp-core", + "sp-runtime", "tracing", ] @@ -2154,16 +2101,16 @@ dependencies = [ "sc-telemetry", "schnellru", "sp-api", - "sp-application-crypto 31.0.0", + "sp-application-crypto", "sp-block-builder", "sp-blockchain", "sp-consensus", "sp-consensus-aura", - "sp-core 29.0.0", + "sp-core", "sp-inherents", - "sp-keystore 0.35.0", - "sp-runtime 32.0.0", - "sp-state-machine 0.36.0", + "sp-keystore", + "sp-runtime", + "sp-state-machine", "sp-timestamp", "substrate-prometheus-endpoint", "tracing", @@ -2191,10 +2138,10 @@ dependencies = [ "sp-blockchain", "sp-consensus", "sp-consensus-slots", - "sp-core 29.0.0", - "sp-runtime 32.0.0", + "sp-core", + "sp-runtime", "sp-timestamp", - "sp-trie 30.0.0", + "sp-trie", "substrate-prometheus-endpoint", "tracing", ] @@ -2210,8 +2157,8 @@ dependencies = [ "cumulus-primitives-parachain-inherent", "sp-consensus", "sp-inherents", - "sp-runtime 32.0.0", - "sp-state-machine 0.36.0", + "sp-runtime", + "sp-state-machine", "thiserror", ] @@ -2233,9 +2180,9 @@ dependencies = [ "sc-client-api", "sp-blockchain", "sp-consensus", - "sp-core 29.0.0", - "sp-runtime 32.0.0", - "sp-state-machine 0.36.0", + "sp-core", + "sp-runtime", + "sp-state-machine", "tracing", ] @@ -2256,11 +2203,11 @@ dependencies = [ "sp-api", "sp-crypto-hashing", "sp-inherents", - "sp-runtime 32.0.0", - "sp-state-machine 0.36.0", - "sp-std 14.0.0", - "sp-storage 20.0.0", - "sp-trie 30.0.0", + "sp-runtime", + "sp-state-machine", + "sp-std", + "sp-storage", + "sp-trie", "tracing", ] @@ -2280,12 +2227,12 @@ dependencies = [ "polkadot-node-subsystem", "polkadot-overseer", "polkadot-primitives", - "rand 0.8.5", + "rand", "sc-client-api", "sc-consensus", "sp-consensus", "sp-maybe-compressed-blob", - "sp-runtime 32.0.0", + "sp-runtime", "tracing", ] @@ -2321,8 +2268,8 @@ dependencies = [ "sp-api", "sp-blockchain", "sp-consensus", - "sp-core 29.0.0", - "sp-runtime 32.0.0", + "sp-core", + "sp-runtime", "sp-transaction-pool", ] @@ -2339,10 +2286,10 @@ dependencies = [ "pallet-timestamp", "parity-scale-codec", "scale-info", - "sp-application-crypto 31.0.0", + "sp-application-crypto", "sp-consensus-aura", - "sp-runtime 32.0.0", - "sp-std 14.0.0", + "sp-runtime", + "sp-std", ] [[package]] @@ -2368,17 +2315,17 @@ dependencies = [ "polkadot-runtime-common", "polkadot-runtime-parachains", "scale-info", - "sp-core 29.0.0", - "sp-externalities 0.26.0", + "sp-core", + "sp-externalities", "sp-inherents", - "sp-io 31.0.0", - "sp-runtime 32.0.0", - "sp-state-machine 0.36.0", - "sp-std 14.0.0", - "sp-trie 30.0.0", + "sp-io", + "sp-runtime", + "sp-state-machine", + "sp-std", + "sp-trie", "sp-version", "staging-xcm", - "trie-db 0.28.0", + "trie-db", ] [[package]] @@ -2404,8 +2351,8 @@ dependencies = [ "frame-system", "pallet-session", "parity-scale-codec", - "sp-runtime 32.0.0", - "sp-std 14.0.0", + "sp-runtime", + "sp-std", ] [[package]] @@ -2419,9 +2366,9 @@ dependencies = [ "frame-system", "parity-scale-codec", "scale-info", - "sp-io 31.0.0", - "sp-runtime 32.0.0", - "sp-std 14.0.0", + "sp-io", + "sp-runtime", + "sp-std", "staging-xcm", ] @@ -2443,10 +2390,10 @@ dependencies = [ "polkadot-runtime-common", "polkadot-runtime-parachains", "scale-info", - "sp-core 29.0.0", - "sp-io 31.0.0", - "sp-runtime 32.0.0", - "sp-std 14.0.0", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", "staging-xcm", "staging-xcm-executor", ] @@ -2462,8 +2409,8 @@ dependencies = [ "polkadot-primitives", "sp-api", "sp-consensus-aura", - "sp-runtime 32.0.0", - "sp-std 14.0.0", + "sp-runtime", + "sp-std", ] [[package]] @@ -2478,9 +2425,9 @@ dependencies = [ "polkadot-primitives", "scale-info", "sp-api", - "sp-runtime 32.0.0", - "sp-std 14.0.0", - "sp-trie 30.0.0", + "sp-runtime", + "sp-std", + "sp-trie", "staging-xcm", ] @@ -2494,10 +2441,10 @@ dependencies = [ "cumulus-primitives-core", "parity-scale-codec", "scale-info", - "sp-core 29.0.0", + "sp-core", "sp-inherents", - "sp-std 14.0.0", - "sp-trie 30.0.0", + "sp-std", + "sp-trie", ] [[package]] @@ -2506,9 +2453,9 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c1b74f9141190b9f4bf96a947ade46da64097b77f1ebfa8d611c81724250e119" dependencies = [ - "sp-externalities 0.26.0", - "sp-runtime-interface 25.0.0", - "sp-trie 30.0.0", + "sp-externalities", + "sp-runtime-interface", + "sp-trie", ] [[package]] @@ -2524,9 +2471,9 @@ dependencies = [ "parity-scale-codec", "polkadot-runtime-common", "polkadot-runtime-parachains", - "sp-io 31.0.0", - "sp-runtime 32.0.0", - "sp-std 14.0.0", + "sp-io", + "sp-runtime", + "sp-std", "staging-xcm", "staging-xcm-builder", "staging-xcm-executor", @@ -2552,9 +2499,9 @@ dependencies = [ "sc-tracing", "sp-api", "sp-consensus", - "sp-core 29.0.0", - "sp-runtime 32.0.0", - "sp-state-machine 0.36.0", + "sp-core", + "sp-runtime", + "sp-state-machine", ] [[package]] @@ -2572,7 +2519,7 @@ dependencies = [ "sc-client-api", "sp-api", "sp-blockchain", - "sp-state-machine 0.36.0", + "sp-state-machine", "thiserror", ] @@ -2612,7 +2559,7 @@ dependencies = [ "sp-blockchain", "sp-consensus", "sp-consensus-babe", - "sp-runtime 32.0.0", + "sp-runtime", "substrate-prometheus-endpoint", "tokio", "tracing", @@ -2634,7 +2581,7 @@ dependencies = [ "parity-scale-codec", "pin-project", "polkadot-overseer", - "rand 0.8.5", + "rand", "sc-client-api", "sc-rpc-api", "sc-service", @@ -2646,10 +2593,10 @@ dependencies = [ "sp-api", "sp-authority-discovery", "sp-consensus-babe", - "sp-core 29.0.0", - "sp-runtime 32.0.0", - "sp-state-machine 0.36.0", - "sp-storage 20.0.0", + "sp-core", + "sp-runtime", + "sp-state-machine", + "sp-storage", "sp-version", "thiserror", "tokio", @@ -2667,23 +2614,10 @@ dependencies = [ "cumulus-primitives-core", "parity-scale-codec", "polkadot-primitives", - "sp-runtime 32.0.0", - "sp-state-machine 0.36.0", - "sp-std 14.0.0", - "sp-trie 30.0.0", -] - -[[package]] -name = "curve25519-dalek" -version = "2.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a9b85542f99a2dfa2a1b8e192662741c9859a846b296bef1c92ef9b58b5a216" -dependencies = [ - "byteorder", - "digest 0.8.1", - "rand_core 0.5.1", - "subtle 2.5.0", - "zeroize", + "sp-runtime", + "sp-state-machine", + "sp-std", + "sp-trie", ] [[package]] @@ -3130,19 +3064,10 @@ dependencies = [ "digest 0.10.7", "elliptic-curve", "rfc6979", - "signature 2.2.0", + "signature", "spki", ] -[[package]] -name = "ed25519" -version = "1.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91cff35c70bba8a626e3185d8cd48cc11b5437e1a5bcd15b9b5fa3c64b6dfee7" -dependencies = [ - "signature 1.6.4", -] - [[package]] name = "ed25519" version = "2.2.3" @@ -3150,19 +3075,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "115531babc129696a58c64a4fef0a8bf9e9698629fb97e9e40767d235cfbcd53" dependencies = [ "pkcs8", - "signature 2.2.0", -] - -[[package]] -name = "ed25519-dalek" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c762bae6dcaf24c4c84667b8579785430908723d5c889f469d76a41d59cc7a9d" -dependencies = [ - "curve25519-dalek 3.2.0", - "ed25519 1.5.3", - "sha2 0.9.9", - "zeroize", + "signature", ] [[package]] @@ -3172,7 +3085,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4a3daa8e81a3963a60642bcc1f90a670680bd4a77535faa384e9d1c79d620871" dependencies = [ "curve25519-dalek 4.1.2", - "ed25519 2.2.3", + "ed25519", "rand_core 0.6.4", "serde", "sha2 0.10.8", @@ -3201,7 +3114,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7d9ce6874da5d4415896cd45ffbc4d1cfc0c4f9c079427bd870742c30f2f65a9" dependencies = [ "curve25519-dalek 4.1.2", - "ed25519 2.2.3", + "ed25519", "hashbrown 0.14.3", "hex", "rand_core 0.6.4", @@ -3261,8 +3174,8 @@ dependencies = [ "sc-consensus-grandpa", "sp-authority-discovery", "sp-consensus-babe", - "sp-core 29.0.0", - "sp-runtime 32.0.0", + "sp-core", + "sp-runtime", "staging-xcm", "xcm-emulator", ] @@ -3509,12 +3422,6 @@ dependencies = [ "syn 2.0.58", ] -[[package]] -name = "fake-simd" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed" - [[package]] name = "fallible-iterator" version = "0.2.0" @@ -3632,7 +3539,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "835c052cb0c08c1acf6ffd71c022172e18723949c8282f2b9f27efbc51e64534" dependencies = [ "byteorder", - "rand 0.8.5", + "rand", "rustc-hex", "static_assertions", ] @@ -3709,13 +3616,13 @@ dependencies = [ "scale-info", "serde", "sp-api", - "sp-application-crypto 31.0.0", - "sp-core 29.0.0", - "sp-io 31.0.0", - "sp-runtime 32.0.0", - "sp-runtime-interface 25.0.0", - "sp-std 14.0.0", - "sp-storage 20.0.0", + "sp-application-crypto", + "sp-core", + "sp-io", + "sp-runtime", + "sp-runtime-interface", + "sp-std", + "sp-storage", "static_assertions", ] @@ -3740,7 +3647,7 @@ dependencies = [ "linked-hash-map", "log", "parity-scale-codec", - "rand 0.8.5", + "rand", "rand_pcg", "sc-block-builder", "sc-cli", @@ -3753,17 +3660,17 @@ dependencies = [ "serde_json", "sp-api", "sp-blockchain", - "sp-core 29.0.0", + "sp-core", "sp-database", - "sp-externalities 0.26.0", + "sp-externalities", "sp-inherents", - "sp-io 31.0.0", - "sp-keystore 0.35.0", - "sp-runtime 32.0.0", - "sp-state-machine 0.36.0", - "sp-storage 20.0.0", - "sp-trie 30.0.0", - "sp-wasm-interface 20.0.0", + "sp-io", + "sp-keystore", + "sp-runtime", + "sp-state-machine", + "sp-storage", + "sp-trie", + "sp-wasm-interface", "thiserror", "thousands", ] @@ -3791,11 +3698,11 @@ dependencies = [ "frame-system", "parity-scale-codec", "scale-info", - "sp-arithmetic 24.0.0", - "sp-core 29.0.0", + "sp-arithmetic", + "sp-core", "sp-npos-elections", - "sp-runtime 32.0.0", - "sp-std 14.0.0", + "sp-runtime", + "sp-std", ] [[package]] @@ -3810,11 +3717,11 @@ dependencies = [ "log", "parity-scale-codec", "scale-info", - "sp-core 29.0.0", - "sp-io 31.0.0", - "sp-runtime 32.0.0", - "sp-std 14.0.0", - "sp-tracing 16.0.0", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", + "sp-tracing", ] [[package]] @@ -3852,11 +3759,11 @@ dependencies = [ "log", "parity-scale-codec", "serde", - "sp-core 29.0.0", + "sp-core", "sp-crypto-hashing", - "sp-io 31.0.0", - "sp-runtime 32.0.0", - "sp-state-machine 0.36.0", + "sp-io", + "sp-runtime", + "sp-state-machine", "spinners", "substrate-rpc-client", "tokio", @@ -3887,20 +3794,20 @@ dependencies = [ "serde_json", "smallvec", "sp-api", - "sp-arithmetic 24.0.0", - "sp-core 29.0.0", + "sp-arithmetic", + "sp-core", "sp-crypto-hashing-proc-macro", - "sp-debug-derive 14.0.0", + "sp-debug-derive", "sp-genesis-builder", "sp-inherents", - "sp-io 31.0.0", + "sp-io", "sp-metadata-ir", - "sp-runtime 32.0.0", + "sp-runtime", "sp-staking", - "sp-state-machine 0.36.0", - "sp-std 14.0.0", - "sp-tracing 16.0.0", - "sp-weights 28.0.0", + "sp-state-machine", + "sp-std", + "sp-tracing", + "sp-weights", "static_assertions", "tt-call", ] @@ -3962,12 +3869,12 @@ dependencies = [ "parity-scale-codec", "scale-info", "serde", - "sp-core 29.0.0", - "sp-io 31.0.0", - "sp-runtime 32.0.0", - "sp-std 14.0.0", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", "sp-version", - "sp-weights 28.0.0", + "sp-weights", ] [[package]] @@ -3981,9 +3888,9 @@ dependencies = [ "frame-system", "parity-scale-codec", "scale-info", - "sp-core 29.0.0", - "sp-runtime 32.0.0", - "sp-std 14.0.0", + "sp-core", + "sp-runtime", + "sp-std", ] [[package]] @@ -4005,8 +3912,8 @@ dependencies = [ "frame-support", "parity-scale-codec", "sp-api", - "sp-runtime 32.0.0", - "sp-std 14.0.0", + "sp-runtime", + "sp-std", ] [[package]] @@ -4256,7 +4163,7 @@ version = "0.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6ea1015b5a70616b688dc230cfe50c8af89d972cb132d5a622814d29773b10b9" dependencies = [ - "rand 0.8.5", + "rand", "rand_core 0.6.4", ] @@ -4762,206 +4669,6 @@ dependencies = [ "unicode-width", ] -[[package]] -name = "ink" -version = "5.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d4a862aedbfda93175ddf75c9aaa2ae4c4b39ee5cee06c16d50bccce05bf5c7" -dependencies = [ - "derive_more", - "ink_env", - "ink_macro", - "ink_metadata", - "ink_prelude", - "ink_primitives", - "ink_storage", - "pallet-contracts-uapi-next", - "parity-scale-codec", - "scale-info", -] - -[[package]] -name = "ink_allocator" -version = "5.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cee56055bac6d928d425e944c5f3b69baa33c9635822fd1c00cd4afc70fde3e" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "ink_codegen" -version = "5.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70a1f8473fa09e0f9b6f3cb3f8d18c07c14ebf9ea1f7cdfee270f009d45ee8e9" -dependencies = [ - "blake2 0.10.6", - "derive_more", - "either", - "heck 0.4.1", - "impl-serde", - "ink_ir", - "ink_primitives", - "itertools 0.12.1", - "parity-scale-codec", - "proc-macro2", - "quote", - "serde", - "serde_json", - "syn 2.0.58", -] - -[[package]] -name = "ink_engine" -version = "5.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f357e2e867f4e222ffc4015a6e61d1073548de89f70a4e36a8b0385562777fa" -dependencies = [ - "blake2 0.10.6", - "derive_more", - "ink_primitives", - "pallet-contracts-uapi-next", - "parity-scale-codec", - "secp256k1 0.28.2", - "sha2 0.10.8", - "sha3", -] - -[[package]] -name = "ink_env" -version = "5.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42cec50b7e4f8406aab25801b015d3802a52d76cfbe48ce11cfb4200fa88e296" -dependencies = [ - "blake2 0.10.6", - "cfg-if", - "const_env", - "derive_more", - "ink_allocator", - "ink_engine", - "ink_prelude", - "ink_primitives", - "ink_storage_traits", - "num-traits", - "pallet-contracts-uapi-next", - "parity-scale-codec", - "paste", - "rlibc", - "scale-decode", - "scale-encode", - "scale-info", - "schnorrkel 0.11.4", - "secp256k1 0.28.2", - "sha2 0.10.8", - "sha3", - "static_assertions", -] - -[[package]] -name = "ink_ir" -version = "5.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b1ad2975551c4ed800af971289ed6d2c68ac41ffc03a42010b3e01d7360dfb2" -dependencies = [ - "blake2 0.10.6", - "either", - "impl-serde", - "ink_prelude", - "itertools 0.12.1", - "proc-macro2", - "quote", - "syn 2.0.58", -] - -[[package]] -name = "ink_macro" -version = "5.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aee1a546f37eae3b3cd223832d31702033c5369dcfa3405899587c110a7908d3" -dependencies = [ - "ink_codegen", - "ink_ir", - "ink_primitives", - "parity-scale-codec", - "proc-macro2", - "quote", - "syn 2.0.58", - "synstructure 0.13.1", -] - -[[package]] -name = "ink_metadata" -version = "5.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a98fcc0ff9292ff68c7ee7b84c93533c9ff13859ec3b148faa822e2da9954fe6" -dependencies = [ - "derive_more", - "impl-serde", - "ink_prelude", - "ink_primitives", - "linkme", - "parity-scale-codec", - "scale-info", - "schemars", - "serde", -] - -[[package]] -name = "ink_prelude" -version = "5.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea1734d058c80aa72e59c8ae75624fd8a51791efba21469f273156c0f4cad5c9" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "ink_primitives" -version = "5.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11ec35ef7f45e67a53b6142d7e7f18e6d9292d76c3a2a1da14cf8423e481813d" -dependencies = [ - "derive_more", - "ink_prelude", - "parity-scale-codec", - "scale-decode", - "scale-encode", - "scale-info", - "xxhash-rust", -] - -[[package]] -name = "ink_storage" -version = "5.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbdb04cad74df858c05bc9cb6f30bbf12da33c3e2cb7ca211749c001fa761aa9" -dependencies = [ - "array-init", - "cfg-if", - "derive_more", - "ink_env", - "ink_metadata", - "ink_prelude", - "ink_primitives", - "ink_storage_traits", - "pallet-contracts-uapi-next", - "parity-scale-codec", - "scale-info", -] - -[[package]] -name = "ink_storage_traits" -version = "5.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83ce49e3d2935fc1ec3e73117119712b187d3123339f6a31624e92f75fa2293d" -dependencies = [ - "ink_metadata", - "ink_prelude", - "ink_primitives", - "parity-scale-codec", - "scale-info", -] - [[package]] name = "inout" version = "0.1.3" @@ -5019,8 +4726,8 @@ dependencies = [ "sp-consensus-babe", "sp-consensus-beefy", "sp-consensus-grandpa", - "sp-core 29.0.0", - "sp-runtime 32.0.0", + "sp-core", + "sp-runtime", "staging-xcm", "staging-xcm-executor", "tracing-subscriber 0.3.18", @@ -5216,7 +4923,7 @@ dependencies = [ "hyper", "jsonrpsee-types 0.20.3", "parking_lot 0.12.1", - "rand 0.8.5", + "rand", "rustc-hash", "serde", "serde_json", @@ -5549,7 +5256,7 @@ dependencies = [ "parking_lot 0.12.1", "pin-project", "quick-protobuf", - "rand 0.8.5", + "rand", "rw-stream-sink", "smallvec", "thiserror", @@ -5600,12 +5307,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "276bb57e7af15d8f100d3c11cbdd32c6752b7eef4ba7a18ecf464972c07abcce" dependencies = [ "bs58 0.4.0", - "ed25519-dalek 2.1.1", + "ed25519-dalek", "log", "multiaddr", "multihash 0.17.0", "quick-protobuf", - "rand 0.8.5", + "rand", "sha2 0.10.8", "thiserror", "zeroize", @@ -5630,7 +5337,7 @@ dependencies = [ "libp2p-swarm", "log", "quick-protobuf", - "rand 0.8.5", + "rand", "sha2 0.10.8", "smallvec", "thiserror", @@ -5652,7 +5359,7 @@ dependencies = [ "libp2p-identity", "libp2p-swarm", "log", - "rand 0.8.5", + "rand", "smallvec", "socket2 0.4.10", "tokio", @@ -5688,7 +5395,7 @@ dependencies = [ "log", "once_cell", "quick-protobuf", - "rand 0.8.5", + "rand", "sha2 0.10.8", "snow", "static_assertions", @@ -5710,7 +5417,7 @@ dependencies = [ "libp2p-core", "libp2p-swarm", "log", - "rand 0.8.5", + "rand", "void", ] @@ -5730,7 +5437,7 @@ dependencies = [ "log", "parking_lot 0.12.1", "quinn-proto", - "rand 0.8.5", + "rand", "rustls 0.20.9", "thiserror", "tokio", @@ -5748,7 +5455,7 @@ dependencies = [ "libp2p-core", "libp2p-identity", "libp2p-swarm", - "rand 0.8.5", + "rand", "smallvec", ] @@ -5767,7 +5474,7 @@ dependencies = [ "libp2p-identity", "libp2p-swarm-derive", "log", - "rand 0.8.5", + "rand", "smallvec", "tokio", "void", @@ -5903,7 +5610,7 @@ dependencies = [ "libsecp256k1-core", "libsecp256k1-gen-ecmult", "libsecp256k1-gen-genmult", - "rand 0.8.5", + "rand", "serde", "sha2 0.9.9", "typenum", @@ -5973,26 +5680,6 @@ dependencies = [ "linked-hash-map", ] -[[package]] -name = "linkme" -version = "0.3.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ccb76662d78edc9f9bf56360d6919bdacc8b7761227727e5082f128eeb90bbf5" -dependencies = [ - "linkme-impl", -] - -[[package]] -name = "linkme-impl" -version = "0.3.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8dccda732e04fa3baf2e17cf835bfe2601c7c2edafd64417c627dabae3a8cda" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.58", -] - [[package]] name = "linregress" version = "0.5.3" @@ -6264,18 +5951,6 @@ dependencies = [ "hash-db", ] -[[package]] -name = "merlin" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e261cf0f8b3c42ded9f7d2bb59dea03aa52bc8a1cbc7482f9fc3fd1229d3b42" -dependencies = [ - "byteorder", - "keccak", - "rand_core 0.5.1", - "zeroize", -] - [[package]] name = "merlin" version = "3.0.0" @@ -6295,7 +5970,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "69672161530e8aeca1d1400fbf3f1a1747ff60ea604265a4e906c2442df20532" dependencies = [ "futures", - "rand 0.8.5", + "rand", "thrift", ] @@ -6342,7 +6017,7 @@ dependencies = [ "lioness", "log", "parking_lot 0.12.1", - "rand 0.8.5", + "rand", "rand_chacha 0.3.1", "rand_distr", "subtle 2.5.0", @@ -6365,9 +6040,9 @@ dependencies = [ "sp-blockchain", "sp-consensus", "sp-consensus-beefy", - "sp-core 29.0.0", + "sp-core", "sp-mmr-primitives", - "sp-runtime 32.0.0", + "sp-runtime", ] [[package]] @@ -6381,9 +6056,9 @@ dependencies = [ "serde", "sp-api", "sp-blockchain", - "sp-core 29.0.0", + "sp-core", "sp-mmr-primitives", - "sp-runtime 32.0.0", + "sp-runtime", ] [[package]] @@ -6514,7 +6189,7 @@ dependencies = [ "proc-macro2", "quote", "syn 1.0.109", - "synstructure 0.12.6", + "synstructure", ] [[package]] @@ -6539,7 +6214,7 @@ dependencies = [ "proc-macro2", "quote", "syn 1.0.109", - "synstructure 0.12.6", + "synstructure", ] [[package]] @@ -6595,7 +6270,7 @@ version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7bddcd3bf5144b6392de80e04c347cd7fab2508f6df16a85fc496ecd5cec39bc" dependencies = [ - "rand 0.8.5", + "rand", ] [[package]] @@ -6923,11 +6598,11 @@ dependencies = [ "parity-scale-codec", "scale-info", "sp-api", - "sp-arithmetic 24.0.0", - "sp-core 29.0.0", - "sp-io 31.0.0", - "sp-runtime 32.0.0", - "sp-std 14.0.0", + "sp-arithmetic", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", ] [[package]] @@ -6942,8 +6617,8 @@ dependencies = [ "pallet-transaction-payment", "parity-scale-codec", "scale-info", - "sp-runtime 32.0.0", - "sp-std 14.0.0", + "sp-runtime", + "sp-std", ] [[package]] @@ -6957,9 +6632,9 @@ dependencies = [ "frame-system", "parity-scale-codec", "scale-info", - "sp-core 29.0.0", - "sp-runtime 32.0.0", - "sp-std 14.0.0", + "sp-core", + "sp-runtime", + "sp-std", ] [[package]] @@ -6975,10 +6650,10 @@ dependencies = [ "parity-scale-codec", "scale-info", "serde", - "sp-core 29.0.0", - "sp-io 31.0.0", - "sp-runtime 32.0.0", - "sp-std 14.0.0", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", ] [[package]] @@ -6993,9 +6668,9 @@ dependencies = [ "log", "parity-scale-codec", "scale-info", - "sp-core 29.0.0", - "sp-runtime 32.0.0", - "sp-std 14.0.0", + "sp-core", + "sp-runtime", + "sp-std", ] [[package]] @@ -7010,10 +6685,10 @@ dependencies = [ "pallet-timestamp", "parity-scale-codec", "scale-info", - "sp-application-crypto 31.0.0", + "sp-application-crypto", "sp-consensus-aura", - "sp-runtime 32.0.0", - "sp-std 14.0.0", + "sp-runtime", + "sp-std", ] [[package]] @@ -7027,10 +6702,10 @@ dependencies = [ "pallet-session", "parity-scale-codec", "scale-info", - "sp-application-crypto 31.0.0", + "sp-application-crypto", "sp-authority-discovery", - "sp-runtime 32.0.0", - "sp-std 14.0.0", + "sp-runtime", + "sp-std", ] [[package]] @@ -7044,8 +6719,8 @@ dependencies = [ "impl-trait-for-tuples", "parity-scale-codec", "scale-info", - "sp-runtime 32.0.0", - "sp-std 14.0.0", + "sp-runtime", + "sp-std", ] [[package]] @@ -7063,14 +6738,14 @@ dependencies = [ "pallet-timestamp", "parity-scale-codec", "scale-info", - "sp-application-crypto 31.0.0", + "sp-application-crypto", "sp-consensus-babe", - "sp-core 29.0.0", - "sp-io 31.0.0", - "sp-runtime 32.0.0", + "sp-core", + "sp-io", + "sp-runtime", "sp-session", "sp-staking", - "sp-std 14.0.0", + "sp-std", ] [[package]] @@ -7089,18 +6764,18 @@ dependencies = [ "pallet-balances", "parity-scale-codec", "scale-info", - "sp-core 29.0.0", - "sp-io 31.0.0", - "sp-runtime 32.0.0", - "sp-std 14.0.0", - "sp-tracing 16.0.0", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", + "sp-tracing", ] [[package]] name = "pallet-balances" -version = "29.0.1" +version = "29.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e27946a57494d7c6231ae8909275bbd3cb5460ee3d27b7a5774a8b8e64d3ab92" +checksum = "a9a54b5d0c7c4c3731883d6b1ac18aff44db20c3d0a3470c8861001a17afdc85" dependencies = [ "docify", "frame-benchmarking", @@ -7109,8 +6784,8 @@ dependencies = [ "log", "parity-scale-codec", "scale-info", - "sp-runtime 32.0.0", - "sp-std 14.0.0", + "sp-runtime", + "sp-std", ] [[package]] @@ -7128,10 +6803,10 @@ dependencies = [ "scale-info", "serde", "sp-consensus-beefy", - "sp-runtime 32.0.0", + "sp-runtime", "sp-session", "sp-staking", - "sp-std 14.0.0", + "sp-std", ] [[package]] @@ -7153,11 +6828,11 @@ dependencies = [ "serde", "sp-api", "sp-consensus-beefy", - "sp-core 29.0.0", - "sp-io 31.0.0", - "sp-runtime 32.0.0", - "sp-state-machine 0.36.0", - "sp-std 14.0.0", + "sp-core", + "sp-io", + "sp-runtime", + "sp-state-machine", + "sp-std", ] [[package]] @@ -7173,10 +6848,10 @@ dependencies = [ "pallet-treasury", "parity-scale-codec", "scale-info", - "sp-core 29.0.0", - "sp-io 31.0.0", - "sp-runtime 32.0.0", - "sp-std 14.0.0", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", ] [[package]] @@ -7196,9 +6871,9 @@ dependencies = [ "parity-scale-codec", "scale-info", "sp-consensus-grandpa", - "sp-runtime 32.0.0", - "sp-std 14.0.0", - "sp-trie 30.0.0", + "sp-runtime", + "sp-std", + "sp-trie", ] [[package]] @@ -7216,8 +6891,8 @@ dependencies = [ "num-traits", "parity-scale-codec", "scale-info", - "sp-runtime 32.0.0", - "sp-std 14.0.0", + "sp-runtime", + "sp-std", ] [[package]] @@ -7237,9 +6912,9 @@ dependencies = [ "pallet-bridge-grandpa", "parity-scale-codec", "scale-info", - "sp-runtime 32.0.0", - "sp-std 14.0.0", - "sp-trie 30.0.0", + "sp-runtime", + "sp-std", + "sp-trie", ] [[package]] @@ -7258,27 +6933,28 @@ dependencies = [ "pallet-bridge-messages", "parity-scale-codec", "scale-info", - "sp-arithmetic 24.0.0", - "sp-runtime 32.0.0", - "sp-std 14.0.0", + "sp-arithmetic", + "sp-runtime", + "sp-std", ] [[package]] name = "pallet-broker" -version = "0.7.0" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd8cfe04e8c3f9ca8342ac785f2b1aee6140e1809546fc6f3a99fad20a8dfbf9" +checksum = "574c52fd629191c374c24a18036acac008ea92142309e5dd05e7f03149a667c3" dependencies = [ "bitvec", "frame-benchmarking", "frame-support", "frame-system", + "log", "parity-scale-codec", "scale-info", - "sp-arithmetic 24.0.0", - "sp-core 29.0.0", - "sp-runtime 32.0.0", - "sp-std 14.0.0", + "sp-arithmetic", + "sp-core", + "sp-runtime", + "sp-std", ] [[package]] @@ -7295,30 +6971,31 @@ dependencies = [ "pallet-treasury", "parity-scale-codec", "scale-info", - "sp-core 29.0.0", - "sp-io 31.0.0", - "sp-runtime 32.0.0", - "sp-std 14.0.0", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", ] [[package]] name = "pallet-collator-selection" -version = "10.0.0" +version = "10.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59b5ad46601c613396e92292a24c5b5d76e904c456ece9deb10913f6ea2e2999" +checksum = "49d1157d9a4b7966040158a7b4f1fb29f0cefa8deb6eb9b3452df7ce4161a31c" dependencies = [ "frame-benchmarking", "frame-support", "frame-system", "log", "pallet-authorship", + "pallet-balances", "pallet-session", "parity-scale-codec", - "rand 0.8.5", + "rand", "scale-info", - "sp-runtime 32.0.0", + "sp-runtime", "sp-staking", - "sp-std 14.0.0", + "sp-std", ] [[package]] @@ -7333,10 +7010,10 @@ dependencies = [ "log", "parity-scale-codec", "scale-info", - "sp-core 29.0.0", - "sp-io 31.0.0", - "sp-runtime 32.0.0", - "sp-std 14.0.0", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", ] [[package]] @@ -7356,16 +7033,16 @@ dependencies = [ "pallet-contracts-proc-macro", "pallet-contracts-uapi", "parity-scale-codec", - "rand 0.8.5", + "rand", "rand_pcg", "scale-info", "serde", "smallvec", "sp-api", - "sp-core 29.0.0", - "sp-io 31.0.0", - "sp-runtime 32.0.0", - "sp-std 14.0.0", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", "staging-xcm", "staging-xcm-builder", "wasm-instrument", @@ -7396,17 +7073,6 @@ dependencies = [ "scale-info", ] -[[package]] -name = "pallet-contracts-uapi-next" -version = "6.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd549c16296ea5b2eb7c65c56aba548b286c1be4d7675b424ff6ccb8319c97a9" -dependencies = [ - "bitflags 1.3.2", - "paste", - "polkavm-derive", -] - [[package]] name = "pallet-conviction-voting" version = "29.0.0" @@ -7420,9 +7086,9 @@ dependencies = [ "parity-scale-codec", "scale-info", "serde", - "sp-io 31.0.0", - "sp-runtime 32.0.0", - "sp-std 14.0.0", + "sp-io", + "sp-runtime", + "sp-std", ] [[package]] @@ -7438,10 +7104,10 @@ dependencies = [ "parity-scale-codec", "scale-info", "serde", - "sp-core 29.0.0", - "sp-io 31.0.0", - "sp-runtime 32.0.0", - "sp-std 14.0.0", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", ] [[package]] @@ -7457,14 +7123,14 @@ dependencies = [ "log", "pallet-election-provider-support-benchmarking", "parity-scale-codec", - "rand 0.8.5", + "rand", "scale-info", - "sp-arithmetic 24.0.0", - "sp-core 29.0.0", - "sp-io 31.0.0", + "sp-arithmetic", + "sp-core", + "sp-io", "sp-npos-elections", - "sp-runtime 32.0.0", - "sp-std 14.0.0", + "sp-runtime", + "sp-std", "strum 0.24.1", ] @@ -7479,8 +7145,8 @@ dependencies = [ "frame-system", "parity-scale-codec", "sp-npos-elections", - "sp-runtime 32.0.0", - "sp-std 14.0.0", + "sp-runtime", + "sp-std", ] [[package]] @@ -7495,12 +7161,12 @@ dependencies = [ "log", "parity-scale-codec", "scale-info", - "sp-core 29.0.0", - "sp-io 31.0.0", + "sp-core", + "sp-io", "sp-npos-elections", - "sp-runtime 32.0.0", + "sp-runtime", "sp-staking", - "sp-std 14.0.0", + "sp-std", ] [[package]] @@ -7517,10 +7183,10 @@ dependencies = [ "log", "parity-scale-codec", "scale-info", - "sp-io 31.0.0", - "sp-runtime 32.0.0", + "sp-io", + "sp-runtime", "sp-staking", - "sp-std 14.0.0", + "sp-std", ] [[package]] @@ -7537,21 +7203,21 @@ dependencies = [ "pallet-session", "parity-scale-codec", "scale-info", - "sp-application-crypto 31.0.0", + "sp-application-crypto", "sp-consensus-grandpa", - "sp-core 29.0.0", - "sp-io 31.0.0", - "sp-runtime 32.0.0", + "sp-core", + "sp-io", + "sp-runtime", "sp-session", "sp-staking", - "sp-std 14.0.0", + "sp-std", ] [[package]] name = "pallet-identity" -version = "29.0.0" +version = "29.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9e1cae19e30e7dc822c419988b30bb1318d79a8d5da92733822d0e84fe760ca" +checksum = "452bba25325b7f0148eeecbde13e7c26dfb677ad46b3f160b359d7643b44c94b" dependencies = [ "enumflags2", "frame-benchmarking", @@ -7560,9 +7226,9 @@ dependencies = [ "log", "parity-scale-codec", "scale-info", - "sp-io 31.0.0", - "sp-runtime 32.0.0", - "sp-std 14.0.0", + "sp-io", + "sp-runtime", + "sp-std", ] [[package]] @@ -7578,12 +7244,12 @@ dependencies = [ "pallet-authorship", "parity-scale-codec", "scale-info", - "sp-application-crypto 31.0.0", - "sp-core 29.0.0", - "sp-io 31.0.0", - "sp-runtime 32.0.0", + "sp-application-crypto", + "sp-core", + "sp-io", + "sp-runtime", "sp-staking", - "sp-std 14.0.0", + "sp-std", ] [[package]] @@ -7597,11 +7263,11 @@ dependencies = [ "frame-system", "parity-scale-codec", "scale-info", - "sp-core 29.0.0", - "sp-io 31.0.0", + "sp-core", + "sp-io", "sp-keyring", - "sp-runtime 32.0.0", - "sp-std 14.0.0", + "sp-runtime", + "sp-std", ] [[package]] @@ -7616,10 +7282,10 @@ dependencies = [ "log", "parity-scale-codec", "scale-info", - "sp-core 29.0.0", - "sp-io 31.0.0", - "sp-runtime 32.0.0", - "sp-std 14.0.0", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", ] [[package]] @@ -7635,12 +7301,12 @@ dependencies = [ "log", "parity-scale-codec", "scale-info", - "sp-arithmetic 24.0.0", - "sp-core 29.0.0", - "sp-io 31.0.0", - "sp-runtime 32.0.0", - "sp-std 14.0.0", - "sp-weights 28.0.0", + "sp-arithmetic", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", + "sp-weights", ] [[package]] @@ -7655,11 +7321,11 @@ dependencies = [ "log", "parity-scale-codec", "scale-info", - "sp-core 29.0.0", - "sp-io 31.0.0", + "sp-core", + "sp-io", "sp-mmr-primitives", - "sp-runtime 32.0.0", - "sp-std 14.0.0", + "sp-runtime", + "sp-std", ] [[package]] @@ -7674,9 +7340,9 @@ dependencies = [ "log", "parity-scale-codec", "scale-info", - "sp-io 31.0.0", - "sp-runtime 32.0.0", - "sp-std 14.0.0", + "sp-io", + "sp-runtime", + "sp-std", ] [[package]] @@ -7693,8 +7359,8 @@ dependencies = [ "pallet-nfts", "parity-scale-codec", "scale-info", - "sp-runtime 32.0.0", - "sp-std 14.0.0", + "sp-runtime", + "sp-std", ] [[package]] @@ -7710,10 +7376,10 @@ dependencies = [ "log", "parity-scale-codec", "scale-info", - "sp-core 29.0.0", - "sp-io 31.0.0", - "sp-runtime 32.0.0", - "sp-std 14.0.0", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", ] [[package]] @@ -7725,7 +7391,7 @@ dependencies = [ "pallet-nfts", "parity-scale-codec", "sp-api", - "sp-std 14.0.0", + "sp-std", ] [[package]] @@ -7739,10 +7405,10 @@ dependencies = [ "frame-system", "parity-scale-codec", "scale-info", - "sp-arithmetic 24.0.0", - "sp-core 29.0.0", - "sp-runtime 32.0.0", - "sp-std 14.0.0", + "sp-arithmetic", + "sp-core", + "sp-runtime", + "sp-std", ] [[package]] @@ -7757,12 +7423,12 @@ dependencies = [ "pallet-balances", "parity-scale-codec", "scale-info", - "sp-core 29.0.0", - "sp-io 31.0.0", - "sp-runtime 32.0.0", + "sp-core", + "sp-io", + "sp-runtime", "sp-staking", - "sp-std 14.0.0", - "sp-tracing 16.0.0", + "sp-std", + "sp-tracing", ] [[package]] @@ -7780,10 +7446,10 @@ dependencies = [ "pallet-staking", "parity-scale-codec", "scale-info", - "sp-runtime 32.0.0", - "sp-runtime-interface 25.0.0", + "sp-runtime", + "sp-runtime-interface", "sp-staking", - "sp-std 14.0.0", + "sp-std", ] [[package]] @@ -7795,7 +7461,7 @@ dependencies = [ "pallet-nomination-pools", "parity-scale-codec", "sp-api", - "sp-std 14.0.0", + "sp-std", ] [[package]] @@ -7811,9 +7477,9 @@ dependencies = [ "parity-scale-codec", "scale-info", "serde", - "sp-runtime 32.0.0", + "sp-runtime", "sp-staking", - "sp-std 14.0.0", + "sp-std", ] [[package]] @@ -7836,9 +7502,9 @@ dependencies = [ "pallet-staking", "parity-scale-codec", "scale-info", - "sp-runtime 32.0.0", + "sp-runtime", "sp-staking", - "sp-std 14.0.0", + "sp-std", ] [[package]] @@ -7853,10 +7519,10 @@ dependencies = [ "log", "parity-scale-codec", "scale-info", - "sp-core 29.0.0", - "sp-io 31.0.0", - "sp-runtime 32.0.0", - "sp-std 14.0.0", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", ] [[package]] @@ -7870,9 +7536,9 @@ dependencies = [ "frame-system", "parity-scale-codec", "scale-info", - "sp-io 31.0.0", - "sp-runtime 32.0.0", - "sp-std 14.0.0", + "sp-io", + "sp-runtime", + "sp-std", ] [[package]] @@ -7888,11 +7554,11 @@ dependencies = [ "log", "parity-scale-codec", "scale-info", - "sp-arithmetic 24.0.0", - "sp-core 29.0.0", - "sp-io 31.0.0", - "sp-runtime 32.0.0", - "sp-std 14.0.0", + "sp-arithmetic", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", ] [[package]] @@ -7906,9 +7572,9 @@ dependencies = [ "frame-system", "parity-scale-codec", "scale-info", - "sp-io 31.0.0", - "sp-runtime 32.0.0", - "sp-std 14.0.0", + "sp-io", + "sp-runtime", + "sp-std", ] [[package]] @@ -7925,10 +7591,10 @@ dependencies = [ "parity-scale-codec", "scale-info", "serde", - "sp-arithmetic 24.0.0", - "sp-io 31.0.0", - "sp-runtime 32.0.0", - "sp-std 14.0.0", + "sp-arithmetic", + "sp-io", + "sp-runtime", + "sp-std", ] [[package]] @@ -7941,10 +7607,10 @@ dependencies = [ "frame-system", "parity-scale-codec", "scale-info", - "sp-core 29.0.0", - "sp-io 31.0.0", - "sp-runtime 32.0.0", - "sp-std 14.0.0", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", ] [[package]] @@ -7960,10 +7626,10 @@ dependencies = [ "log", "parity-scale-codec", "scale-info", - "sp-io 31.0.0", - "sp-runtime 32.0.0", - "sp-std 14.0.0", - "sp-weights 28.0.0", + "sp-io", + "sp-runtime", + "sp-std", + "sp-weights", ] [[package]] @@ -7979,14 +7645,14 @@ dependencies = [ "pallet-timestamp", "parity-scale-codec", "scale-info", - "sp-core 29.0.0", - "sp-io 31.0.0", - "sp-runtime 32.0.0", + "sp-core", + "sp-io", + "sp-runtime", "sp-session", "sp-staking", - "sp-state-machine 0.36.0", - "sp-std 14.0.0", - "sp-trie 30.0.0", + "sp-state-machine", + "sp-std", + "sp-trie", ] [[package]] @@ -8001,10 +7667,10 @@ dependencies = [ "pallet-session", "pallet-staking", "parity-scale-codec", - "rand 0.8.5", - "sp-runtime 32.0.0", + "rand", + "sp-runtime", "sp-session", - "sp-std 14.0.0", + "sp-std", ] [[package]] @@ -8020,17 +7686,17 @@ dependencies = [ "parity-scale-codec", "rand_chacha 0.2.2", "scale-info", - "sp-arithmetic 24.0.0", - "sp-io 31.0.0", - "sp-runtime 32.0.0", - "sp-std 14.0.0", + "sp-arithmetic", + "sp-io", + "sp-runtime", + "sp-std", ] [[package]] name = "pallet-staking" -version = "29.0.2" +version = "29.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "668b7d28c499f0d9f295fad26cf6c342472e21842e3b13bcaaac8536358b2d6c" +checksum = "061b00814eb794a40df4eca7972a7c67b26473cd85cc7c54f5816ae49ad6e11b" dependencies = [ "frame-benchmarking", "frame-election-provider-support", @@ -8043,11 +7709,11 @@ dependencies = [ "rand_chacha 0.2.2", "scale-info", "serde", - "sp-application-crypto 31.0.0", - "sp-io 31.0.0", - "sp-runtime 32.0.0", + "sp-application-crypto", + "sp-io", + "sp-runtime", "sp-staking", - "sp-std 14.0.0", + "sp-std", ] [[package]] @@ -8069,7 +7735,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "505d45e08bad052f55fb51f00a6b6244d23ee46ffdc8091f6cddf4e3a880319d" dependencies = [ "log", - "sp-arithmetic 24.0.0", + "sp-arithmetic", ] [[package]] @@ -8095,10 +7761,10 @@ dependencies = [ "log", "parity-scale-codec", "scale-info", - "sp-core 29.0.0", - "sp-io 31.0.0", - "sp-runtime 32.0.0", - "sp-std 14.0.0", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", ] [[package]] @@ -8113,9 +7779,9 @@ dependencies = [ "frame-system", "parity-scale-codec", "scale-info", - "sp-io 31.0.0", - "sp-runtime 32.0.0", - "sp-std 14.0.0", + "sp-io", + "sp-runtime", + "sp-std", ] [[package]] @@ -8132,10 +7798,10 @@ dependencies = [ "parity-scale-codec", "scale-info", "sp-inherents", - "sp-io 31.0.0", - "sp-runtime 32.0.0", - "sp-std 14.0.0", - "sp-storage 20.0.0", + "sp-io", + "sp-runtime", + "sp-std", + "sp-storage", "sp-timestamp", ] @@ -8153,27 +7819,27 @@ dependencies = [ "parity-scale-codec", "scale-info", "serde", - "sp-core 29.0.0", - "sp-io 31.0.0", - "sp-runtime 32.0.0", - "sp-std 14.0.0", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", ] [[package]] name = "pallet-transaction-payment" -version = "29.0.0" +version = "29.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39f690f5c287ad34b28ca951ef7fae80b08cc9218d970723b7a70e4d29396872" +checksum = "0b0c408252aefe10cff96af1e54f06f45cb0dd184b4e450e9a2ecf837dfe506e" dependencies = [ "frame-support", "frame-system", "parity-scale-codec", "scale-info", "serde", - "sp-core 29.0.0", - "sp-io 31.0.0", - "sp-runtime 32.0.0", - "sp-std 14.0.0", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", ] [[package]] @@ -8187,10 +7853,10 @@ dependencies = [ "parity-scale-codec", "sp-api", "sp-blockchain", - "sp-core 29.0.0", + "sp-core", "sp-rpc", - "sp-runtime 32.0.0", - "sp-weights 28.0.0", + "sp-runtime", + "sp-weights", ] [[package]] @@ -8202,15 +7868,15 @@ dependencies = [ "pallet-transaction-payment", "parity-scale-codec", "sp-api", - "sp-runtime 32.0.0", - "sp-weights 28.0.0", + "sp-runtime", + "sp-weights", ] [[package]] name = "pallet-treasury" -version = "28.0.0" +version = "28.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1605eb5083a2cd172544f33c6e59eca2e23ac49f02f13d1562b1b8a409df9c60" +checksum = "3eca44990d0d759213744f2d1f6fe1fadec1079a3e4e4da40556d6b4e42abbcd" dependencies = [ "docify", "frame-benchmarking", @@ -8221,9 +7887,9 @@ dependencies = [ "parity-scale-codec", "scale-info", "serde", - "sp-core 29.0.0", - "sp-runtime 32.0.0", - "sp-std 14.0.0", + "sp-core", + "sp-runtime", + "sp-std", ] [[package]] @@ -8238,8 +7904,8 @@ dependencies = [ "log", "parity-scale-codec", "scale-info", - "sp-runtime 32.0.0", - "sp-std 14.0.0", + "sp-runtime", + "sp-std", ] [[package]] @@ -8253,10 +7919,10 @@ dependencies = [ "frame-system", "parity-scale-codec", "scale-info", - "sp-core 29.0.0", - "sp-io 31.0.0", - "sp-runtime 32.0.0", - "sp-std 14.0.0", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", ] [[package]] @@ -8271,8 +7937,8 @@ dependencies = [ "log", "parity-scale-codec", "scale-info", - "sp-runtime 32.0.0", - "sp-std 14.0.0", + "sp-runtime", + "sp-std", ] [[package]] @@ -8287,15 +7953,15 @@ dependencies = [ "parity-scale-codec", "scale-info", "sp-api", - "sp-runtime 32.0.0", - "sp-std 14.0.0", + "sp-runtime", + "sp-std", ] [[package]] name = "pallet-xcm" -version = "8.0.1" +version = "8.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b0bade2eb6ce40af35a5af150692b4e150638f7f68c15735ab9cdf79650d68e" +checksum = "ba9138b04168b07b1aff4a2079f5514753c31dddba40e5fb471b9cda7da27ad6" dependencies = [ "bounded-collections 0.2.0", "frame-benchmarking", @@ -8306,10 +7972,10 @@ dependencies = [ "parity-scale-codec", "scale-info", "serde", - "sp-core 29.0.0", - "sp-io 31.0.0", - "sp-runtime 32.0.0", - "sp-std 14.0.0", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", "staging-xcm", "staging-xcm-builder", "staging-xcm-executor", @@ -8327,9 +7993,9 @@ dependencies = [ "log", "parity-scale-codec", "scale-info", - "sp-io 31.0.0", - "sp-runtime 32.0.0", - "sp-std 14.0.0", + "sp-io", + "sp-runtime", + "sp-std", "staging-xcm", "staging-xcm-builder", "staging-xcm-executor", @@ -8348,9 +8014,9 @@ dependencies = [ "log", "parity-scale-codec", "scale-info", - "sp-core 29.0.0", - "sp-runtime 32.0.0", - "sp-std 14.0.0", + "sp-core", + "sp-runtime", + "sp-std", "staging-xcm", "staging-xcm-builder", ] @@ -8377,10 +8043,10 @@ dependencies = [ "polkadot-primitives", "scale-info", "sp-consensus-aura", - "sp-core 29.0.0", - "sp-io 31.0.0", - "sp-runtime 32.0.0", - "sp-std 14.0.0", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", "staging-parachain-info", "staging-xcm", "staging-xcm-executor", @@ -8407,11 +8073,11 @@ dependencies = [ "parity-scale-codec", "polkadot-parachain-primitives", "sp-consensus-aura", - "sp-core 29.0.0", - "sp-io 31.0.0", - "sp-runtime 32.0.0", - "sp-std 14.0.0", - "sp-tracing 16.0.0", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", + "sp-tracing", "staging-parachain-info", "staging-xcm", "staging-xcm-executor", @@ -8439,7 +8105,7 @@ dependencies = [ "lz4", "memmap2 0.5.10", "parking_lot 0.12.1", - "rand 0.8.5", + "rand", "siphasher 0.3.11", "snap", "winapi", @@ -8504,7 +8170,7 @@ checksum = "f557c32c6d268a07c921471619c0295f5efad3a0e76d4f97a05c091a51d110b2" dependencies = [ "proc-macro2", "syn 1.0.109", - "synstructure 0.12.6", + "synstructure", ] [[package]] @@ -8590,18 +8256,9 @@ dependencies = [ [[package]] name = "pbkdf2" -version = "0.11.0" +version = "0.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83a0692ec44e4cf1ef28ca317f14f8f07da2d95ec3fa01f86e4467b725e60917" -dependencies = [ - "digest 0.10.7", -] - -[[package]] -name = "pbkdf2" -version = "0.12.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8ed6a7761f76e3b9f92dfb0a60a6a6477c61024b775147ff0973a02653abaf2" +checksum = "f8ed6a7761f76e3b9f92dfb0a60a6a6477c61024b775147ff0973a02653abaf2" dependencies = [ "digest 0.10.7", ] @@ -8770,7 +8427,7 @@ dependencies = [ "polkadot-node-subsystem", "polkadot-node-subsystem-util", "polkadot-primitives", - "rand 0.8.5", + "rand", "tracing-gum", ] @@ -8787,7 +8444,7 @@ dependencies = [ "polkadot-node-subsystem", "polkadot-node-subsystem-util", "polkadot-primitives", - "rand 0.8.5", + "rand", "tracing-gum", ] @@ -8807,10 +8464,10 @@ dependencies = [ "polkadot-node-subsystem", "polkadot-node-subsystem-util", "polkadot-primitives", - "rand 0.8.5", + "rand", "schnellru", - "sp-core 29.0.0", - "sp-keystore 0.35.0", + "sp-core", + "sp-keystore", "thiserror", "tracing-gum", ] @@ -8831,7 +8488,7 @@ dependencies = [ "polkadot-node-subsystem", "polkadot-node-subsystem-util", "polkadot-primitives", - "rand 0.8.5", + "rand", "sc-network", "schnellru", "thiserror", @@ -8859,8 +8516,8 @@ dependencies = [ "sc-storage-monitor", "sc-sysinfo", "sc-tracing", - "sp-core 29.0.0", - "sp-io 31.0.0", + "sp-core", + "sp-io", "sp-keyring", "sp-maybe-compressed-blob", "substrate-build-script-utils", @@ -8883,9 +8540,9 @@ dependencies = [ "polkadot-node-subsystem", "polkadot-node-subsystem-util", "polkadot-primitives", - "sp-core 29.0.0", - "sp-keystore 0.35.0", - "sp-runtime 32.0.0", + "sp-core", + "sp-keystore", + "sp-runtime", "thiserror", "tokio-util", "tracing-gum", @@ -8899,9 +8556,9 @@ checksum = "b6a08e4e014c853b252ecbbe3ccd67b2d33d78e46988d309b8cccf4ac06e25ef" dependencies = [ "parity-scale-codec", "scale-info", - "sp-core 29.0.0", - "sp-runtime 32.0.0", - "sp-std 14.0.0", + "sp-core", + "sp-runtime", + "sp-std", ] [[package]] @@ -8924,8 +8581,8 @@ dependencies = [ "polkadot-primitives", "sc-network", "schnellru", - "sp-application-crypto 31.0.0", - "sp-keystore 0.35.0", + "sp-application-crypto", + "sp-keystore", "thiserror", "tracing-gum", ] @@ -8940,8 +8597,8 @@ dependencies = [ "polkadot-node-primitives", "polkadot-primitives", "reed-solomon-novelpoly", - "sp-core 29.0.0", - "sp-trie 30.0.0", + "sp-core", + "sp-trie", "thiserror", ] @@ -8957,14 +8614,14 @@ dependencies = [ "polkadot-node-subsystem", "polkadot-node-subsystem-util", "polkadot-primitives", - "rand 0.8.5", + "rand", "rand_chacha 0.3.1", "sc-network", "sc-network-common", - "sp-application-crypto 31.0.0", - "sp-core 29.0.0", + "sp-application-crypto", + "sp-core", "sp-crypto-hashing", - "sp-keystore 0.35.0", + "sp-keystore", "tracing-gum", ] @@ -9005,7 +8662,7 @@ dependencies = [ "polkadot-node-subsystem", "polkadot-node-subsystem-util", "polkadot-primitives", - "sp-core 29.0.0", + "sp-core", "sp-maybe-compressed-blob", "thiserror", "tracing-gum", @@ -9023,7 +8680,7 @@ dependencies = [ "futures-timer", "itertools 0.10.5", "kvdb", - "merlin 3.0.0", + "merlin", "parity-scale-codec", "polkadot-node-jaeger", "polkadot-node-primitives", @@ -9031,16 +8688,16 @@ dependencies = [ "polkadot-node-subsystem-util", "polkadot-overseer", "polkadot-primitives", - "rand 0.8.5", + "rand", "rand_chacha 0.3.1", "rand_core 0.6.4", "sc-keystore", "schnellru", "schnorrkel 0.11.4", - "sp-application-crypto 31.0.0", + "sp-application-crypto", "sp-consensus", "sp-consensus-slots", - "sp-runtime 32.0.0", + "sp-runtime", "thiserror", "tracing-gum", ] @@ -9084,7 +8741,7 @@ dependencies = [ "polkadot-primitives", "polkadot-statement-table", "schnellru", - "sp-keystore 0.35.0", + "sp-keystore", "thiserror", "tracing-gum", ] @@ -9099,7 +8756,7 @@ dependencies = [ "polkadot-node-subsystem", "polkadot-node-subsystem-util", "polkadot-primitives", - "sp-keystore 0.35.0", + "sp-keystore", "thiserror", "tracing-gum", "wasm-timer", @@ -9257,11 +8914,11 @@ dependencies = [ "polkadot-node-subsystem", "polkadot-parachain-primitives", "polkadot-primitives", - "rand 0.8.5", + "rand", "slotmap", - "sp-core 29.0.0", + "sp-core", "sp-maybe-compressed-blob", - "sp-wasm-interface 20.0.0", + "sp-wasm-interface", "tempfile", "thiserror", "tokio", @@ -9280,7 +8937,7 @@ dependencies = [ "polkadot-node-subsystem-util", "polkadot-overseer", "polkadot-primitives", - "sp-keystore 0.35.0", + "sp-keystore", "thiserror", "tracing-gum", ] @@ -9304,11 +8961,11 @@ dependencies = [ "sc-executor-common", "sc-executor-wasmtime", "seccompiler", - "sp-core 29.0.0", + "sp-core", "sp-crypto-hashing", - "sp-externalities 0.26.0", - "sp-io 31.0.0", - "sp-tracing 16.0.0", + "sp-externalities", + "sp-io", + "sp-tracing", "thiserror", "tracing-gum", ] @@ -9343,7 +9000,7 @@ dependencies = [ "polkadot-node-primitives", "polkadot-primitives", "sc-network", - "sp-core 29.0.0", + "sp-core", "thiserror", "tokio", ] @@ -9385,7 +9042,7 @@ dependencies = [ "polkadot-node-jaeger", "polkadot-node-primitives", "polkadot-primitives", - "rand 0.8.5", + "rand", "sc-authority-discovery", "sc-network", "strum 0.24.1", @@ -9407,12 +9064,12 @@ dependencies = [ "polkadot-primitives", "schnorrkel 0.11.4", "serde", - "sp-application-crypto 31.0.0", + "sp-application-crypto", "sp-consensus-babe", - "sp-core 29.0.0", - "sp-keystore 0.35.0", + "sp-core", + "sp-keystore", "sp-maybe-compressed-blob", - "sp-runtime 32.0.0", + "sp-runtime", "thiserror", "zstd 0.12.4", ] @@ -9452,7 +9109,7 @@ dependencies = [ "sp-authority-discovery", "sp-blockchain", "sp-consensus-babe", - "sp-runtime 32.0.0", + "sp-runtime", "substrate-prometheus-endpoint", "thiserror", ] @@ -9483,12 +9140,12 @@ dependencies = [ "polkadot-overseer", "polkadot-primitives", "prioritized-metered-channel", - "rand 0.8.5", + "rand", "sc-client-api", "schnellru", - "sp-application-crypto 31.0.0", - "sp-core 29.0.0", - "sp-keystore 0.35.0", + "sp-application-crypto", + "sp-core", + "sp-keystore", "thiserror", "tracing-gum", ] @@ -9511,7 +9168,7 @@ dependencies = [ "polkadot-primitives", "sc-client-api", "sp-api", - "sp-core 29.0.0", + "sp-core", "tikv-jemalloc-ctl", "tracing-gum", ] @@ -9528,10 +9185,10 @@ dependencies = [ "polkadot-core-primitives", "scale-info", "serde", - "sp-core 29.0.0", - "sp-runtime 32.0.0", - "sp-std 14.0.0", - "sp-weights 28.0.0", + "sp-core", + "sp-runtime", + "sp-std", + "sp-weights", ] [[package]] @@ -9549,17 +9206,17 @@ dependencies = [ "scale-info", "serde", "sp-api", - "sp-application-crypto 31.0.0", - "sp-arithmetic 24.0.0", + "sp-application-crypto", + "sp-arithmetic", "sp-authority-discovery", "sp-consensus-slots", - "sp-core 29.0.0", + "sp-core", "sp-inherents", - "sp-io 31.0.0", - "sp-keystore 0.35.0", - "sp-runtime 32.0.0", + "sp-io", + "sp-keystore", + "sp-runtime", "sp-staking", - "sp-std 14.0.0", + "sp-std", ] [[package]] @@ -9590,17 +9247,17 @@ dependencies = [ "sp-blockchain", "sp-consensus", "sp-consensus-babe", - "sp-keystore 0.35.0", - "sp-runtime 32.0.0", + "sp-keystore", + "sp-runtime", "substrate-frame-rpc-system", "substrate-state-trie-migration-rpc", ] [[package]] name = "polkadot-runtime-common" -version = "8.0.1" +version = "8.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06afbb3bd10245ad1907242a98ddffc3c0c1e209738b8382bc5bcfc1f28c0429" +checksum = "d815f0ff0a69dce7235d42c6e7d5e2b8b7429cba1252b4802ddc7879e2e74d4a" dependencies = [ "bitvec", "frame-benchmarking", @@ -9634,14 +9291,14 @@ dependencies = [ "serde_derive", "slot-range-helper", "sp-api", - "sp-core 29.0.0", + "sp-core", "sp-inherents", - "sp-io 31.0.0", + "sp-io", "sp-npos-elections", - "sp-runtime 32.0.0", + "sp-runtime", "sp-session", "sp-staking", - "sp-std 14.0.0", + "sp-std", "staging-xcm", "staging-xcm-builder", "staging-xcm-executor", @@ -9658,15 +9315,15 @@ dependencies = [ "frame-benchmarking", "parity-scale-codec", "polkadot-primitives", - "sp-std 14.0.0", - "sp-tracing 16.0.0", + "sp-std", + "sp-tracing", ] [[package]] name = "polkadot-runtime-parachains" -version = "8.0.1" +version = "8.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9bcfd672be236fd1c38c702e7e99fe3f3e54df0ddb8127e542423221d1f50669" +checksum = "b8d37cd3e014b06daf396d1483b5327782a0ebadc816423419665166b75b3e3e" dependencies = [ "bitflags 1.3.2", "bitvec", @@ -9691,22 +9348,22 @@ dependencies = [ "polkadot-parachain-primitives", "polkadot-primitives", "polkadot-runtime-metrics", - "rand 0.8.5", + "rand", "rand_chacha 0.3.1", "rustc-hex", "scale-info", "serde", "sp-api", - "sp-application-crypto 31.0.0", - "sp-arithmetic 24.0.0", - "sp-core 29.0.0", + "sp-application-crypto", + "sp-arithmetic", + "sp-core", "sp-inherents", - "sp-io 31.0.0", - "sp-keystore 0.35.0", - "sp-runtime 32.0.0", + "sp-io", + "sp-keystore", + "sp-runtime", "sp-session", "sp-staking", - "sp-std 14.0.0", + "sp-std", "staging-xcm", "staging-xcm-executor", "static_assertions", @@ -9809,21 +9466,21 @@ dependencies = [ "sp-consensus-babe", "sp-consensus-beefy", "sp-consensus-grandpa", - "sp-core 29.0.0", + "sp-core", "sp-inherents", - "sp-io 31.0.0", + "sp-io", "sp-keyring", - "sp-keystore 0.35.0", + "sp-keystore", "sp-mmr-primitives", "sp-offchain", - "sp-runtime 32.0.0", + "sp-runtime", "sp-session", - "sp-state-machine 0.36.0", - "sp-storage 20.0.0", + "sp-state-machine", + "sp-storage", "sp-timestamp", "sp-transaction-pool", "sp-version", - "sp-weights 28.0.0", + "sp-weights", "substrate-prometheus-endpoint", "thiserror", "tracing-gum", @@ -9848,7 +9505,7 @@ dependencies = [ "polkadot-node-subsystem", "polkadot-node-subsystem-util", "polkadot-primitives", - "sp-keystore 0.35.0", + "sp-keystore", "sp-staking", "thiserror", "tracing-gum", @@ -9862,7 +9519,7 @@ checksum = "de5e010da3c6a65d8f263d0f825a04d995ffc8a37f886f674fcbbc73bf158d01" dependencies = [ "parity-scale-codec", "polkadot-primitives", - "sp-core 29.0.0", + "sp-core", "tracing-gum", ] @@ -9948,19 +9605,6 @@ dependencies = [ "universal-hash", ] -[[package]] -name = "pop-api" -version = "0.0.0" -dependencies = [ - "enumflags2", - "ink", - "parity-scale-codec", - "pop-primitives", - "scale-info", - "sp-io 23.0.0", - "sp-runtime 24.0.0", -] - [[package]] name = "pop-node" version = "0.1.0-alpha" @@ -10011,11 +9655,11 @@ dependencies = [ "sp-block-builder", "sp-blockchain", "sp-consensus-aura", - "sp-core 29.0.0", - "sp-io 31.0.0", - "sp-keystore 0.35.0", + "sp-core", + "sp-io", + "sp-keystore", "sp-offchain", - "sp-runtime 32.0.0", + "sp-runtime", "sp-session", "sp-timestamp", "sp-transaction-pool", @@ -10045,8 +9689,8 @@ dependencies = [ "parity-scale-codec", "polkadot-primitives", "scale-info", - "sp-runtime 32.0.0", - "sp-std 14.0.0", + "sp-runtime", + "sp-std", ] [[package]] @@ -10098,7 +9742,6 @@ dependencies = [ "parity-scale-codec", "polkadot-parachain-primitives", "polkadot-runtime-common", - "pop-api", "pop-primitives", "pop-runtime-common", "scale-info", @@ -10106,14 +9749,14 @@ dependencies = [ "sp-api", "sp-block-builder", "sp-consensus-aura", - "sp-core 29.0.0", + "sp-core", "sp-genesis-builder", "sp-inherents", - "sp-io 31.0.0", + "sp-io", "sp-offchain", - "sp-runtime 32.0.0", + "sp-runtime", "sp-session", - "sp-std 14.0.0", + "sp-std", "sp-transaction-pool", "sp-version", "staging-parachain-info", @@ -10179,14 +9822,14 @@ dependencies = [ "sp-api", "sp-block-builder", "sp-consensus-aura", - "sp-core 29.0.0", + "sp-core", "sp-genesis-builder", "sp-inherents", - "sp-io 31.0.0", + "sp-io", "sp-offchain", - "sp-runtime 32.0.0", + "sp-runtime", "sp-session", - "sp-std 14.0.0", + "sp-std", "sp-transaction-pool", "sp-version", "staging-parachain-info", @@ -10546,7 +10189,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94b0b33c13a79f669c85defaf4c275dc86a0c0372807d0ca3d78e0bb87274863" dependencies = [ "bytes", - "rand 0.8.5", + "rand", "ring 0.16.20", "rustc-hash", "rustls 0.20.9", @@ -10572,19 +10215,6 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" -[[package]] -name = "rand" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" -dependencies = [ - "getrandom 0.1.16", - "libc", - "rand_chacha 0.2.2", - "rand_core 0.5.1", - "rand_hc", -] - [[package]] name = "rand" version = "0.8.5" @@ -10641,16 +10271,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32cb0b9bc82b0a0876c2dd994a7e7a2683d3e7390ca40e6886785ef0c7e3ee31" dependencies = [ "num-traits", - "rand 0.8.5", -] - -[[package]] -name = "rand_hc" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" -dependencies = [ - "rand_core 0.5.1", + "rand", ] [[package]] @@ -10876,12 +10497,6 @@ dependencies = [ "digest 0.10.7", ] -[[package]] -name = "rlibc" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc874b127765f014d792f16763a81245ab80500e2ad921ed4ee9e82481ee08fe" - [[package]] name = "rlp" version = "0.5.2" @@ -10974,22 +10589,22 @@ dependencies = [ "serde_derive", "smallvec", "sp-api", - "sp-arithmetic 24.0.0", + "sp-arithmetic", "sp-authority-discovery", "sp-block-builder", "sp-consensus-babe", "sp-consensus-beefy", - "sp-core 29.0.0", + "sp-core", "sp-genesis-builder", "sp-inherents", - "sp-io 31.0.0", + "sp-io", "sp-mmr-primitives", "sp-offchain", - "sp-runtime 32.0.0", + "sp-runtime", "sp-session", "sp-staking", - "sp-std 14.0.0", - "sp-storage 20.0.0", + "sp-std", + "sp-storage", "sp-transaction-pool", "sp-version", "staging-xcm", @@ -11009,9 +10624,9 @@ dependencies = [ "polkadot-primitives", "polkadot-runtime-common", "smallvec", - "sp-core 29.0.0", - "sp-runtime 32.0.0", - "sp-weights 28.0.0", + "sp-core", + "sp-runtime", + "sp-weights", "staging-xcm", "staging-xcm-builder", ] @@ -11314,8 +10929,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "357127c91373ed6d1ae582f6e3300ab5b13bcde43bbf270a891f44194ef48b70" dependencies = [ "log", - "sp-core 29.0.0", - "sp-wasm-interface 20.0.0", + "sp-core", + "sp-wasm-interface", "thiserror", ] @@ -11336,15 +10951,15 @@ dependencies = [ "parity-scale-codec", "prost 0.12.3", "prost-build", - "rand 0.8.5", + "rand", "sc-client-api", "sc-network", "sp-api", "sp-authority-discovery", "sp-blockchain", - "sp-core 29.0.0", - "sp-keystore 0.35.0", - "sp-runtime 32.0.0", + "sp-core", + "sp-keystore", + "sp-runtime", "substrate-prometheus-endpoint", "thiserror", ] @@ -11366,9 +10981,9 @@ dependencies = [ "sp-api", "sp-blockchain", "sp-consensus", - "sp-core 29.0.0", + "sp-core", "sp-inherents", - "sp-runtime 32.0.0", + "sp-runtime", "substrate-prometheus-endpoint", ] @@ -11382,10 +10997,10 @@ dependencies = [ "sp-api", "sp-block-builder", "sp-blockchain", - "sp-core 29.0.0", + "sp-core", "sp-inherents", - "sp-runtime 32.0.0", - "sp-trie 30.0.0", + "sp-runtime", + "sp-trie", ] [[package]] @@ -11407,12 +11022,12 @@ dependencies = [ "serde", "serde_json", "sp-blockchain", - "sp-core 29.0.0", + "sp-core", "sp-crypto-hashing", "sp-genesis-builder", - "sp-io 31.0.0", - "sp-runtime 32.0.0", - "sp-state-machine 0.36.0", + "sp-io", + "sp-runtime", + "sp-state-machine", ] [[package]] @@ -11444,7 +11059,7 @@ dependencies = [ "log", "names", "parity-scale-codec", - "rand 0.8.5", + "rand", "regex", "rpassword", "sc-client-api", @@ -11459,11 +11074,11 @@ dependencies = [ "serde", "serde_json", "sp-blockchain", - "sp-core 29.0.0", + "sp-core", "sp-keyring", - "sp-keystore 0.35.0", - "sp-panic-handler 13.0.0", - "sp-runtime 32.0.0", + "sp-keystore", + "sp-panic-handler", + "sp-runtime", "sp-version", "thiserror", "tokio", @@ -11486,14 +11101,14 @@ dependencies = [ "sp-api", "sp-blockchain", "sp-consensus", - "sp-core 29.0.0", + "sp-core", "sp-database", - "sp-externalities 0.26.0", - "sp-runtime 32.0.0", - "sp-state-machine 0.36.0", + "sp-externalities", + "sp-runtime", + "sp-state-machine", "sp-statement-store", - "sp-storage 20.0.0", - "sp-trie 30.0.0", + "sp-storage", + "sp-trie", "substrate-prometheus-endpoint", ] @@ -11515,13 +11130,13 @@ dependencies = [ "sc-client-api", "sc-state-db", "schnellru", - "sp-arithmetic 24.0.0", + "sp-arithmetic", "sp-blockchain", - "sp-core 29.0.0", + "sp-core", "sp-database", - "sp-runtime 32.0.0", - "sp-state-machine 0.36.0", - "sp-trie 30.0.0", + "sp-runtime", + "sp-state-machine", + "sp-trie", ] [[package]] @@ -11543,9 +11158,9 @@ dependencies = [ "sp-api", "sp-blockchain", "sp-consensus", - "sp-core 29.0.0", - "sp-runtime 32.0.0", - "sp-state-machine 0.36.0", + "sp-core", + "sp-runtime", + "sp-state-machine", "substrate-prometheus-endpoint", "thiserror", ] @@ -11566,16 +11181,16 @@ dependencies = [ "sc-consensus-slots", "sc-telemetry", "sp-api", - "sp-application-crypto 31.0.0", + "sp-application-crypto", "sp-block-builder", "sp-blockchain", "sp-consensus", "sp-consensus-aura", "sp-consensus-slots", - "sp-core 29.0.0", + "sp-core", "sp-inherents", - "sp-keystore 0.35.0", - "sp-runtime 32.0.0", + "sp-keystore", + "sp-runtime", "substrate-prometheus-endpoint", "thiserror", ] @@ -11602,17 +11217,17 @@ dependencies = [ "sc-telemetry", "sc-transaction-pool-api", "sp-api", - "sp-application-crypto 31.0.0", + "sp-application-crypto", "sp-block-builder", "sp-blockchain", "sp-consensus", "sp-consensus-babe", "sp-consensus-slots", - "sp-core 29.0.0", + "sp-core", "sp-crypto-hashing", "sp-inherents", - "sp-keystore 0.35.0", - "sp-runtime 32.0.0", + "sp-keystore", + "sp-runtime", "substrate-prometheus-endpoint", "thiserror", ] @@ -11630,13 +11245,13 @@ dependencies = [ "sc-rpc-api", "serde", "sp-api", - "sp-application-crypto 31.0.0", + "sp-application-crypto", "sp-blockchain", "sp-consensus", "sp-consensus-babe", - "sp-core 29.0.0", - "sp-keystore 0.35.0", - "sp-runtime 32.0.0", + "sp-core", + "sp-keystore", + "sp-runtime", "thiserror", ] @@ -11661,16 +11276,16 @@ dependencies = [ "sc-network-sync", "sc-utils", "sp-api", - "sp-application-crypto 31.0.0", - "sp-arithmetic 24.0.0", + "sp-application-crypto", + "sp-arithmetic", "sp-blockchain", "sp-consensus", "sp-consensus-beefy", - "sp-core 29.0.0", + "sp-core", "sp-crypto-hashing", - "sp-keystore 0.35.0", + "sp-keystore", "sp-mmr-primitives", - "sp-runtime 32.0.0", + "sp-runtime", "substrate-prometheus-endpoint", "thiserror", "tokio", @@ -11692,8 +11307,8 @@ dependencies = [ "sc-rpc", "serde", "sp-consensus-beefy", - "sp-core 29.0.0", - "sp-runtime 32.0.0", + "sp-core", + "sp-runtime", "thiserror", ] @@ -11708,7 +11323,7 @@ dependencies = [ "sc-client-api", "sc-consensus", "sp-blockchain", - "sp-runtime 32.0.0", + "sp-runtime", ] [[package]] @@ -11728,7 +11343,7 @@ dependencies = [ "log", "parity-scale-codec", "parking_lot 0.12.1", - "rand 0.8.5", + "rand", "sc-block-builder", "sc-chain-spec", "sc-client-api", @@ -11742,15 +11357,15 @@ dependencies = [ "sc-utils", "serde_json", "sp-api", - "sp-application-crypto 31.0.0", - "sp-arithmetic 24.0.0", + "sp-application-crypto", + "sp-arithmetic", "sp-blockchain", "sp-consensus", "sp-consensus-grandpa", - "sp-core 29.0.0", + "sp-core", "sp-crypto-hashing", - "sp-keystore 0.35.0", - "sp-runtime 32.0.0", + "sp-keystore", + "sp-runtime", "substrate-prometheus-endpoint", "thiserror", ] @@ -11771,8 +11386,8 @@ dependencies = [ "sc-rpc", "serde", "sp-blockchain", - "sp-core 29.0.0", - "sp-runtime 32.0.0", + "sp-core", + "sp-runtime", "thiserror", ] @@ -11790,14 +11405,14 @@ dependencies = [ "sc-client-api", "sc-consensus", "sc-telemetry", - "sp-arithmetic 24.0.0", + "sp-arithmetic", "sp-blockchain", "sp-consensus", "sp-consensus-slots", - "sp-core 29.0.0", + "sp-core", "sp-inherents", - "sp-runtime 32.0.0", - "sp-state-machine 0.36.0", + "sp-runtime", + "sp-state-machine", ] [[package]] @@ -11812,14 +11427,14 @@ dependencies = [ "sc-executor-wasmtime", "schnellru", "sp-api", - "sp-core 29.0.0", - "sp-externalities 0.26.0", - "sp-io 31.0.0", - "sp-panic-handler 13.0.0", - "sp-runtime-interface 25.0.0", - "sp-trie 30.0.0", + "sp-core", + "sp-externalities", + "sp-io", + "sp-panic-handler", + "sp-runtime-interface", + "sp-trie", "sp-version", - "sp-wasm-interface 20.0.0", + "sp-wasm-interface", "tracing", ] @@ -11831,7 +11446,7 @@ checksum = "07498138dee3ddf2c71299ca372d8449880bb3a8a8a299a483094e9c26b0823e" dependencies = [ "sc-allocator", "sp-maybe-compressed-blob", - "sp-wasm-interface 20.0.0", + "sp-wasm-interface", "thiserror", "wasm-instrument", ] @@ -11850,8 +11465,8 @@ dependencies = [ "rustix 0.36.17", "sc-allocator", "sc-executor-common", - "sp-runtime-interface 25.0.0", - "sp-wasm-interface 20.0.0", + "sp-runtime-interface", + "sp-wasm-interface", "wasmtime", ] @@ -11870,7 +11485,7 @@ dependencies = [ "sc-network-common", "sc-network-sync", "sp-blockchain", - "sp-runtime 32.0.0", + "sp-runtime", ] [[package]] @@ -11882,9 +11497,9 @@ dependencies = [ "array-bytes 6.2.2", "parking_lot 0.12.1", "serde_json", - "sp-application-crypto 31.0.0", - "sp-core 29.0.0", - "sp-keystore 0.35.0", + "sp-application-crypto", + "sp-core", + "sp-keystore", "thiserror", ] @@ -11911,10 +11526,10 @@ dependencies = [ "sc-transaction-pool-api", "sp-api", "sp-consensus", - "sp-core 29.0.0", - "sp-keystore 0.35.0", + "sp-core", + "sp-keystore", "sp-mixnet", - "sp-runtime 32.0.0", + "sp-runtime", "thiserror", ] @@ -11942,17 +11557,17 @@ dependencies = [ "parking_lot 0.12.1", "partial_sort", "pin-project", - "rand 0.8.5", + "rand", "sc-client-api", "sc-network-common", "sc-utils", "serde", "serde_json", "smallvec", - "sp-arithmetic 24.0.0", + "sp-arithmetic", "sp-blockchain", - "sp-core 29.0.0", - "sp-runtime 32.0.0", + "sp-core", + "sp-runtime", "substrate-prometheus-endpoint", "thiserror", "tokio", @@ -11978,7 +11593,7 @@ dependencies = [ "sc-client-api", "sc-network", "sp-blockchain", - "sp-runtime 32.0.0", + "sp-runtime", "thiserror", "unsigned-varint", ] @@ -11998,7 +11613,7 @@ dependencies = [ "sc-consensus", "sp-consensus", "sp-consensus-grandpa", - "sp-runtime 32.0.0", + "sp-runtime", ] [[package]] @@ -12016,7 +11631,7 @@ dependencies = [ "sc-network-common", "sc-network-sync", "schnellru", - "sp-runtime 32.0.0", + "sp-runtime", "substrate-prometheus-endpoint", "tracing", ] @@ -12038,8 +11653,8 @@ dependencies = [ "sc-client-api", "sc-network", "sp-blockchain", - "sp-core 29.0.0", - "sp-runtime 32.0.0", + "sp-core", + "sp-runtime", "thiserror", ] @@ -12068,12 +11683,12 @@ dependencies = [ "sc-utils", "schnellru", "smallvec", - "sp-arithmetic 24.0.0", + "sp-arithmetic", "sp-blockchain", "sp-consensus", "sp-consensus-grandpa", - "sp-core 29.0.0", - "sp-runtime 32.0.0", + "sp-core", + "sp-runtime", "substrate-prometheus-endpoint", "thiserror", "tokio", @@ -12096,7 +11711,7 @@ dependencies = [ "sc-network-sync", "sc-utils", "sp-consensus", - "sp-runtime 32.0.0", + "sp-runtime", "substrate-prometheus-endpoint", ] @@ -12119,18 +11734,18 @@ dependencies = [ "once_cell", "parity-scale-codec", "parking_lot 0.12.1", - "rand 0.8.5", + "rand", "sc-client-api", "sc-network", "sc-network-common", "sc-transaction-pool-api", "sc-utils", "sp-api", - "sp-core 29.0.0", - "sp-externalities 0.26.0", - "sp-keystore 0.35.0", + "sp-core", + "sp-externalities", + "sp-keystore", "sp-offchain", - "sp-runtime 32.0.0", + "sp-runtime", "threadpool", "tracing", ] @@ -12167,11 +11782,11 @@ dependencies = [ "serde_json", "sp-api", "sp-blockchain", - "sp-core 29.0.0", - "sp-keystore 0.35.0", + "sp-core", + "sp-keystore", "sp-offchain", "sp-rpc", - "sp-runtime 32.0.0", + "sp-runtime", "sp-session", "sp-statement-store", "sp-version", @@ -12192,9 +11807,9 @@ dependencies = [ "scale-info", "serde", "serde_json", - "sp-core 29.0.0", + "sp-core", "sp-rpc", - "sp-runtime 32.0.0", + "sp-runtime", "sp-version", "thiserror", ] @@ -12237,9 +11852,9 @@ dependencies = [ "serde", "sp-api", "sp-blockchain", - "sp-core 29.0.0", + "sp-core", "sp-rpc", - "sp-runtime 32.0.0", + "sp-runtime", "sp-version", "thiserror", "tokio", @@ -12262,7 +11877,7 @@ dependencies = [ "parity-scale-codec", "parking_lot 0.12.1", "pin-project", - "rand 0.8.5", + "rand", "sc-chain-spec", "sc-client-api", "sc-client-db", @@ -12290,16 +11905,16 @@ dependencies = [ "sp-api", "sp-blockchain", "sp-consensus", - "sp-core 29.0.0", - "sp-externalities 0.26.0", - "sp-keystore 0.35.0", - "sp-runtime 32.0.0", + "sp-core", + "sp-externalities", + "sp-keystore", + "sp-runtime", "sp-session", - "sp-state-machine 0.36.0", - "sp-storage 20.0.0", + "sp-state-machine", + "sp-storage", "sp-transaction-pool", "sp-transaction-storage-proof", - "sp-trie 30.0.0", + "sp-trie", "sp-version", "static_init", "substrate-prometheus-endpoint", @@ -12319,7 +11934,7 @@ dependencies = [ "log", "parity-scale-codec", "parking_lot 0.12.1", - "sp-core 29.0.0", + "sp-core", ] [[package]] @@ -12331,7 +11946,7 @@ dependencies = [ "clap", "fs4", "log", - "sp-core 29.0.0", + "sp-core", "thiserror", "tokio", ] @@ -12352,7 +11967,7 @@ dependencies = [ "serde", "serde_json", "sp-blockchain", - "sp-runtime 32.0.0", + "sp-runtime", "thiserror", ] @@ -12366,16 +11981,16 @@ dependencies = [ "futures", "libc", "log", - "rand 0.8.5", + "rand", "rand_pcg", "regex", "sc-telemetry", "serde", "serde_json", - "sp-core 29.0.0", + "sp-core", "sp-crypto-hashing", - "sp-io 31.0.0", - "sp-std 14.0.0", + "sp-io", + "sp-std", ] [[package]] @@ -12390,7 +12005,7 @@ dependencies = [ "log", "parking_lot 0.12.1", "pin-project", - "rand 0.8.5", + "rand", "sc-utils", "serde", "serde_json", @@ -12419,10 +12034,10 @@ dependencies = [ "serde", "sp-api", "sp-blockchain", - "sp-core 29.0.0", + "sp-core", "sp-rpc", - "sp-runtime 32.0.0", - "sp-tracing 16.0.0", + "sp-runtime", + "sp-tracing", "thiserror", "tracing", "tracing-log 0.1.4", @@ -12460,10 +12075,10 @@ dependencies = [ "serde", "sp-api", "sp-blockchain", - "sp-core 29.0.0", + "sp-core", "sp-crypto-hashing", - "sp-runtime 32.0.0", - "sp-tracing 16.0.0", + "sp-runtime", + "sp-tracing", "sp-transaction-pool", "substrate-prometheus-endpoint", "thiserror", @@ -12481,8 +12096,8 @@ dependencies = [ "parity-scale-codec", "serde", "sp-blockchain", - "sp-core 29.0.0", - "sp-runtime 32.0.0", + "sp-core", + "sp-runtime", "thiserror", ] @@ -12499,7 +12114,7 @@ dependencies = [ "log", "parking_lot 0.12.1", "prometheus", - "sp-arithmetic 24.0.0", + "sp-arithmetic", ] [[package]] @@ -12580,7 +12195,6 @@ dependencies = [ "derive_more", "parity-scale-codec", "scale-info-derive", - "schemars", "serde", ] @@ -12638,30 +12252,6 @@ dependencies = [ "windows-sys 0.52.0", ] -[[package]] -name = "schemars" -version = "0.8.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09c024468a378b7e36765cd36702b7a90cc3cba11654f6685c8f233408e89e92" -dependencies = [ - "dyn-clone", - "schemars_derive", - "serde", - "serde_json", -] - -[[package]] -name = "schemars_derive" -version = "0.8.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1eee588578aff73f856ab961cd2f79e36bc45d7ded33a7562adba4667aecc0e" -dependencies = [ - "proc-macro2", - "quote", - "serde_derive_internals", - "syn 2.0.58", -] - [[package]] name = "schnellru" version = "0.2.1" @@ -12673,24 +12263,6 @@ dependencies = [ "hashbrown 0.13.2", ] -[[package]] -name = "schnorrkel" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "021b403afe70d81eea68f6ea12f6b3c9588e5d536a94c3bf80f15e7faa267862" -dependencies = [ - "arrayref", - "arrayvec 0.5.2", - "curve25519-dalek 2.1.3", - "getrandom 0.1.16", - "merlin 2.0.1", - "rand 0.7.3", - "rand_core 0.5.1", - "sha2 0.8.2", - "subtle 2.5.0", - "zeroize", -] - [[package]] name = "schnorrkel" version = "0.10.2" @@ -12700,7 +12272,7 @@ dependencies = [ "arrayref", "arrayvec 0.7.4", "curve25519-dalek-ng", - "merlin 3.0.0", + "merlin", "rand_core 0.6.4", "sha2 0.9.9", "subtle-ng", @@ -12718,7 +12290,7 @@ dependencies = [ "arrayvec 0.7.4", "curve25519-dalek 4.1.2", "getrandom_or_panic", - "merlin 3.0.0", + "merlin", "rand_core 0.6.4", "serde_bytes", "sha2 0.10.8", @@ -12771,31 +12343,13 @@ dependencies = [ "libc", ] -[[package]] -name = "secp256k1" -version = "0.24.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b1629c9c557ef9b293568b338dddfc8208c98a18c59d722a9d53f859d9c9b62" -dependencies = [ - "secp256k1-sys 0.6.1", -] - [[package]] name = "secp256k1" version = "0.28.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d24b59d129cdadea20aea4fb2352fa053712e5d713eee47d700cd4b2bc002f10" dependencies = [ - "secp256k1-sys 0.9.2", -] - -[[package]] -name = "secp256k1-sys" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83080e2c2fc1006e625be82e5d1eb6a43b7fd9578b617fcc55814daf286bba4b" -dependencies = [ - "cc", + "secp256k1-sys", ] [[package]] @@ -12901,17 +12455,6 @@ dependencies = [ "syn 2.0.58", ] -[[package]] -name = "serde_derive_internals" -version = "0.29.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18d26a20a969b9e3fdf2fc2d9f21eda6c40e2de84c9408bb5d3b05d499aae711" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.58", -] - [[package]] name = "serde_json" version = "1.0.115" @@ -12956,18 +12499,6 @@ dependencies = [ "digest 0.10.7", ] -[[package]] -name = "sha2" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a256f46ea78a0c0d9ff00077504903ac881a1dafdc20da66545699e7776b3e69" -dependencies = [ - "block-buffer 0.7.3", - "digest 0.8.1", - "fake-simd", - "opaque-debug 0.2.3", -] - [[package]] name = "sha2" version = "0.9.9" @@ -13026,12 +12557,6 @@ dependencies = [ "libc", ] -[[package]] -name = "signature" -version = "1.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" - [[package]] name = "signature" version = "2.2.0" @@ -13097,8 +12622,8 @@ dependencies = [ "enumn", "parity-scale-codec", "paste", - "sp-runtime 32.0.0", - "sp-std 14.0.0", + "sp-runtime", + "sp-std", ] [[package]] @@ -13177,7 +12702,7 @@ dependencies = [ "hmac 0.12.1", "itertools 0.11.0", "libsecp256k1", - "merlin 3.0.0", + "merlin", "no-std-net", "nom", "num-bigint", @@ -13186,7 +12711,7 @@ dependencies = [ "pbkdf2 0.12.2", "pin-project", "poly1305", - "rand 0.8.5", + "rand", "rand_chacha 0.3.1", "ruzstd 0.4.0", "schnorrkel 0.10.2", @@ -13232,7 +12757,7 @@ dependencies = [ "itertools 0.12.1", "libm", "libsecp256k1", - "merlin 3.0.0", + "merlin", "no-std-net", "nom", "num-bigint", @@ -13241,7 +12766,7 @@ dependencies = [ "pbkdf2 0.12.2", "pin-project", "poly1305", - "rand 0.8.5", + "rand", "rand_chacha 0.3.1", "ruzstd 0.5.0", "schnorrkel 0.11.4", @@ -13284,7 +12809,7 @@ dependencies = [ "no-std-net", "parking_lot 0.12.1", "pin-project", - "rand 0.8.5", + "rand", "rand_chacha 0.3.1", "serde", "serde_json", @@ -13320,7 +12845,7 @@ dependencies = [ "no-std-net", "parking_lot 0.12.1", "pin-project", - "rand 0.8.5", + "rand", "rand_chacha 0.3.1", "serde", "serde_json", @@ -13380,10 +12905,10 @@ dependencies = [ "serde", "snowbridge-ethereum", "snowbridge-milagro-bls", - "sp-core 29.0.0", - "sp-io 31.0.0", - "sp-runtime 32.0.0", - "sp-std 14.0.0", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", "ssz_rs", "ssz_rs_derive", "static_assertions", @@ -13404,11 +12929,11 @@ dependencies = [ "scale-info", "serde", "snowbridge-beacon-primitives", - "sp-arithmetic 24.0.0", - "sp-core 29.0.0", - "sp-io 31.0.0", - "sp-runtime 32.0.0", - "sp-std 14.0.0", + "sp-arithmetic", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", "staging-xcm", "staging-xcm-builder", ] @@ -13430,10 +12955,10 @@ dependencies = [ "scale-info", "serde", "serde-big-array", - "sp-core 29.0.0", - "sp-io 31.0.0", - "sp-runtime 32.0.0", - "sp-std 14.0.0", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", ] [[package]] @@ -13445,7 +12970,7 @@ dependencies = [ "hex", "lazy_static", "parity-scale-codec", - "rand 0.8.5", + "rand", "scale-info", "snowbridge-amcl", "zeroize", @@ -13466,10 +12991,10 @@ dependencies = [ "scale-info", "serde", "snowbridge-core", - "sp-core 29.0.0", - "sp-io 31.0.0", - "sp-runtime 32.0.0", - "sp-std 14.0.0", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", "staging-xcm", "staging-xcm-builder", "staging-xcm-executor", @@ -13508,37 +13033,37 @@ dependencies = [ "http", "httparse", "log", - "rand 0.8.5", + "rand", "sha-1", ] [[package]] name = "sp-api" -version = "27.0.0" +version = "27.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ef42aa652381ade883c14ffbbb5c0fec36d382d2217b5bace01b8a0e8634778" +checksum = "2e4f8702afd77f14a32733e2b589c02694bf79d0b3a641963c508016208724d0" dependencies = [ "hash-db", "log", "parity-scale-codec", "scale-info", "sp-api-proc-macro", - "sp-core 29.0.0", - "sp-externalities 0.26.0", + "sp-core", + "sp-externalities", "sp-metadata-ir", - "sp-runtime 32.0.0", - "sp-state-machine 0.36.0", - "sp-std 14.0.0", - "sp-trie 30.0.0", + "sp-runtime", + "sp-state-machine", + "sp-std", + "sp-trie", "sp-version", "thiserror", ] [[package]] name = "sp-api-proc-macro" -version = "15.0.0" +version = "15.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0694be2891593450916d6b53a274d234bccbc86bcbada36ba23fc356989070c7" +checksum = "0301e2f77afb450fbf2b093f8b324c7ad88cc82e5e69bd5dc8658a1f068b2a96" dependencies = [ "Inflector", "blake2 0.10.6", @@ -13549,20 +13074,6 @@ dependencies = [ "syn 2.0.58", ] -[[package]] -name = "sp-application-crypto" -version = "23.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "899492ea547816d5dfe9a5a2ecc32f65a7110805af6da3380aa4902371b31dc2" -dependencies = [ - "parity-scale-codec", - "scale-info", - "serde", - "sp-core 21.0.0", - "sp-io 23.0.0", - "sp-std 8.0.0", -] - [[package]] name = "sp-application-crypto" version = "31.0.0" @@ -13572,24 +13083,9 @@ dependencies = [ "parity-scale-codec", "scale-info", "serde", - "sp-core 29.0.0", - "sp-io 31.0.0", - "sp-std 14.0.0", -] - -[[package]] -name = "sp-arithmetic" -version = "16.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb6020576e544c6824a51d651bc8df8e6ab67cd59f1c9ac09868bb81a5199ded" -dependencies = [ - "integer-sqrt", - "num-traits", - "parity-scale-codec", - "scale-info", - "serde", - "sp-std 8.0.0", - "static_assertions", + "sp-core", + "sp-io", + "sp-std", ] [[package]] @@ -13603,7 +13099,7 @@ dependencies = [ "parity-scale-codec", "scale-info", "serde", - "sp-std 14.0.0", + "sp-std", "static_assertions", ] @@ -13616,9 +13112,9 @@ dependencies = [ "parity-scale-codec", "scale-info", "sp-api", - "sp-application-crypto 31.0.0", - "sp-runtime 32.0.0", - "sp-std 14.0.0", + "sp-application-crypto", + "sp-runtime", + "sp-std", ] [[package]] @@ -13629,8 +13125,8 @@ checksum = "1b36ce171caa7eb2bbe682c089f755fdefa71d3702e4fb1ba30d10146aef99d5" dependencies = [ "sp-api", "sp-inherents", - "sp-runtime 32.0.0", - "sp-std 14.0.0", + "sp-runtime", + "sp-std", ] [[package]] @@ -13647,8 +13143,8 @@ dependencies = [ "sp-api", "sp-consensus", "sp-database", - "sp-runtime 32.0.0", - "sp-state-machine 0.36.0", + "sp-runtime", + "sp-state-machine", "thiserror", ] @@ -13661,10 +13157,10 @@ dependencies = [ "async-trait", "futures", "log", - "sp-core 29.0.0", + "sp-core", "sp-inherents", - "sp-runtime 32.0.0", - "sp-state-machine 0.36.0", + "sp-runtime", + "sp-state-machine", "thiserror", ] @@ -13678,11 +13174,11 @@ dependencies = [ "parity-scale-codec", "scale-info", "sp-api", - "sp-application-crypto 31.0.0", + "sp-application-crypto", "sp-consensus-slots", "sp-inherents", - "sp-runtime 32.0.0", - "sp-std 14.0.0", + "sp-runtime", + "sp-std", "sp-timestamp", ] @@ -13697,12 +13193,12 @@ dependencies = [ "scale-info", "serde", "sp-api", - "sp-application-crypto 31.0.0", + "sp-application-crypto", "sp-consensus-slots", - "sp-core 29.0.0", + "sp-core", "sp-inherents", - "sp-runtime 32.0.0", - "sp-std 14.0.0", + "sp-runtime", + "sp-std", "sp-timestamp", ] @@ -13717,13 +13213,13 @@ dependencies = [ "scale-info", "serde", "sp-api", - "sp-application-crypto 31.0.0", - "sp-core 29.0.0", + "sp-application-crypto", + "sp-core", "sp-crypto-hashing", - "sp-io 31.0.0", + "sp-io", "sp-mmr-primitives", - "sp-runtime 32.0.0", - "sp-std 14.0.0", + "sp-runtime", + "sp-std", "strum 0.24.1", ] @@ -13739,11 +13235,11 @@ dependencies = [ "scale-info", "serde", "sp-api", - "sp-application-crypto 31.0.0", - "sp-core 29.0.0", - "sp-keystore 0.35.0", - "sp-runtime 32.0.0", - "sp-std 14.0.0", + "sp-application-crypto", + "sp-core", + "sp-keystore", + "sp-runtime", + "sp-std", ] [[package]] @@ -13755,55 +13251,10 @@ dependencies = [ "parity-scale-codec", "scale-info", "serde", - "sp-std 14.0.0", + "sp-std", "sp-timestamp", ] -[[package]] -name = "sp-core" -version = "21.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f18d9e2f67d8661f9729f35347069ac29d92758b59135176799db966947a7336" -dependencies = [ - "array-bytes 4.2.0", - "bitflags 1.3.2", - "blake2 0.10.6", - "bounded-collections 0.1.9", - "bs58 0.4.0", - "dyn-clonable", - "ed25519-zebra 3.1.0", - "futures", - "hash-db", - "hash256-std-hasher", - "impl-serde", - "lazy_static", - "libsecp256k1", - "log", - "merlin 2.0.1", - "parity-scale-codec", - "parking_lot 0.12.1", - "paste", - "primitive-types", - "rand 0.8.5", - "regex", - "scale-info", - "schnorrkel 0.9.1", - "secp256k1 0.24.3", - "secrecy", - "serde", - "sp-core-hashing 9.0.0", - "sp-debug-derive 8.0.0", - "sp-externalities 0.19.0", - "sp-runtime-interface 17.0.0", - "sp-std 8.0.0", - "sp-storage 13.0.0", - "ss58-registry", - "substrate-bip39", - "thiserror", - "tiny-bip39", - "zeroize", -] - [[package]] name = "sp-core" version = "29.0.0" @@ -13825,23 +13276,23 @@ dependencies = [ "itertools 0.10.5", "libsecp256k1", "log", - "merlin 3.0.0", + "merlin", "parity-scale-codec", "parking_lot 0.12.1", "paste", "primitive-types", - "rand 0.8.5", + "rand", "scale-info", "schnorrkel 0.11.4", - "secp256k1 0.28.2", + "secp256k1", "secrecy", "serde", "sp-crypto-hashing", - "sp-debug-derive 14.0.0", - "sp-externalities 0.26.0", - "sp-runtime-interface 25.0.0", - "sp-std 14.0.0", - "sp-storage 20.0.0", + "sp-debug-derive", + "sp-externalities", + "sp-runtime-interface", + "sp-std", + "sp-storage", "ss58-registry", "substrate-bip39", "thiserror", @@ -13850,21 +13301,6 @@ dependencies = [ "zeroize", ] -[[package]] -name = "sp-core-hashing" -version = "9.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ee599a8399448e65197f9a6cee338ad192e9023e35e31f22382964c3c174c68" -dependencies = [ - "blake2b_simd", - "byteorder", - "digest 0.10.7", - "sha2 0.10.8", - "sha3", - "sp-std 8.0.0", - "twox-hash", -] - [[package]] name = "sp-core-hashing" version = "15.0.0" @@ -13914,17 +13350,6 @@ dependencies = [ "parking_lot 0.12.1", ] -[[package]] -name = "sp-debug-derive" -version = "8.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7f531814d2f16995144c74428830ccf7d94ff4a7749632b83ad8199b181140c" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.58", -] - [[package]] name = "sp-debug-derive" version = "14.0.0" @@ -13936,18 +13361,6 @@ dependencies = [ "syn 2.0.58", ] -[[package]] -name = "sp-externalities" -version = "0.19.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0f71c671e01a8ca60da925d43a1b351b69626e268b8837f8371e320cf1dd100" -dependencies = [ - "environmental", - "parity-scale-codec", - "sp-std 8.0.0", - "sp-storage 13.0.0", -] - [[package]] name = "sp-externalities" version = "0.26.0" @@ -13956,8 +13369,8 @@ checksum = "e7096ed024cec397804864898b093b51e14c7299f1d00c67dd5800330e02bb82" dependencies = [ "environmental", "parity-scale-codec", - "sp-std 14.0.0", - "sp-storage 20.0.0", + "sp-std", + "sp-storage", ] [[package]] @@ -13968,8 +13381,8 @@ checksum = "fd865540ec19479c7349b584ccd78cc34c3f3a628a2a69dbb6365ceec36295ee" dependencies = [ "serde_json", "sp-api", - "sp-runtime 32.0.0", - "sp-std 14.0.0", + "sp-runtime", + "sp-std", ] [[package]] @@ -13982,38 +13395,11 @@ dependencies = [ "impl-trait-for-tuples", "parity-scale-codec", "scale-info", - "sp-runtime 32.0.0", - "sp-std 14.0.0", + "sp-runtime", + "sp-std", "thiserror", ] -[[package]] -name = "sp-io" -version = "23.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d597e35a9628fe7454b08965b2442e3ec0f264b0a90d41328e87422cec02e99" -dependencies = [ - "bytes", - "ed25519 1.5.3", - "ed25519-dalek 1.0.1", - "futures", - "libsecp256k1", - "log", - "parity-scale-codec", - "rustversion", - "secp256k1 0.24.3", - "sp-core 21.0.0", - "sp-externalities 0.19.0", - "sp-keystore 0.27.0", - "sp-runtime-interface 17.0.0", - "sp-state-machine 0.28.0", - "sp-std 8.0.0", - "sp-tracing 10.0.0", - "sp-trie 22.0.0", - "tracing", - "tracing-core", -] - [[package]] name = "sp-io" version = "31.0.0" @@ -14021,21 +13407,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec43aa073eab35fcb920d7592474d5427ea3be2bf938706a3ad955d7ba54fd8d" dependencies = [ "bytes", - "ed25519-dalek 2.1.1", + "ed25519-dalek", "libsecp256k1", "log", "parity-scale-codec", "rustversion", - "secp256k1 0.28.2", - "sp-core 29.0.0", + "secp256k1", + "sp-core", "sp-crypto-hashing", - "sp-externalities 0.26.0", - "sp-keystore 0.35.0", - "sp-runtime-interface 25.0.0", - "sp-state-machine 0.36.0", - "sp-std 14.0.0", - "sp-tracing 16.0.0", - "sp-trie 30.0.0", + "sp-externalities", + "sp-keystore", + "sp-runtime-interface", + "sp-state-machine", + "sp-std", + "sp-tracing", + "sp-trie", "tracing", "tracing-core", ] @@ -14046,25 +13432,11 @@ version = "32.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "69cf0a2f881958466fc92bc9b39bbc2c0d815ded4a21f8f953372b0ac2e11b02" dependencies = [ - "sp-core 29.0.0", - "sp-runtime 32.0.0", + "sp-core", + "sp-runtime", "strum 0.24.1", ] -[[package]] -name = "sp-keystore" -version = "0.27.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9be3cdd67cc1d9c1db17c5cbc4ec4924054a8437009d167f21f6590797e4aa45" -dependencies = [ - "futures", - "parity-scale-codec", - "parking_lot 0.12.1", - "sp-core 21.0.0", - "sp-externalities 0.19.0", - "thiserror", -] - [[package]] name = "sp-keystore" version = "0.35.0" @@ -14073,8 +13445,8 @@ checksum = "444f2d53968b1ce5e908882710ff1f3873fcf3e95f59d57432daf685bbacb959" dependencies = [ "parity-scale-codec", "parking_lot 0.12.1", - "sp-core 29.0.0", - "sp-externalities 0.26.0", + "sp-core", + "sp-externalities", "thiserror", ] @@ -14097,7 +13469,7 @@ dependencies = [ "frame-metadata 16.0.0", "parity-scale-codec", "scale-info", - "sp-std 14.0.0", + "sp-std", ] [[package]] @@ -14109,8 +13481,8 @@ dependencies = [ "parity-scale-codec", "scale-info", "sp-api", - "sp-application-crypto 31.0.0", - "sp-std 14.0.0", + "sp-application-crypto", + "sp-std", ] [[package]] @@ -14125,10 +13497,10 @@ dependencies = [ "scale-info", "serde", "sp-api", - "sp-core 29.0.0", - "sp-debug-derive 14.0.0", - "sp-runtime 32.0.0", - "sp-std 14.0.0", + "sp-core", + "sp-debug-derive", + "sp-runtime", + "sp-std", "thiserror", ] @@ -14141,10 +13513,10 @@ dependencies = [ "parity-scale-codec", "scale-info", "serde", - "sp-arithmetic 24.0.0", - "sp-core 29.0.0", - "sp-runtime 32.0.0", - "sp-std 14.0.0", + "sp-arithmetic", + "sp-core", + "sp-runtime", + "sp-std", ] [[package]] @@ -14154,19 +13526,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4d83b955dce0b6d143bec3f60571311168f362b1c16cf044da7037a407b66c19" dependencies = [ "sp-api", - "sp-core 29.0.0", - "sp-runtime 32.0.0", -] - -[[package]] -name = "sp-panic-handler" -version = "8.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebd2de46003fa8212426838ca71cd42ee36a26480ba9ffea983506ce03131033" -dependencies = [ - "backtrace", - "lazy_static", - "regex", + "sp-core", + "sp-runtime", ] [[package]] @@ -14188,30 +13549,7 @@ checksum = "9af4b73fe7ddd88b1641cca90048c4e525e721763199e6fd29c4f590884f4d16" dependencies = [ "rustc-hash", "serde", - "sp-core 29.0.0", -] - -[[package]] -name = "sp-runtime" -version = "24.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21c5bfc764a1a8259d7e8f7cfd22c84006275a512c958d3ff966c92151e134d5" -dependencies = [ - "either", - "hash256-std-hasher", - "impl-trait-for-tuples", - "log", - "parity-scale-codec", - "paste", - "rand 0.8.5", - "scale-info", - "serde", - "sp-application-crypto 23.0.0", - "sp-arithmetic 16.0.0", - "sp-core 21.0.0", - "sp-io 23.0.0", - "sp-std 8.0.0", - "sp-weights 20.0.0", + "sp-core", ] [[package]] @@ -14227,35 +13565,16 @@ dependencies = [ "log", "parity-scale-codec", "paste", - "rand 0.8.5", + "rand", "scale-info", "serde", "simple-mermaid", - "sp-application-crypto 31.0.0", - "sp-arithmetic 24.0.0", - "sp-core 29.0.0", - "sp-io 31.0.0", - "sp-std 14.0.0", - "sp-weights 28.0.0", -] - -[[package]] -name = "sp-runtime-interface" -version = "17.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e676128182f90015e916f806cba635c8141e341e7abbc45d25525472e1bbce8" -dependencies = [ - "bytes", - "impl-trait-for-tuples", - "parity-scale-codec", - "primitive-types", - "sp-externalities 0.19.0", - "sp-runtime-interface-proc-macro 11.0.0", - "sp-std 8.0.0", - "sp-storage 13.0.0", - "sp-tracing 10.0.0", - "sp-wasm-interface 14.0.0", - "static_assertions", + "sp-application-crypto", + "sp-arithmetic", + "sp-core", + "sp-io", + "sp-std", + "sp-weights", ] [[package]] @@ -14268,28 +13587,15 @@ dependencies = [ "impl-trait-for-tuples", "parity-scale-codec", "primitive-types", - "sp-externalities 0.26.0", - "sp-runtime-interface-proc-macro 17.0.0", - "sp-std 14.0.0", - "sp-storage 20.0.0", - "sp-tracing 16.0.0", - "sp-wasm-interface 20.0.0", + "sp-externalities", + "sp-runtime-interface-proc-macro", + "sp-std", + "sp-storage", + "sp-tracing", + "sp-wasm-interface", "static_assertions", ] -[[package]] -name = "sp-runtime-interface-proc-macro" -version = "11.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5d5bd5566fe5633ec48dfa35ab152fd29f8a577c21971e1c6db9f28afb9bbb9" -dependencies = [ - "Inflector", - "proc-macro-crate 1.3.1", - "proc-macro2", - "quote", - "syn 2.0.58", -] - [[package]] name = "sp-runtime-interface-proc-macro" version = "17.0.0" @@ -14313,11 +13619,11 @@ dependencies = [ "parity-scale-codec", "scale-info", "sp-api", - "sp-core 29.0.0", - "sp-keystore 0.35.0", - "sp-runtime 32.0.0", + "sp-core", + "sp-keystore", + "sp-runtime", "sp-staking", - "sp-std 14.0.0", + "sp-std", ] [[package]] @@ -14330,30 +13636,9 @@ dependencies = [ "parity-scale-codec", "scale-info", "serde", - "sp-core 29.0.0", - "sp-runtime 32.0.0", - "sp-std 14.0.0", -] - -[[package]] -name = "sp-state-machine" -version = "0.28.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ef45d31f9e7ac648f8899a0cd038a3608f8499028bff55b6c799702592325b6" -dependencies = [ - "hash-db", - "log", - "parity-scale-codec", - "parking_lot 0.12.1", - "rand 0.8.5", - "smallvec", - "sp-core 21.0.0", - "sp-externalities 0.19.0", - "sp-panic-handler 8.0.0", - "sp-std 8.0.0", - "sp-trie 22.0.0", - "thiserror", - "tracing", + "sp-core", + "sp-runtime", + "sp-std", ] [[package]] @@ -14366,16 +13651,16 @@ dependencies = [ "log", "parity-scale-codec", "parking_lot 0.12.1", - "rand 0.8.5", + "rand", "smallvec", - "sp-core 29.0.0", - "sp-externalities 0.26.0", - "sp-panic-handler 13.0.0", - "sp-std 14.0.0", - "sp-trie 30.0.0", + "sp-core", + "sp-externalities", + "sp-panic-handler", + "sp-std", + "sp-trie", "thiserror", "tracing", - "trie-db 0.28.0", + "trie-db", ] [[package]] @@ -14386,50 +13671,30 @@ checksum = "309a9ae4e8134bbed8ffc510cf4d461a4a651f9250b556de782cedd876abe1ff" dependencies = [ "aes-gcm", "curve25519-dalek 4.1.2", - "ed25519-dalek 2.1.1", + "ed25519-dalek", "hkdf", "parity-scale-codec", - "rand 0.8.5", + "rand", "scale-info", "sha2 0.10.8", "sp-api", - "sp-application-crypto 31.0.0", - "sp-core 29.0.0", + "sp-application-crypto", + "sp-core", "sp-crypto-hashing", - "sp-externalities 0.26.0", - "sp-runtime 32.0.0", - "sp-runtime-interface 25.0.0", - "sp-std 14.0.0", + "sp-externalities", + "sp-runtime", + "sp-runtime-interface", + "sp-std", "thiserror", "x25519-dalek 2.0.1", ] -[[package]] -name = "sp-std" -version = "8.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53458e3c57df53698b3401ec0934bea8e8cfce034816873c0b0abbd83d7bac0d" - [[package]] name = "sp-std" version = "14.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "12f8ee986414b0a9ad741776762f4083cd3a5128449b982a3919c4df36874834" -[[package]] -name = "sp-storage" -version = "13.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94294be83f11d4958cfea89ed5798f0b6605f5defc3a996948848458abbcc18e" -dependencies = [ - "impl-serde", - "parity-scale-codec", - "ref-cast", - "serde", - "sp-debug-derive 8.0.0", - "sp-std 8.0.0", -] - [[package]] name = "sp-storage" version = "20.0.0" @@ -14440,8 +13705,8 @@ dependencies = [ "parity-scale-codec", "ref-cast", "serde", - "sp-debug-derive 14.0.0", - "sp-std 14.0.0", + "sp-debug-derive", + "sp-std", ] [[package]] @@ -14453,24 +13718,11 @@ dependencies = [ "async-trait", "parity-scale-codec", "sp-inherents", - "sp-runtime 32.0.0", - "sp-std 14.0.0", + "sp-runtime", + "sp-std", "thiserror", ] -[[package]] -name = "sp-tracing" -version = "10.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "357f7591980dd58305956d32f8f6646d0a8ea9ea0e7e868e46f53b68ddf00cec" -dependencies = [ - "parity-scale-codec", - "sp-std 8.0.0", - "tracing", - "tracing-core", - "tracing-subscriber 0.2.25", -] - [[package]] name = "sp-tracing" version = "16.0.0" @@ -14478,7 +13730,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0351810b9d074df71c4514c5228ed05c250607cba131c1c9d1526760ab69c05c" dependencies = [ "parity-scale-codec", - "sp-std 14.0.0", + "sp-std", "tracing", "tracing-core", "tracing-subscriber 0.2.25", @@ -14491,7 +13743,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9742861c5330bdcb42856a6eed3d3745b58ee1c92ca4c9260032ff4e6c387165" dependencies = [ "sp-api", - "sp-runtime 32.0.0", + "sp-runtime", ] [[package]] @@ -14503,35 +13755,11 @@ dependencies = [ "async-trait", "parity-scale-codec", "scale-info", - "sp-core 29.0.0", + "sp-core", "sp-inherents", - "sp-runtime 32.0.0", - "sp-std 14.0.0", - "sp-trie 30.0.0", -] - -[[package]] -name = "sp-trie" -version = "22.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48e4eeb7ef23f79eba8609db79ef9cef242f994f1f87a3c0387b4b5f177fda74" -dependencies = [ - "ahash 0.8.11", - "hash-db", - "hashbrown 0.13.2", - "lazy_static", - "memory-db", - "nohash-hasher", - "parity-scale-codec", - "parking_lot 0.12.1", - "scale-info", - "schnellru", - "sp-core 21.0.0", - "sp-std 8.0.0", - "thiserror", - "tracing", - "trie-db 0.27.1", - "trie-root", + "sp-runtime", + "sp-std", + "sp-trie", ] [[package]] @@ -14547,15 +13775,15 @@ dependencies = [ "nohash-hasher", "parity-scale-codec", "parking_lot 0.12.1", - "rand 0.8.5", + "rand", "scale-info", "schnellru", - "sp-core 29.0.0", - "sp-externalities 0.26.0", - "sp-std 14.0.0", + "sp-core", + "sp-externalities", + "sp-std", "thiserror", "tracing", - "trie-db 0.28.0", + "trie-db", "trie-root", ] @@ -14571,8 +13799,8 @@ dependencies = [ "scale-info", "serde", "sp-crypto-hashing-proc-macro", - "sp-runtime 32.0.0", - "sp-std 14.0.0", + "sp-runtime", + "sp-std", "sp-version-proc-macro", "thiserror", ] @@ -14589,20 +13817,6 @@ dependencies = [ "syn 2.0.58", ] -[[package]] -name = "sp-wasm-interface" -version = "14.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a19c122609ca5d8246be6386888596320d03c7bc880959eaa2c36bcd5acd6846" -dependencies = [ - "anyhow", - "impl-trait-for-tuples", - "log", - "parity-scale-codec", - "sp-std 8.0.0", - "wasmtime", -] - [[package]] name = "sp-wasm-interface" version = "20.0.0" @@ -14613,26 +13827,10 @@ dependencies = [ "impl-trait-for-tuples", "log", "parity-scale-codec", - "sp-std 14.0.0", + "sp-std", "wasmtime", ] -[[package]] -name = "sp-weights" -version = "20.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45d084c735544f70625b821c3acdbc7a2fc1893ca98b85f1942631284692c75b" -dependencies = [ - "parity-scale-codec", - "scale-info", - "serde", - "smallvec", - "sp-arithmetic 16.0.0", - "sp-core 21.0.0", - "sp-debug-derive 8.0.0", - "sp-std 8.0.0", -] - [[package]] name = "sp-weights" version = "28.0.0" @@ -14644,9 +13842,9 @@ dependencies = [ "scale-info", "serde", "smallvec", - "sp-arithmetic 24.0.0", - "sp-debug-derive 14.0.0", - "sp-std 14.0.0", + "sp-arithmetic", + "sp-debug-derive", + "sp-std", ] [[package]] @@ -14737,8 +13935,8 @@ dependencies = [ "frame-system", "parity-scale-codec", "scale-info", - "sp-runtime 32.0.0", - "sp-std 14.0.0", + "sp-runtime", + "sp-std", ] [[package]] @@ -14756,15 +13954,15 @@ dependencies = [ "parity-scale-codec", "scale-info", "serde", - "sp-weights 28.0.0", + "sp-weights", "xcm-procedural", ] [[package]] name = "staging-xcm-builder" -version = "8.0.1" +version = "8.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8f6cfc27c1d45f9a67e20ed3f7e60296299688825350291606add10bf3bbff2" +checksum = "988d765ad5ab3b5cc90bb1dd143153ebdbe2b7600e10d5ef3a7f3e8df1bdac5d" dependencies = [ "frame-support", "frame-system", @@ -14774,20 +13972,20 @@ dependencies = [ "parity-scale-codec", "polkadot-parachain-primitives", "scale-info", - "sp-arithmetic 24.0.0", - "sp-io 31.0.0", - "sp-runtime 32.0.0", - "sp-std 14.0.0", - "sp-weights 28.0.0", + "sp-arithmetic", + "sp-io", + "sp-runtime", + "sp-std", + "sp-weights", "staging-xcm", "staging-xcm-executor", ] [[package]] name = "staging-xcm-executor" -version = "8.0.1" +version = "8.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a638f4c8735cc04b5c93920a1f59e679f48b131315a07d146798e0decebf7720" +checksum = "74b5c5f2a1d610c5e20e5fae2680c9a28380f305afafeed62f341bfbce57b79a" dependencies = [ "environmental", "frame-benchmarking", @@ -14796,12 +13994,12 @@ dependencies = [ "log", "parity-scale-codec", "scale-info", - "sp-arithmetic 24.0.0", - "sp-core 29.0.0", - "sp-io 31.0.0", - "sp-runtime 32.0.0", - "sp-std 14.0.0", - "sp-weights 28.0.0", + "sp-arithmetic", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", + "sp-weights", "staging-xcm", ] @@ -14940,8 +14138,8 @@ dependencies = [ "sp-api", "sp-block-builder", "sp-blockchain", - "sp-core 29.0.0", - "sp-runtime 32.0.0", + "sp-core", + "sp-runtime", ] [[package]] @@ -14968,7 +14166,7 @@ dependencies = [ "log", "sc-rpc-api", "serde", - "sp-runtime 32.0.0", + "sp-runtime", ] [[package]] @@ -14982,18 +14180,18 @@ dependencies = [ "sc-client-api", "sc-rpc-api", "serde", - "sp-core 29.0.0", - "sp-runtime 32.0.0", - "sp-state-machine 0.36.0", - "sp-trie 30.0.0", - "trie-db 0.28.0", + "sp-core", + "sp-runtime", + "sp-state-machine", + "sp-trie", + "trie-db", ] [[package]] name = "substrate-wasm-builder" -version = "18.0.0" +version = "18.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "511bbc2df035f5fe2556d855369a1bbb45df620360391a1f6e3fa1a1d64af79a" +checksum = "4a39a20e17c24ede36b5bd5e7543a4cef8d8a0daf6e1a046dc31832b837a54a0" dependencies = [ "build-helper", "cargo_metadata", @@ -15052,7 +14250,7 @@ dependencies = [ "scale-value", "serde", "serde_json", - "sp-core-hashing 15.0.0", + "sp-core-hashing", "subxt-lightclient", "subxt-macro", "subxt-metadata", @@ -15124,7 +14322,7 @@ dependencies = [ "frame-metadata 16.0.0", "parity-scale-codec", "scale-info", - "sp-core-hashing 15.0.0", + "sp-core-hashing", "thiserror", ] @@ -15141,10 +14339,10 @@ dependencies = [ "pbkdf2 0.12.2", "regex", "schnorrkel 0.11.4", - "secp256k1 0.28.2", + "secp256k1", "secrecy", "sha2 0.10.8", - "sp-core-hashing 15.0.0", + "sp-core-hashing", "subxt", "thiserror", "zeroize", @@ -15184,17 +14382,6 @@ dependencies = [ "unicode-xid", ] -[[package]] -name = "synstructure" -version = "0.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.58", -] - [[package]] name = "system-configuration" version = "0.5.1" @@ -15275,7 +14462,7 @@ dependencies = [ "polkadot-core-primitives", "rococo-runtime-constants", "smallvec", - "sp-runtime 32.0.0", + "sp-runtime", "staging-xcm", "westend-runtime-constants", ] @@ -15410,25 +14597,6 @@ dependencies = [ "time-core", ] -[[package]] -name = "tiny-bip39" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62cc94d358b5a1e84a5cb9109f559aa3c4d634d2b1b4de3d0fa4adc7c78e2861" -dependencies = [ - "anyhow", - "hmac 0.12.1", - "once_cell", - "pbkdf2 0.11.0", - "rand 0.8.5", - "rustc-hash", - "sha2 0.10.8", - "thiserror", - "unicode-normalization", - "wasm-bindgen", - "zeroize", -] - [[package]] name = "tiny-keccak" version = "2.0.2" @@ -15490,7 +14658,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f57eb36ecbe0fc510036adff84824dd3c24bb781e21bfa67b69d556aa85214f" dependencies = [ "pin-project", - "rand 0.8.5", + "rand", "tokio", ] @@ -15802,19 +14970,6 @@ dependencies = [ "tracing-log 0.2.0", ] -[[package]] -name = "trie-db" -version = "0.27.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "767abe6ffed88a1889671a102c2861ae742726f52e0a5a425b92c9fbfa7e9c85" -dependencies = [ - "hash-db", - "hashbrown 0.13.2", - "log", - "rustc-hex", - "smallvec", -] - [[package]] name = "trie-db" version = "0.28.0" @@ -15853,7 +15008,7 @@ dependencies = [ "idna 0.2.3", "ipnet", "lazy_static", - "rand 0.8.5", + "rand", "smallvec", "socket2 0.4.10", "thiserror", @@ -15909,19 +15064,19 @@ dependencies = [ "sp-api", "sp-consensus-aura", "sp-consensus-babe", - "sp-core 29.0.0", - "sp-debug-derive 14.0.0", - "sp-externalities 0.26.0", + "sp-core", + "sp-debug-derive", + "sp-externalities", "sp-inherents", - "sp-io 31.0.0", - "sp-keystore 0.35.0", + "sp-io", + "sp-keystore", "sp-rpc", - "sp-runtime 32.0.0", - "sp-state-machine 0.36.0", + "sp-runtime", + "sp-state-machine", "sp-timestamp", "sp-transaction-storage-proof", "sp-version", - "sp-weights 28.0.0", + "sp-weights", "substrate-rpc-client", "zstd 0.12.4", ] @@ -15940,7 +15095,7 @@ checksum = "97fee6b57c6a41524a810daee9286c02d7752c4253064d0b05472833a438f675" dependencies = [ "cfg-if", "digest 0.10.7", - "rand 0.8.5", + "rand", "static_assertions", ] @@ -16091,7 +15246,7 @@ dependencies = [ "arrayref", "constcat", "digest 0.10.7", - "rand 0.8.5", + "rand", "rand_chacha 0.3.1", "rand_core 0.6.4", "sha2 0.10.8", @@ -16501,7 +15656,7 @@ dependencies = [ "memfd", "memoffset", "paste", - "rand 0.8.5", + "rand", "rustix 0.36.17", "wasmtime-asm-macros", "wasmtime-environ", @@ -16630,24 +15785,24 @@ dependencies = [ "serde_derive", "smallvec", "sp-api", - "sp-application-crypto 31.0.0", - "sp-arithmetic 24.0.0", + "sp-application-crypto", + "sp-arithmetic", "sp-authority-discovery", "sp-block-builder", "sp-consensus-babe", "sp-consensus-beefy", - "sp-core 29.0.0", + "sp-core", "sp-genesis-builder", "sp-inherents", - "sp-io 31.0.0", + "sp-io", "sp-mmr-primitives", "sp-npos-elections", "sp-offchain", - "sp-runtime 32.0.0", + "sp-runtime", "sp-session", "sp-staking", - "sp-std 14.0.0", - "sp-storage 20.0.0", + "sp-std", + "sp-storage", "sp-transaction-pool", "sp-version", "staging-xcm", @@ -16667,9 +15822,9 @@ dependencies = [ "polkadot-primitives", "polkadot-runtime-common", "smallvec", - "sp-core 29.0.0", - "sp-runtime 32.0.0", - "sp-weights 28.0.0", + "sp-core", + "sp-runtime", + "sp-weights", "staging-xcm", "staging-xcm-builder", ] @@ -17061,13 +16216,13 @@ dependencies = [ "polkadot-parachain-primitives", "polkadot-primitives", "polkadot-runtime-parachains", - "sp-arithmetic 24.0.0", - "sp-core 29.0.0", + "sp-arithmetic", + "sp-core", "sp-crypto-hashing", - "sp-io 31.0.0", - "sp-runtime 32.0.0", - "sp-std 14.0.0", - "sp-tracing 16.0.0", + "sp-io", + "sp-runtime", + "sp-std", + "sp-tracing", "staging-xcm", "staging-xcm-executor", ] @@ -17084,12 +16239,6 @@ dependencies = [ "syn 2.0.58", ] -[[package]] -name = "xxhash-rust" -version = "0.8.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "927da81e25be1e1a2901d59b81b37dd2efd1fc9c9345a55007f09bf5a2d3ee03" - [[package]] name = "yamux" version = "0.10.2" @@ -17100,7 +16249,7 @@ dependencies = [ "log", "nohash-hasher", "parking_lot 0.12.1", - "rand 0.8.5", + "rand", "static_assertions", ] diff --git a/Cargo.toml b/Cargo.toml index 3f1d6e1c..3719e83d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -47,7 +47,7 @@ subxt-signer = "0.34.0" tokio = { version = "1.36", features = ["macros", "time", "rt-multi-thread"] } # Build -substrate-wasm-builder = "18.0.0" +substrate-wasm-builder = "18.0.1" substrate-build-script-utils = "11.0.0" # Local @@ -76,7 +76,7 @@ sc-transaction-pool-api = "29.0.0" frame-benchmarking = { version = "29.0.0", default-features = false } frame-benchmarking-cli = "33.0.0" frame-executive = { version = "29.0.0", default-features = false } -frame-support = { version = "29.0.0", default-features = false } +frame-support = { version = "29.0.2", default-features = false } frame-system = { version = "29.0.0", default-features = false } frame-system-benchmarking = { version = "29.0.0", default-features = false } frame-system-rpc-runtime-api = { version = "27.0.0", default-features = false } @@ -84,7 +84,7 @@ frame-try-runtime = { version = "0.35.0", default-features = false } pallet-aura = { version = "28.0.0", default-features = false } pallet-authorship = { version = "29.0.0", default-features = false } pallet-assets = { version = "30.0.0", default-features = false } -pallet-balances = { version = "29.0.0", default-features = false } +pallet-balances = { version = "29.0.2", default-features = false } pallet-contracts = { version = "28.0.0", default-features = false } pallet-message-queue = { version = "32.0.0", default-features = false } pallet-multisig = { version = "29.0.0", default-features = false } @@ -97,11 +97,11 @@ pallet-scheduler = { version = "30.0.0", default-features = false } pallet-session = { version = "29.0.0", default-features = false } pallet-sudo = { version = "29.0.0", default-features = false } pallet-timestamp = { version = "28.0.0", default-features = false } -pallet-transaction-payment = { version = "29.0.0", default-features = false } +pallet-transaction-payment = { version = "29.0.1", default-features = false } pallet-transaction-payment-rpc = "31.0.0" pallet-transaction-payment-rpc-runtime-api = { version = "29.0.0", default-features = false } pallet-utility = { version = "29.0.0", default-features = false } -sp-api = { version = "27.0.0", default-features = false } +sp-api = { version = "27.0.1", default-features = false } sp-authority-discovery = { version = "27.0.0", default-features = false } sp-block-builder = { version = "27.0.0", default-features = false } sp-blockchain = "29.0.0" @@ -125,17 +125,17 @@ sp-transaction-pool = { version = "27.0.0", default-features = false } sp-version = { version = "30.0.0", default-features = false } # Polkadot -pallet-xcm = { version = "=8.0.1", default-features = false } +pallet-xcm = { version = "8.0.5", default-features = false } polkadot-cli = "8.0.0" polkadot-parachain-primitives = { version = "7.0.0", default-features = false } -polkadot-runtime-parachains = { version = "8.0.1", default-features = false } +polkadot-runtime-parachains = { version = "8.0.3", default-features = false } polkadot-primitives = { version = "8.0.1", default-features = false } -polkadot-runtime-common = { version = "8.0.1", default-features = false } +polkadot-runtime-common = { version = "8.0.2", default-features = false } rococo-runtime-constants = { version = "8.0.0", default-features = false } rococo-runtime = { version = "8.0.0", default-features = false } -xcm = { package = "staging-xcm", version = "8.0.1", default-features = false } -xcm-builder = { package = "staging-xcm-builder", version = "8.0.1", default-features = false } -xcm-executor = { package = "staging-xcm-executor", version = "8.0.1", default-features = false } +xcm = { version = "8.0.1", package = "staging-xcm", default-features = false } +xcm-builder = { version = "8.0.2", package = "staging-xcm-builder", default-features = false } +xcm-executor = { version = "8.0.2", package = "staging-xcm-executor", default-features = false } # Cumulus asset-hub-rococo-runtime = { version = "0.12.0", default-features = false } @@ -149,9 +149,9 @@ cumulus-primitives-aura = { version = "0.8.0", default-features = false } cumulus-primitives-core = { version = "0.8.0", default-features = false } cumulus-primitives-utility = { version = "0.8.1", default-features = false } emulated-integration-tests-common = { version = "4.0.0", default-features = false } -pallet-collator-selection = { version = "10.0.0", default-features = false } +pallet-collator-selection = { version = "10.0.2", default-features = false } parachains-common = { version = "8.0.0", default-features = false } -parachain-info = { package = "staging-parachain-info", version = "0.8.0", default-features = false } +parachain-info = { version = "0.8.0", package = "staging-parachain-info", default-features = false } cumulus-primitives-parachain-inherent = "0.8.0" cumulus-relay-chain-interface = "0.8.0" color-print = "0.3.4" @@ -160,4 +160,4 @@ cumulus-client-collator = "0.8.0" cumulus-client-consensus-aura = "0.8.0" cumulus-client-consensus-common = "0.8.0" cumulus-client-consensus-proposer = "0.8.0" -cumulus-client-service = "0.8.0" \ No newline at end of file +cumulus-client-service = "0.8.0" diff --git a/pop-api/Cargo.toml b/pop-api/Cargo.toml index 9a868cfa..2dd4519c 100644 --- a/pop-api/Cargo.toml +++ b/pop-api/Cargo.toml @@ -9,9 +9,9 @@ edition = "2021" enumflags2 = { version = "0.7.7" } ink = { version = "5.0.0", default-features = false } scale = { package = "parity-scale-codec", version = "3", default-features = false, features = ["derive"] } -scale-info = { version = "2.6", default-features = false, features = ["derive"] } -sp-io = { version = "23.0.0", default-features = false, features = ["disable_panic_handler", "disable_oom", "disable_allocator"] } -sp-runtime = { version = "24.0", default-features = false } +scale-info = { version = "2.10.0", default-features = false, features = ["derive"] } +sp-io = { version = "31.0.0", default-features = false, features = ["disable_panic_handler", "disable_oom", "disable_allocator"] } +sp-runtime = { version = "32.0.0", default-features = false } pop-primitives = { path = "../primitives", features = ["devnet"], default-features = false } diff --git a/pop-api/examples/.gitignore b/pop-api/examples/.gitignore index e0caa493..d60800c8 100755 --- a/pop-api/examples/.gitignore +++ b/pop-api/examples/.gitignore @@ -1,9 +1,9 @@ # Ignore build artifacts from the local tests sub-crate. -/fungibles/target/ +**/target/ # Ignore backup files creates by cargo fmt. **/*.rs.bk # Remove Cargo.lock when creating an executable, leave it for libraries # More information here http://doc.crates.io/guide.html#cargotoml-vs-cargolock -Cargo.lock +**/Cargo.lock diff --git a/pop-api/examples/fungibles/lib.rs b/pop-api/examples/fungibles/lib.rs index 41ea1b14..35719ac6 100755 --- a/pop-api/examples/fungibles/lib.rs +++ b/pop-api/examples/fungibles/lib.rs @@ -12,7 +12,7 @@ use pop_api::{ primitives::{AccountId as AccountId32, AssetId}, }; -pub type Result = core::result::Result; +pub type Result = core::result::Result; #[ink::contract(env = pop_api::Environment)] mod fungibles { @@ -68,9 +68,9 @@ mod fungibles { value, ); - let result = api::transfer(id, to, value).map_err(|e| e.into()); + let result = api::transfer(id, to, value); ink::env::debug_println!("Result: {:?}", result); - result + result.map_err(|e| e.into()) } #[ink(message)] @@ -91,9 +91,9 @@ mod fungibles { value, ); - let result = api::transfer_from(id, from, to, value, &data).map_err(|e| e.into()); + let result = api::transfer_from(id, from, to, value, &data); ink::env::debug_println!("Result: {:?}", result); - result + result.map_err(|e| e.into()) } /// 2. PSP-22 Metadata Interface: @@ -118,9 +118,9 @@ mod fungibles { admin, min_balance, ); - let result = api::create(id, admin, min_balance).map_err(|e| e.into()); + let result = api::create(id, admin, min_balance); ink::env::debug_println!("Result: {:?}", result); - result + result.map_err(|e| e.into()) } #[ink(message)] @@ -138,9 +138,9 @@ mod fungibles { symbol, decimals, ); - let result = api::set_metadata(id, name, symbol, decimals).map_err(|e| e.into()); + let result = api::set_metadata(id, name, symbol, decimals); ink::env::debug_println!("Result: {:?}", result); - result + result.map_err(|e| e.into()) } #[ink(message)] diff --git a/pop-api/integration-tests/Cargo.toml b/pop-api/integration-tests/Cargo.toml new file mode 100644 index 00000000..84769433 --- /dev/null +++ b/pop-api/integration-tests/Cargo.toml @@ -0,0 +1,31 @@ +[package] +name = "integration-tests" +version = "0.1.0" +edition = "2021" + +[dev-dependencies] +env_logger = "0.11.2" +scale = { package = "parity-scale-codec", version = "3.0.0", default-features = false, features = ["derive"] } +frame-support = { version = "29.0.0", default-features = false } +frame-system = { version = "29.0.0", default-features = false } +pallet-balances = { version = "29.0.2", default-features = false } +pallet-contracts = { version = "28.0.0", default-features = false } +pop-api = { path = "../.", default-features = false, features = ["assets"] } +pop-runtime-devnet = { path = "../../runtime/devnet", default-features = false } +sp-io = { version = "31.0.0", default-features = false } +sp-runtime = { version = "32.0.0", default-features = false } + + +[features] +default = ["std"] +std = [ + "frame-support/std", + "frame-system/std", + "pallet-balances/std", + "pallet-contracts/std", + "pop-api/std", + "pop-runtime-devnet/std", + "scale/std", + "sp-io/std", + "sp-runtime/std", +] \ No newline at end of file diff --git a/pop-api/integration-tests/src/lib.rs b/pop-api/integration-tests/src/lib.rs new file mode 100644 index 00000000..624c3000 --- /dev/null +++ b/pop-api/integration-tests/src/lib.rs @@ -0,0 +1,95 @@ +#![cfg(test)] + +use frame_support::{ + traits::fungibles::{approvals::Inspect as ApprovalInspect, Inspect}, + weights::Weight, +}; +use pallet_contracts::{Code, CollectEvents, Determinism, ExecReturnValue}; +use scale::{Decode, Encode}; +use sp_runtime::{traits::Hash, AccountId32, BuildStorage, DispatchError}; + +use pop_runtime_devnet::{Assets, Contracts, Runtime, RuntimeOrigin, System, UNIT}; + +mod local_fungibles; + +type Balance = u128; +type AssetId = u32; +const DEBUG_OUTPUT: pallet_contracts::DebugInfo = pallet_contracts::DebugInfo::UnsafeDebug; + +const ALICE: AccountId32 = AccountId32::new([1_u8; 32]); +const BOB: AccountId32 = AccountId32::new([2_u8; 32]); +// FERDIE has no initial balance. +const FERDIE: AccountId32 = AccountId32::new([3_u8; 32]); +const INIT_AMOUNT: Balance = 100_000_000 * UNIT; +const INIT_VALUE: Balance = 100 * UNIT; +const GAS_LIMIT: Weight = Weight::from_parts(100_000_000_000, 3 * 1024 * 1024); + +fn new_test_ext() -> sp_io::TestExternalities { + let mut t = frame_system::GenesisConfig::::default() + .build_storage() + .expect("Frame system builds valid default genesis config"); + + pallet_balances::GenesisConfig:: { + balances: vec![(ALICE, INIT_AMOUNT), (BOB, INIT_AMOUNT)], + } + .assimilate_storage(&mut t) + .expect("Pallet balances storage can be assimilated"); + + let mut ext = sp_io::TestExternalities::new(t); + ext.execute_with(|| System::set_block_number(1)); + ext +} + +fn load_wasm_module(path: &str) -> std::io::Result<(Vec, ::Output)> +where + T: frame_system::Config, +{ + let wasm_binary = std::fs::read(path)?; + let code_hash = T::Hashing::hash(&wasm_binary); + Ok((wasm_binary, code_hash)) +} + +fn function_selector(name: &str) -> Vec { + let hash = sp_io::hashing::blake2_256(name.as_bytes()); + [hash[0..4].to_vec()].concat() +} + +fn do_bare_call( + addr: AccountId32, + input: Vec, + value: u128, +) -> Result { + let result = Contracts::bare_call( + ALICE, + addr.into(), + value.into(), + GAS_LIMIT, + None, + input, + DEBUG_OUTPUT, + CollectEvents::Skip, + Determinism::Enforced, + ); + result.result +} + +// Deploy, instantiate and return contract address. +fn instantiate(contract: &str, init_value: u128, salt: Vec) -> AccountId32 { + let (wasm_binary, _) = + load_wasm_module::(contract).expect("could not read .wasm file"); + let result = Contracts::bare_instantiate( + ALICE, + init_value, + GAS_LIMIT, + None, + Code::Upload(wasm_binary), + function_selector("new"), + salt, + DEBUG_OUTPUT, + CollectEvents::Skip, + ) + .result + .unwrap(); + assert!(!result.result.did_revert(), "deploying contract reverted {:?}", result); + result.account_id +} diff --git a/runtime/devnet/src/tests/local_fungibles.rs b/pop-api/integration-tests/src/local_fungibles.rs similarity index 88% rename from runtime/devnet/src/tests/local_fungibles.rs rename to pop-api/integration-tests/src/local_fungibles.rs index ac2b8ca0..1b3c6633 100644 --- a/runtime/devnet/src/tests/local_fungibles.rs +++ b/pop-api/integration-tests/src/local_fungibles.rs @@ -1,16 +1,8 @@ -// Todo - errors: -// - Badorigin: contract is always signed -// - Lookup: is a valid AccountId due to the contract -// - Many errors can occur from calling a dispatchable. All the DispatchErrors are handled by the -// pop api but not all the possible errors for each dipatchable are tested. How should I approach -// this? -#![cfg(test)] - use super::*; - -use pop_api::{ - error::{ArithmeticError::*, Error::*, TokenError::*}, - v0::assets::fungibles::FungiblesError::*, +use pop_api::error::{ + ArithmeticError::*, + Error::{self, *}, + TokenError::*, }; const ASSET_ID: AssetId = 1; @@ -196,11 +188,8 @@ fn total_supply_works() { fn balance_of_works() { new_test_ext().execute_with(|| { let _ = env_logger::try_init(); - let addr = instantiate( - "../../pop-api/examples/fungibles/target/ink/fungibles.wasm", - INIT_VALUE, - vec![], - ); + let addr = + instantiate("../examples/fungibles/target/ink/fungibles.wasm", INIT_VALUE, vec![]); // No tokens in circulation. assert_eq!(Assets::balance(ASSET_ID, BOB), balance_of(addr.clone(), ASSET_ID, BOB)); @@ -216,11 +205,8 @@ fn balance_of_works() { fn allowance_works() { new_test_ext().execute_with(|| { let _ = env_logger::try_init(); - let addr = instantiate( - "../../pop-api/examples/fungibles/target/ink/fungibles.wasm", - INIT_VALUE, - vec![], - ); + let addr = + instantiate("../examples/fungibles/target/ink/fungibles.wasm", INIT_VALUE, vec![]); // No tokens in circulation. assert_eq!( @@ -242,11 +228,8 @@ fn allowance_works() { fn asset_exists_works() { new_test_ext().execute_with(|| { let _ = env_logger::try_init(); - let addr = instantiate( - "../../pop-api/examples/fungibles/target/ink/fungibles.wasm", - INIT_VALUE, - vec![], - ); + let addr = + instantiate("../examples/fungibles/target/ink/fungibles.wasm", INIT_VALUE, vec![]); // No tokens in circulation. assert_eq!(Assets::asset_exists(ASSET_ID), asset_exists(addr.clone(), ASSET_ID)); @@ -264,16 +247,14 @@ fn create_works() { let _ = env_logger::try_init(); let new_asset = 2; // Instantiate a contract without balance (relay token). - let addr = - instantiate("../../pop-api/examples/fungibles/target/ink/fungibles.wasm", 0, vec![0]); + let addr = instantiate("../examples/fungibles/target/ink/fungibles.wasm", 0, vec![0]); // No balance to pay for fees. assert_eq!( decoded::(create(addr.clone(), ASSET_ID, addr.clone(), 1)), Module { index: 10, error: 2 }, ); // Instantiate a contract without balance (relay token). - let addr = - instantiate("../../pop-api/examples/fungibles/target/ink/fungibles.wasm", 100, vec![2]); + let addr = instantiate("../examples/fungibles/target/ink/fungibles.wasm", 100, vec![2]); // TODO: make sure it has enough for the fees but not for the deposit. // No balance to pay fe deposit. assert_eq!( @@ -281,11 +262,8 @@ fn create_works() { Module { index: 10, error: 2 }, ); // Instantiate a contract with balance. - let addr = instantiate( - "../../pop-api/examples/fungibles/target/ink/fungibles.wasm", - INIT_VALUE, - vec![1], - ); + let addr = + instantiate("../examples/fungibles/target/ink/fungibles.wasm", INIT_VALUE, vec![1]); create_asset(ALICE, ASSET_ID, 1); // Asset ID is already taken. assert_eq!( @@ -307,11 +285,8 @@ fn create_works() { fn set_metadata_works() { new_test_ext().execute_with(|| { let _ = env_logger::try_init(); - let addr = instantiate( - "../../pop-api/examples/fungibles/target/ink/fungibles.wasm", - INIT_VALUE, - vec![], - ); + let addr = + instantiate("../examples/fungibles/target/ink/fungibles.wasm", INIT_VALUE, vec![]); create_asset(addr.clone(), ASSET_ID, 1); let result = set_metadata(addr.clone(), ASSET_ID, vec![12], vec![12], 12); @@ -324,11 +299,8 @@ fn set_metadata_works() { fn transfer_from_mint_works() { new_test_ext().execute_with(|| { let _ = env_logger::try_init(); - let addr = instantiate( - "../../pop-api/examples/fungibles/target/ink/fungibles.wasm", - INIT_VALUE, - vec![], - ); + let addr = + instantiate("../examples/fungibles/target/ink/fungibles.wasm", INIT_VALUE, vec![]); let amount: Balance = 100 * UNIT; // Asset does not exist. @@ -387,11 +359,8 @@ fn transfer_from_mint_works() { fn transfer_works() { new_test_ext().execute_with(|| { let _ = env_logger::try_init(); - let addr = instantiate( - "../../pop-api/examples/fungibles/target/ink/fungibles.wasm", - INIT_VALUE, - vec![], - ); + let addr = + instantiate("../examples/fungibles/target/ink/fungibles.wasm", INIT_VALUE, vec![]); let amount: Balance = 100 * UNIT; // Asset does not exist. diff --git a/pop-api/src/lib.rs b/pop-api/src/lib.rs index 3e9ead7f..c516adff 100644 --- a/pop-api/src/lib.rs +++ b/pop-api/src/lib.rs @@ -21,8 +21,7 @@ pub mod v0; type AccountId = AccountId32; // TODO: do the same as the AccountId above and check expanded macro code. -// type Balance = ::Balance; -type Balance = u128; +type Balance = ::Balance; #[cfg(any(feature = "nfts", feature = "cross-chain"))] type BlockNumber = ::BlockNumber; diff --git a/pop-api/src/v0/assets/mod.rs b/pop-api/src/v0/assets/mod.rs index d67d30bd..778387cb 100644 --- a/pop-api/src/v0/assets/mod.rs +++ b/pop-api/src/v0/assets/mod.rs @@ -298,18 +298,18 @@ pub(crate) fn block(id: AssetId, who: impl Into>) -> /// - pub(crate) fn total_supply(id: AssetId) -> Result { - state::read(RuntimeStateKeys::Assets(AssetsKeys::TotalSupply(id))).into() + state::read(RuntimeStateKeys::Assets(AssetsKeys::TotalSupply(id))) } pub(crate) fn balance_of(id: AssetId, owner: AccountId) -> Result { - state::read(RuntimeStateKeys::Assets(AssetsKeys::BalanceOf(id, owner))).into() + state::read(RuntimeStateKeys::Assets(AssetsKeys::BalanceOf(id, owner))) } pub(crate) fn allowance(id: AssetId, owner: AccountId, spender: AccountId) -> Result { - state::read(RuntimeStateKeys::Assets(AssetsKeys::Allowance(id, owner, spender))).into() + state::read(RuntimeStateKeys::Assets(AssetsKeys::Allowance(id, owner, spender))) } pub(crate) fn asset_exists(id: AssetId) -> Result { - state::read(RuntimeStateKeys::Assets(AssetsKeys::AssetExists(id))).into() + state::read(RuntimeStateKeys::Assets(AssetsKeys::AssetExists(id))) } // Parameters to extrinsics representing an asset id (`AssetIdParameter`) and a balance amount (`Balance`) are expected diff --git a/primitives/Cargo.toml b/primitives/Cargo.toml index 6ba3fea7..cb19b0ab 100644 --- a/primitives/Cargo.toml +++ b/primitives/Cargo.toml @@ -7,10 +7,10 @@ edition = "2021" [dependencies] bounded-collections = { version = "0.1", default-features = false } -scale = { package = "parity-scale-codec", version = "3.6.9", default-features = false, features = ["derive"] } +scale = { package = "parity-scale-codec", version = "3", default-features = false, features = ["derive"] } scale-decode = { version = "0.10.0", default-features = false, features = ["derive"], optional = true } scale-encode = { version = "0.5.0", default-features = false, features = ["derive"], optional = true } -scale-info = { version = "2.6", default-features = false, features = ["derive"], optional = true } +scale-info = { version = "2.10", default-features = false, features = ["derive"], optional = true } [features] default = ["std"] diff --git a/primitives/src/storage_keys.rs b/primitives/src/storage_keys.rs index 4be95986..5fc7cdb3 100644 --- a/primitives/src/storage_keys.rs +++ b/primitives/src/storage_keys.rs @@ -4,12 +4,12 @@ use super::*; #[derive(Encode, Decode, Debug, MaxEncodedLen)] pub enum RuntimeStateKeys { + #[cfg(feature = "assets")] + Assets(AssetsKeys), #[cfg(feature = "nfts")] Nfts(NftsKeys), #[cfg(feature = "cross-chain")] ParachainSystem(ParachainSystemKeys), - #[cfg(feature = "assets")] - Assets(AssetsKeys), } #[cfg(feature = "cross-chain")] diff --git a/runtime/devnet/Cargo.toml b/runtime/devnet/Cargo.toml index b72bf4f7..5f52b855 100644 --- a/runtime/devnet/Cargo.toml +++ b/runtime/devnet/Cargo.toml @@ -91,7 +91,6 @@ parachain-info.workspace = true env_logger = "0.11.2" hex = "0.4.3" enumflags2 = "0.7.9" -pop-api = { path = "../../pop-api", features = ["assets", "cross-chain", "nfts"] } [features] default = ["std"] @@ -139,7 +138,6 @@ std = [ "polkadot-parachain-primitives/std", "polkadot-runtime-common/std", "pop-primitives/std", - "pop-api/std", "scale-info/std", "sp-api/std", "sp-io/std", diff --git a/runtime/devnet/src/extensions.rs b/runtime/devnet/src/extensions.rs index 9db31e83..904d18ce 100644 --- a/runtime/devnet/src/extensions.rs +++ b/runtime/devnet/src/extensions.rs @@ -390,6 +390,186 @@ where dispatch_call::(&mut env, call, origin, LOG_PREFIX) } +#[cfg(test)] +mod tests { + use super::*; + use crate::{Assets, Runtime, System}; + use sp_runtime::BuildStorage; + + fn new_test_ext() -> sp_io::TestExternalities { + let t = frame_system::GenesisConfig::::default() + .build_storage() + .expect("Frame system builds valid default genesis config"); + let mut ext = sp_io::TestExternalities::new(t); + ext.execute_with(|| System::set_block_number(1)); + ext + } + + #[test] + fn encoding_decoding_dispatch_error() { + use codec::{Decode, Encode}; + use sp_runtime::{ArithmeticError, DispatchError, ModuleError, TokenError}; + + new_test_ext().execute_with(|| { + let error = DispatchError::Module(ModuleError { + index: 255, + error: [2, 0, 0, 0], + message: Some("error message"), + }); + let encoded = error.encode(); + let decoded = DispatchError::decode(&mut &encoded[..]).unwrap(); + assert_eq!(encoded, vec![3, 255, 2, 0, 0, 0]); + assert_eq!( + decoded, + // `message` is skipped for encoding. + DispatchError::Module(ModuleError { + index: 255, + error: [2, 0, 0, 0], + message: None + }) + ); + println!("Encoded Module Error: {:?}", encoded); + + // Example pallet assets Error into ModuleError. + let index = + <::PalletInfo as frame_support::traits::PalletInfo>::index::< + Assets, + >() + .expect("Every active module has an index in the runtime; qed") as u8; + + let mut error = + pallet_assets::Error::NotFrozen::.encode(); + error.resize(MAX_MODULE_ERROR_ENCODED_SIZE, 0); + let error = DispatchError::Module(ModuleError { + index, + error: TryInto::try_into(error).expect("should work"), + message: None, + }); + let encoded = error.encode(); + let decoded = DispatchError::decode(&mut &encoded[..]).unwrap(); + assert_eq!(encoded, vec![3, 52, 18, 0, 0, 0]); + assert_eq!( + decoded, + DispatchError::Module(ModuleError { + index: 52, + error: [18, 0, 0, 0], + message: None + }) + ); + println!("Encoded Module Error: {:?}", encoded); + + // Example DispatchError::Token + let error = DispatchError::Token(TokenError::UnknownAsset); + let encoded = error.encode(); + assert_eq!(encoded, vec![7, 4]); + println!("Encoded Token Error: {:?}", encoded); + + // Example DispatchError::Arithmetic + let error = DispatchError::Arithmetic(ArithmeticError::Overflow); + let encoded = error.encode(); + assert_eq!(encoded, vec![8, 1]); + println!("Encoded Arithmetic Error: {:?}", encoded); + }); + } + + #[test] + fn encoding_of_enum() { + use codec::{Decode, Encode}; + + // Comprehensive enum with all different type of variants. + #[derive(Debug, PartialEq, Encode, Decode)] + enum ComprehensiveEnum { + SimpleVariant, + DataVariant(u8), + NamedFields { w: u8 }, + NestedEnum(InnerEnum), + OptionVariant(Option), + VecVariant(Vec), + TupleVariant(u8, u8), + NestedStructVariant(NestedStruct), + NestedEnumStructVariant(NestedEnumStruct), + } + + #[derive(Debug, PartialEq, Encode, Decode)] + enum InnerEnum { + A, + B { inner_data: u8 }, + C(u8), + } + + #[derive(Debug, PartialEq, Encode, Decode)] + struct NestedStruct { + x: u8, + y: u8, + } + + #[derive(Debug, PartialEq, Encode, Decode)] + struct NestedEnumStruct { + inner_enum: InnerEnum, + } + + // Creating each possible variant for an enum. + let enum_simple = ComprehensiveEnum::SimpleVariant; + let enum_data = ComprehensiveEnum::DataVariant(42); + let enum_named = ComprehensiveEnum::NamedFields { w: 42 }; + let enum_nested = ComprehensiveEnum::NestedEnum(InnerEnum::B { inner_data: 42 }); + let enum_option = ComprehensiveEnum::OptionVariant(Some(42)); + let enum_vec = ComprehensiveEnum::VecVariant(vec![1, 2, 3, 4, 5]); + let enum_tuple = ComprehensiveEnum::TupleVariant(42, 42); + let enum_nested_struct = + ComprehensiveEnum::NestedStructVariant(NestedStruct { x: 42, y: 42 }); + let enum_nested_enum_struct = + ComprehensiveEnum::NestedEnumStructVariant(NestedEnumStruct { + inner_enum: InnerEnum::C(42), + }); + + // Encode and print each variant individually to see their encoded values. + println!("{:?} -> {:?}", enum_simple, enum_simple.encode()); + println!("{:?} -> {:?}", enum_data, enum_data.encode()); + println!("{:?} -> {:?}", enum_named, enum_named.encode()); + println!("{:?} -> {:?}", enum_nested, enum_nested.encode()); + println!("{:?} -> {:?}", enum_option, enum_option.encode()); + println!("{:?} -> {:?}", enum_vec, enum_vec.encode()); + println!("{:?} -> {:?}", enum_tuple, enum_tuple.encode()); + println!("{:?} -> {:?}", enum_nested_struct, enum_nested_struct.encode()); + println!("{:?} -> {:?}", enum_nested_enum_struct, enum_nested_enum_struct.encode()); + } + + #[test] + fn dispatch_error_to_status_code() { + // Create all the different `DispatchError` variants with its respective `PopApiError`. + let test_cases = vec![ + (DispatchError::Other("hallo"), [0, 0, 0, 0]), + (DispatchError::CannotLookup, [1, 0, 0, 0]), + (DispatchError::BadOrigin, [2, 0, 0, 0]), + ( + DispatchError::Module(sp_runtime::ModuleError { + index: 1, + error: [2, 0, 0, 0], + message: Some("hallo"), + }), + [3, 1, 2, 0], + ), + (DispatchError::ConsumerRemaining, [4, 0, 0, 0]), + (DispatchError::NoProviders, [5, 0, 0, 0]), + (DispatchError::TooManyConsumers, [6, 0, 0, 0]), + (DispatchError::Token(sp_runtime::TokenError::BelowMinimum), [7, 2, 0, 0]), + (DispatchError::Arithmetic(sp_runtime::ArithmeticError::Overflow), [8, 1, 0, 0]), + ( + DispatchError::Transactional(sp_runtime::TransactionalError::LimitReached), + [9, 0, 0, 0], + ), + (DispatchError::Exhausted, [10, 0, 0, 0]), + (DispatchError::Corruption, [11, 0, 0, 0]), + (DispatchError::Unavailable, [12, 0, 0, 0]), + (DispatchError::RootNotAllowed, [13, 0, 0, 0]), + ]; + for (error, encoded_error) in test_cases { + let status_code = crate::extensions::convert_to_status_code(error); + assert_eq!(status_code, u32::decode(&mut &encoded_error[..]).unwrap()); + } + } +} // use enumflags2::BitFlags; // use pallet_nfts::{CollectionConfig, CollectionSetting, CollectionSettings, MintSettings}; // use parachains_common::CollectionId; diff --git a/runtime/devnet/src/lib.rs b/runtime/devnet/src/lib.rs index b03bdac6..9ab64043 100644 --- a/runtime/devnet/src/lib.rs +++ b/runtime/devnet/src/lib.rs @@ -10,8 +10,6 @@ mod extensions; mod weights; // Public due to integration tests crate. pub mod config; -#[cfg(test)] -mod tests; use cumulus_pallet_parachain_system::RelayNumberMonotonicallyIncreases; use polkadot_runtime_common::xcm_sender::NoPriceForMessageDelivery; diff --git a/runtime/devnet/src/tests/mod.rs b/runtime/devnet/src/tests/mod.rs deleted file mode 100644 index 828aa06b..00000000 --- a/runtime/devnet/src/tests/mod.rs +++ /dev/null @@ -1,267 +0,0 @@ -#![cfg(test)] - -use codec::{Decode, Encode}; -use frame_support::traits::fungibles::{approvals::Inspect as ApprovalInspect, Inspect}; -use frame_system::Config; -use pallet_contracts::{Code, CollectEvents, Determinism, ExecReturnValue}; -use sp_runtime::{traits::Hash, AccountId32, BuildStorage, DispatchError}; - -use crate::{Assets, Contracts, Runtime, RuntimeOrigin, System, Weight, UNIT}; - -mod local_fungibles; - -type Balance = u128; -type AssetId = u32; -const DEBUG_OUTPUT: pallet_contracts::DebugInfo = pallet_contracts::DebugInfo::UnsafeDebug; - -const ALICE: AccountId32 = AccountId32::new([1_u8; 32]); -const BOB: AccountId32 = AccountId32::new([2_u8; 32]); -// FERDIE has no initial balance. -const FERDIE: AccountId32 = AccountId32::new([3_u8; 32]); -const INIT_AMOUNT: Balance = 100_000_000 * UNIT; -const INIT_VALUE: Balance = 100 * UNIT; -const GAS_LIMIT: Weight = Weight::from_parts(100_000_000_000, 3 * 1024 * 1024); - -fn new_test_ext() -> sp_io::TestExternalities { - let mut t = frame_system::GenesisConfig::::default() - .build_storage() - .expect("Frame system builds valid default genesis config"); - - pallet_balances::GenesisConfig:: { - balances: vec![(ALICE, INIT_AMOUNT), (BOB, INIT_AMOUNT)], - } - .assimilate_storage(&mut t) - .expect("Pallet balances storage can be assimilated"); - - let mut ext = sp_io::TestExternalities::new(t); - ext.execute_with(|| System::set_block_number(1)); - ext -} - -fn load_wasm_module(path: &str) -> std::io::Result<(Vec, ::Output)> -where - T: frame_system::Config, -{ - let wasm_binary = std::fs::read(path)?; - let code_hash = T::Hashing::hash(&wasm_binary); - Ok((wasm_binary, code_hash)) -} - -fn function_selector(name: &str) -> Vec { - let hash = sp_io::hashing::blake2_256(name.as_bytes()); - [hash[0..4].to_vec()].concat() -} - -fn do_bare_call( - addr: AccountId32, - input: Vec, - value: u128, -) -> Result { - let result = Contracts::bare_call( - ALICE, - addr.into(), - value.into(), - GAS_LIMIT, - None, - input, - DEBUG_OUTPUT, - CollectEvents::Skip, - Determinism::Enforced, - ); - log::debug!("Contract debug buffer - {:?}", String::from_utf8(result.debug_message.clone())); - log::debug!("result: {:?}", result); - result.result -} - -// Deploy, instantiate and return contract address. -fn instantiate(contract: &str, init_value: u128, salt: Vec) -> AccountId32 { - let (wasm_binary, _) = - load_wasm_module::(contract).expect("could not read .wasm file"); - let result = Contracts::bare_instantiate( - ALICE, - init_value, - GAS_LIMIT, - None, - Code::Upload(wasm_binary), - function_selector("new"), - salt, - DEBUG_OUTPUT, - CollectEvents::Skip, - ) - .result - .unwrap(); - assert!(!result.result.did_revert(), "deploying contract reverted {:?}", result); - result.account_id -} - -mod encoding { - use super::*; - use crate::config::assets::TrustBackedAssetsInstance; - use crate::Runtime; - use sp_runtime::DispatchError; - - #[test] - fn encoding_decoding_dispatch_error() { - use codec::{Decode, Encode}; - use sp_runtime::{ArithmeticError, DispatchError, ModuleError, TokenError}; - - new_test_ext().execute_with(|| { - let error = DispatchError::Module(ModuleError { - index: 255, - error: [2, 0, 0, 0], - message: Some("error message"), - }); - let encoded = error.encode(); - let decoded = DispatchError::decode(&mut &encoded[..]).unwrap(); - assert_eq!(encoded, vec![3, 255, 2, 0, 0, 0]); - assert_eq!( - decoded, - // `message` is skipped for encoding. - DispatchError::Module(ModuleError { - index: 255, - error: [2, 0, 0, 0], - message: None - }) - ); - println!("Encoded Module Error: {:?}", encoded); - - // Example pallet assets Error into ModuleError. - let index = - <::PalletInfo as frame_support::traits::PalletInfo>::index::< - Assets, - >() - .expect("Every active module has an index in the runtime; qed") as u8; - - let mut error = - pallet_assets::Error::NotFrozen::.encode(); - error.resize(sp_runtime::MAX_MODULE_ERROR_ENCODED_SIZE, 0); - let error = DispatchError::Module(ModuleError { - index, - error: TryInto::try_into(error).expect("should work"), - message: None, - }); - let encoded = error.encode(); - let decoded = DispatchError::decode(&mut &encoded[..]).unwrap(); - assert_eq!(encoded, vec![3, 52, 18, 0, 0, 0]); - assert_eq!( - decoded, - DispatchError::Module(ModuleError { - index: 52, - error: [18, 0, 0, 0], - message: None - }) - ); - println!("Encoded Module Error: {:?}", encoded); - - // Example DispatchError::Token - let error = DispatchError::Token(TokenError::UnknownAsset); - let encoded = error.encode(); - assert_eq!(encoded, vec![7, 4]); - println!("Encoded Token Error: {:?}", encoded); - - // Example DispatchError::Arithmetic - let error = DispatchError::Arithmetic(ArithmeticError::Overflow); - let encoded = error.encode(); - assert_eq!(encoded, vec![8, 1]); - println!("Encoded Arithmetic Error: {:?}", encoded); - }); - } - - #[test] - fn encoding_of_enum() { - use codec::{Decode, Encode}; - - // Comprehensive enum with all different type of variants. - #[derive(Debug, PartialEq, Encode, Decode)] - enum ComprehensiveEnum { - SimpleVariant, - DataVariant(u8), - NamedFields { w: u8 }, - NestedEnum(InnerEnum), - OptionVariant(Option), - VecVariant(Vec), - TupleVariant(u8, u8), - NestedStructVariant(NestedStruct), - NestedEnumStructVariant(NestedEnumStruct), - } - - #[derive(Debug, PartialEq, Encode, Decode)] - enum InnerEnum { - A, - B { inner_data: u8 }, - C(u8), - } - - #[derive(Debug, PartialEq, Encode, Decode)] - struct NestedStruct { - x: u8, - y: u8, - } - - #[derive(Debug, PartialEq, Encode, Decode)] - struct NestedEnumStruct { - inner_enum: InnerEnum, - } - - // Creating each possible variant for an enum. - let enum_simple = ComprehensiveEnum::SimpleVariant; - let enum_data = ComprehensiveEnum::DataVariant(42); - let enum_named = ComprehensiveEnum::NamedFields { w: 42 }; - let enum_nested = ComprehensiveEnum::NestedEnum(InnerEnum::B { inner_data: 42 }); - let enum_option = ComprehensiveEnum::OptionVariant(Some(42)); - let enum_vec = ComprehensiveEnum::VecVariant(vec![1, 2, 3, 4, 5]); - let enum_tuple = ComprehensiveEnum::TupleVariant(42, 42); - let enum_nested_struct = - ComprehensiveEnum::NestedStructVariant(NestedStruct { x: 42, y: 42 }); - let enum_nested_enum_struct = - ComprehensiveEnum::NestedEnumStructVariant(NestedEnumStruct { - inner_enum: InnerEnum::C(42), - }); - - // Encode and print each variant individually to see their encoded values. - println!("{:?} -> {:?}", enum_simple, enum_simple.encode()); - println!("{:?} -> {:?}", enum_data, enum_data.encode()); - println!("{:?} -> {:?}", enum_named, enum_named.encode()); - println!("{:?} -> {:?}", enum_nested, enum_nested.encode()); - println!("{:?} -> {:?}", enum_option, enum_option.encode()); - println!("{:?} -> {:?}", enum_vec, enum_vec.encode()); - println!("{:?} -> {:?}", enum_tuple, enum_tuple.encode()); - println!("{:?} -> {:?}", enum_nested_struct, enum_nested_struct.encode()); - println!("{:?} -> {:?}", enum_nested_enum_struct, enum_nested_enum_struct.encode()); - } - - #[test] - fn dispatch_error_to_status_code() { - // Create all the different `DispatchError` variants with its respective `PopApiError`. - let test_cases = vec![ - (DispatchError::Other("hallo"), [0, 0, 0, 0]), - (DispatchError::CannotLookup, [1, 0, 0, 0]), - (DispatchError::BadOrigin, [2, 0, 0, 0]), - ( - DispatchError::Module(sp_runtime::ModuleError { - index: 1, - error: [2, 0, 0, 0], - message: Some("hallo"), - }), - [3, 1, 2, 0], - ), - (DispatchError::ConsumerRemaining, [4, 0, 0, 0]), - (DispatchError::NoProviders, [5, 0, 0, 0]), - (DispatchError::TooManyConsumers, [6, 0, 0, 0]), - (DispatchError::Token(sp_runtime::TokenError::BelowMinimum), [7, 2, 0, 0]), - (DispatchError::Arithmetic(sp_runtime::ArithmeticError::Overflow), [8, 1, 0, 0]), - ( - DispatchError::Transactional(sp_runtime::TransactionalError::LimitReached), - [9, 0, 0, 0], - ), - (DispatchError::Exhausted, [10, 0, 0, 0]), - (DispatchError::Corruption, [11, 0, 0, 0]), - (DispatchError::Unavailable, [12, 0, 0, 0]), - (DispatchError::RootNotAllowed, [13, 0, 0, 0]), - ]; - for (error, encoded_error) in test_cases { - let status_code = crate::extensions::convert_to_status_code(error); - assert_eq!(status_code, u32::decode(&mut &encoded_error[..]).unwrap()); - } - } -} From c1616a3611f73f0185f822339c452549c63b2926 Mon Sep 17 00:00:00 2001 From: Daanvdplas Date: Wed, 26 Jun 2024 15:41:18 +0200 Subject: [PATCH 013/112] refactor: naming pallet error --- pop-api/Cargo.toml | 6 +- pop-api/src/lib.rs | 2 +- pop-api/src/v0/cross_chain/mod.rs | 8 +- pop-api/src/v0/nfts.rs | 308 +++++++++++++++--------------- primitives/src/storage_keys.rs | 11 +- 5 files changed, 170 insertions(+), 165 deletions(-) diff --git a/pop-api/Cargo.toml b/pop-api/Cargo.toml index 2dd4519c..8454c1fa 100644 --- a/pop-api/Cargo.toml +++ b/pop-api/Cargo.toml @@ -5,12 +5,15 @@ license = "GPL-3.0-only" version = "0.0.0" edition = "2021" +[workspace] +exclude = [ + "integration-tests", +] [dependencies] enumflags2 = { version = "0.7.7" } ink = { version = "5.0.0", default-features = false } scale = { package = "parity-scale-codec", version = "3", default-features = false, features = ["derive"] } scale-info = { version = "2.10.0", default-features = false, features = ["derive"] } -sp-io = { version = "31.0.0", default-features = false, features = ["disable_panic_handler", "disable_oom", "disable_allocator"] } sp-runtime = { version = "32.0.0", default-features = false } pop-primitives = { path = "../primitives", features = ["devnet"], default-features = false } @@ -28,7 +31,6 @@ std = [ "pop-primitives/std", "scale/std", "scale-info/std", - "sp-io/std", "sp-runtime/std", ] assets = ["pop-primitives/assets"] diff --git a/pop-api/src/lib.rs b/pop-api/src/lib.rs index c516adff..04d08bce 100644 --- a/pop-api/src/lib.rs +++ b/pop-api/src/lib.rs @@ -1,7 +1,7 @@ #![cfg_attr(not(feature = "std"), no_std, no_main)] use ink::{prelude::vec::Vec, ChainExtensionInstance}; -pub use sp_runtime::{BoundedVec, MultiAddress, MultiSignature}; +pub use sp_runtime::{MultiAddress, MultiSignature}; use crate::error::{Error, StatusCode}; use primitives::{storage_keys::*, AccountId as AccountId32}; diff --git a/pop-api/src/v0/cross_chain/mod.rs b/pop-api/src/v0/cross_chain/mod.rs index 5a0dda6c..ad58e0e8 100644 --- a/pop-api/src/v0/cross_chain/mod.rs +++ b/pop-api/src/v0/cross_chain/mod.rs @@ -10,7 +10,7 @@ pub fn relay_chain_block_number() -> Result { #[derive(Debug, Copy, Clone, PartialEq, Eq, scale::Encode, scale::Decode)] #[cfg_attr(feature = "std", derive(scale_info::TypeInfo))] -pub enum Error { +pub enum CrossChainError { /// The desired destination was unreachable, generally because there is a no way of routing /// to it. Unreachable, @@ -66,11 +66,11 @@ pub enum Error { LocalExecutionIncomplete, } -impl TryFrom for Error { - type Error = Error; +impl TryFrom for CrossChainError { + type Error = crate::error::Error; fn try_from(status_code: u32) -> core::result::Result { - use Error::*; + use CrossChainError::*; match status_code { 0 => Ok(Unreachable), 1 => Ok(SendFailure), diff --git a/pop-api/src/v0/nfts.rs b/pop-api/src/v0/nfts.rs index 29219c66..32539576 100644 --- a/pop-api/src/v0/nfts.rs +++ b/pop-api/src/v0/nfts.rs @@ -5,10 +5,10 @@ use crate::{ dispatch, primitives::{ nfts::{ApprovalsLimit, CollectionId, ItemId, KeyLimit}, - BoundedBTreeMap, + BoundedBTreeMap, BoundedVec, }, - state, AccountId, Balance, BlockNumber, BoundedVec, MultiAddress, NftsKeys, RuntimeCall, - RuntimeStateKeys, StatusCode, + state, AccountId, Balance, BlockNumber, MultiAddress, NftsKeys, RuntimeCall, RuntimeStateKeys, + StatusCode, }; pub use types::*; @@ -521,157 +521,157 @@ pub(crate) enum NftCalls { receive_item: ItemId, }, } -// -// #[derive(Debug, Copy, Clone, PartialEq, Eq, Encode, scale::Decode)] -// #[cfg_attr(feature = "std", derive(scale_info::TypeInfo))] -// pub enum Error { -// /// The signing account has no permission to do the operation. -// NoPermission, -// /// The given item ID is unknown. -// UnknownCollection, -// /// The item ID has already been used for an item. -// AlreadyExists, -// /// The approval had a deadline that expired, so the approval isn't valid anymore. -// ApprovalExpired, -// /// The owner turned out to be different to what was expected. -// WrongOwner, -// /// The witness data given does not match the current state of the chain. -// BadWitness, -// /// Collection ID is already taken. -// CollectionIdInUse, -// /// Items within that collection are non-transferable. -// ItemsNonTransferable, -// /// The provided account is not a delegate. -// NotDelegate, -// /// The delegate turned out to be different to what was expected. -// WrongDelegate, -// /// No approval exists that would allow the transfer. -// Unapproved, -// /// The named owner has not signed ownership acceptance of the collection. -// Unaccepted, -// /// The item is locked (non-transferable). -// ItemLocked, -// /// Item's attributes are locked. -// LockedItemAttributes, -// /// Collection's attributes are locked. -// LockedCollectionAttributes, -// /// Item's metadata is locked. -// LockedItemMetadata, -// /// Collection's metadata is locked. -// LockedCollectionMetadata, -// /// All items have been minted. -// MaxSupplyReached, -// /// The max supply is locked and can't be changed. -// MaxSupplyLocked, -// /// The provided max supply is less than the number of items a collection already has. -// MaxSupplyTooSmall, -// /// The given item ID is unknown. -// UnknownItem, -// /// Swap doesn't exist. -// UnknownSwap, -// /// The given item has no metadata set. -// MetadataNotFound, -// /// The provided attribute can't be found. -// AttributeNotFound, -// /// Item is not for sale. -// NotForSale, -// /// The provided bid is too low. -// BidTooLow, -// /// The item has reached its approval limit. -// ReachedApprovalLimit, -// /// The deadline has already expired. -// DeadlineExpired, -// /// The duration provided should be less than or equal to `MaxDeadlineDuration`. -// WrongDuration, -// /// The method is disabled by system settings. -// MethodDisabled, -// /// The provided setting can't be set. -// WrongSetting, -// /// Item's config already exists and should be equal to the provided one. -// InconsistentItemConfig, -// /// Config for a collection or an item can't be found. -// NoConfig, -// /// Some roles were not cleared. -// RolesNotCleared, -// /// Mint has not started yet. -// MintNotStarted, -// /// Mint has already ended. -// MintEnded, -// /// The provided Item was already used for claiming. -// AlreadyClaimed, -// /// The provided data is incorrect. -// IncorrectData, -// /// The extrinsic was sent by the wrong origin. -// WrongOrigin, -// /// The provided signature is incorrect. -// WrongSignature, -// /// The provided metadata might be too long. -// IncorrectMetadata, -// /// Can't set more attributes per one call. -// MaxAttributesLimitReached, -// /// The provided namespace isn't supported in this call. -// WrongNamespace, -// /// Can't delete non-empty collections. -// CollectionNotEmpty, -// /// The witness data should be provided. -// WitnessRequired, -// } -// -// impl TryFrom for Error { -// type Error = Error; -// -// fn try_from(status_code: u32) -> core::result::Result { -// use Error::*; -// match status_code { -// 0 => Ok(NoPermission), -// 1 => Ok(UnknownCollection), -// 2 => Ok(AlreadyExists), -// 3 => Ok(ApprovalExpired), -// 4 => Ok(WrongOwner), -// 5 => Ok(BadWitness), -// 6 => Ok(CollectionIdInUse), -// 7 => Ok(ItemsNonTransferable), -// 8 => Ok(NotDelegate), -// 9 => Ok(WrongDelegate), -// 10 => Ok(Unapproved), -// 11 => Ok(Unaccepted), -// 12 => Ok(ItemLocked), -// 13 => Ok(LockedItemAttributes), -// 14 => Ok(LockedCollectionAttributes), -// 15 => Ok(LockedItemMetadata), -// 16 => Ok(LockedCollectionMetadata), -// 17 => Ok(MaxSupplyReached), -// 18 => Ok(MaxSupplyLocked), -// 19 => Ok(MaxSupplyTooSmall), -// 20 => Ok(UnknownItem), -// 21 => Ok(UnknownSwap), -// 22 => Ok(MetadataNotFound), -// 23 => Ok(AttributeNotFound), -// 24 => Ok(NotForSale), -// 25 => Ok(BidTooLow), -// 26 => Ok(ReachedApprovalLimit), -// 27 => Ok(DeadlineExpired), -// 28 => Ok(WrongDuration), -// 29 => Ok(MethodDisabled), -// 30 => Ok(WrongSetting), -// 31 => Ok(InconsistentItemConfig), -// 32 => Ok(NoConfig), -// 33 => Ok(RolesNotCleared), -// 34 => Ok(MintNotStarted), -// 35 => Ok(MintEnded), -// 36 => Ok(AlreadyClaimed), -// 37 => Ok(IncorrectData), -// 38 => Ok(WrongOrigin), -// 39 => Ok(WrongSignature), -// 40 => Ok(IncorrectMetadata), -// 41 => Ok(MaxAttributesLimitReached), -// 42 => Ok(WrongNamespace), -// 43 => Ok(CollectionNotEmpty), -// 44 => Ok(WitnessRequired), -// _ => todo!(), -// } -// } -// } + +#[derive(Debug, Copy, Clone, PartialEq, Eq, Encode, scale::Decode)] +#[cfg_attr(feature = "std", derive(scale_info::TypeInfo))] +pub enum NftsError { + /// The signing account has no permission to do the operation. + NoPermission, + /// The given item ID is unknown. + UnknownCollection, + /// The item ID has already been used for an item. + AlreadyExists, + /// The approval had a deadline that expired, so the approval isn't valid anymore. + ApprovalExpired, + /// The owner turned out to be different to what was expected. + WrongOwner, + /// The witness data given does not match the current state of the chain. + BadWitness, + /// Collection ID is already taken. + CollectionIdInUse, + /// Items within that collection are non-transferable. + ItemsNonTransferable, + /// The provided account is not a delegate. + NotDelegate, + /// The delegate turned out to be different to what was expected. + WrongDelegate, + /// No approval exists that would allow the transfer. + Unapproved, + /// The named owner has not signed ownership acceptance of the collection. + Unaccepted, + /// The item is locked (non-transferable). + ItemLocked, + /// Item's attributes are locked. + LockedItemAttributes, + /// Collection's attributes are locked. + LockedCollectionAttributes, + /// Item's metadata is locked. + LockedItemMetadata, + /// Collection's metadata is locked. + LockedCollectionMetadata, + /// All items have been minted. + MaxSupplyReached, + /// The max supply is locked and can't be changed. + MaxSupplyLocked, + /// The provided max supply is less than the number of items a collection already has. + MaxSupplyTooSmall, + /// The given item ID is unknown. + UnknownItem, + /// Swap doesn't exist. + UnknownSwap, + /// The given item has no metadata set. + MetadataNotFound, + /// The provided attribute can't be found. + AttributeNotFound, + /// Item is not for sale. + NotForSale, + /// The provided bid is too low. + BidTooLow, + /// The item has reached its approval limit. + ReachedApprovalLimit, + /// The deadline has already expired. + DeadlineExpired, + /// The duration provided should be less than or equal to `MaxDeadlineDuration`. + WrongDuration, + /// The method is disabled by system settings. + MethodDisabled, + /// The provided setting can't be set. + WrongSetting, + /// Item's config already exists and should be equal to the provided one. + InconsistentItemConfig, + /// Config for a collection or an item can't be found. + NoConfig, + /// Some roles were not cleared. + RolesNotCleared, + /// Mint has not started yet. + MintNotStarted, + /// Mint has already ended. + MintEnded, + /// The provided Item was already used for claiming. + AlreadyClaimed, + /// The provided data is incorrect. + IncorrectData, + /// The extrinsic was sent by the wrong origin. + WrongOrigin, + /// The provided signature is incorrect. + WrongSignature, + /// The provided metadata might be too long. + IncorrectMetadata, + /// Can't set more attributes per one call. + MaxAttributesLimitReached, + /// The provided namespace isn't supported in this call. + WrongNamespace, + /// Can't delete non-empty collections. + CollectionNotEmpty, + /// The witness data should be provided. + WitnessRequired, +} + +impl TryFrom for NftsError { + type Error = crate::error::Error; + + fn try_from(status_code: u32) -> core::result::Result { + use NftsError::*; + match status_code { + 0 => Ok(NoPermission), + 1 => Ok(UnknownCollection), + 2 => Ok(AlreadyExists), + 3 => Ok(ApprovalExpired), + 4 => Ok(WrongOwner), + 5 => Ok(BadWitness), + 6 => Ok(CollectionIdInUse), + 7 => Ok(ItemsNonTransferable), + 8 => Ok(NotDelegate), + 9 => Ok(WrongDelegate), + 10 => Ok(Unapproved), + 11 => Ok(Unaccepted), + 12 => Ok(ItemLocked), + 13 => Ok(LockedItemAttributes), + 14 => Ok(LockedCollectionAttributes), + 15 => Ok(LockedItemMetadata), + 16 => Ok(LockedCollectionMetadata), + 17 => Ok(MaxSupplyReached), + 18 => Ok(MaxSupplyLocked), + 19 => Ok(MaxSupplyTooSmall), + 20 => Ok(UnknownItem), + 21 => Ok(UnknownSwap), + 22 => Ok(MetadataNotFound), + 23 => Ok(AttributeNotFound), + 24 => Ok(NotForSale), + 25 => Ok(BidTooLow), + 26 => Ok(ReachedApprovalLimit), + 27 => Ok(DeadlineExpired), + 28 => Ok(WrongDuration), + 29 => Ok(MethodDisabled), + 30 => Ok(WrongSetting), + 31 => Ok(InconsistentItemConfig), + 32 => Ok(NoConfig), + 33 => Ok(RolesNotCleared), + 34 => Ok(MintNotStarted), + 35 => Ok(MintEnded), + 36 => Ok(AlreadyClaimed), + 37 => Ok(IncorrectData), + 38 => Ok(WrongOrigin), + 39 => Ok(WrongSignature), + 40 => Ok(IncorrectMetadata), + 41 => Ok(MaxAttributesLimitReached), + 42 => Ok(WrongNamespace), + 43 => Ok(CollectionNotEmpty), + 44 => Ok(WitnessRequired), + _ => todo!(), + } + } +} // Local implementations of pallet-nfts types mod types { diff --git a/primitives/src/storage_keys.rs b/primitives/src/storage_keys.rs index 5fc7cdb3..748d0662 100644 --- a/primitives/src/storage_keys.rs +++ b/primitives/src/storage_keys.rs @@ -4,12 +4,15 @@ use super::*; #[derive(Encode, Decode, Debug, MaxEncodedLen)] pub enum RuntimeStateKeys { - #[cfg(feature = "assets")] - Assets(AssetsKeys), - #[cfg(feature = "nfts")] - Nfts(NftsKeys), #[cfg(feature = "cross-chain")] + #[codec(index = 1)] ParachainSystem(ParachainSystemKeys), + #[cfg(feature = "nfts")] + #[codec(index = 50)] + Nfts(NftsKeys), + #[cfg(feature = "assets")] + #[codec(index = 52)] + Assets(AssetsKeys), } #[cfg(feature = "cross-chain")] From 13e947e74f82430bc50865ca6a44ec234620728e Mon Sep 17 00:00:00 2001 From: Daanvdplas Date: Wed, 26 Jun 2024 17:10:42 +0200 Subject: [PATCH 014/112] refactor: optimising pop api and additional logic + test --- pop-api/Cargo.toml | 6 +- pop-api/examples/fungibles/lib.rs | 161 +++++-- pop-api/src/error.rs | 166 ++----- pop-api/src/lib.rs | 6 +- pop-api/src/primitives.rs | 1 + pop-api/src/v0/assets/fungibles.rs | 314 +++++++------ pop-api/src/v0/assets/mod.rs | 718 +++++++++++++++-------------- pop-api/src/v0/state.rs | 5 +- primitives/src/lib.rs | 2 +- primitives/src/storage_keys.rs | 7 +- 10 files changed, 710 insertions(+), 676 deletions(-) diff --git a/pop-api/Cargo.toml b/pop-api/Cargo.toml index 8454c1fa..a88d8892 100644 --- a/pop-api/Cargo.toml +++ b/pop-api/Cargo.toml @@ -5,15 +5,12 @@ license = "GPL-3.0-only" version = "0.0.0" edition = "2021" -[workspace] -exclude = [ - "integration-tests", -] [dependencies] enumflags2 = { version = "0.7.7" } ink = { version = "5.0.0", default-features = false } scale = { package = "parity-scale-codec", version = "3", default-features = false, features = ["derive"] } scale-info = { version = "2.10.0", default-features = false, features = ["derive"] } +sp-io = { version = "31.0.0", default-features = false, features = ["disable_panic_handler", "disable_oom", "disable_allocator"] } sp-runtime = { version = "32.0.0", default-features = false } pop-primitives = { path = "../primitives", features = ["devnet"], default-features = false } @@ -31,6 +28,7 @@ std = [ "pop-primitives/std", "scale/std", "scale-info/std", +"sp-io/std", "sp-runtime/std", ] assets = ["pop-primitives/assets"] diff --git a/pop-api/examples/fungibles/lib.rs b/pop-api/examples/fungibles/lib.rs index 35719ac6..bd51d760 100755 --- a/pop-api/examples/fungibles/lib.rs +++ b/pop-api/examples/fungibles/lib.rs @@ -7,12 +7,12 @@ /// use ink::prelude::vec::Vec; use pop_api::{ - assets::fungibles::{self as api, FungiblesError}, - error::{Error, StatusCode}, + assets::fungibles::{self as api}, + error::StatusCode, primitives::{AccountId as AccountId32, AssetId}, }; -pub type Result = core::result::Result; +pub type Result = core::result::Result; #[ink::contract(env = pop_api::Environment)] mod fungibles { @@ -41,12 +41,14 @@ mod fungibles { #[ink(message)] pub fn total_supply(&self, id: AssetId) -> Result { - api::total_supply(id).map_err(|e| e.into()) + // api::total_supply(id).map_err(|e| e.into()) + api::total_supply(id) } #[ink(message)] pub fn balance_of(&self, id: AssetId, owner: AccountId32) -> Result { - api::balance_of(id, owner).map_err(|e| e.into()) + // api::balance_of(id, owner).map_err(|e| e.into()) + api::balance_of(id, owner) } #[ink(message)] @@ -56,7 +58,8 @@ mod fungibles { owner: AccountId32, spender: AccountId32, ) -> Result { - api::allowance(id, owner, spender).map_err(|e| e.into()) + // api::allowance(id, owner, spender).map_err(|e| e.into()) + api::allowance(id, owner, spender) } #[ink(message)] @@ -70,15 +73,16 @@ mod fungibles { let result = api::transfer(id, to, value); ink::env::debug_println!("Result: {:?}", result); - result.map_err(|e| e.into()) + // result.map_err(|e| e.into()) + result } #[ink(message)] pub fn transfer_from( &self, id: AssetId, - from: Option, - to: Option, + from: AccountId32, + to: AccountId32, value: Balance, // In the standard a `[u8]`, but the size needs to be known at compile time. data: Vec, @@ -93,60 +97,137 @@ mod fungibles { let result = api::transfer_from(id, from, to, value, &data); ink::env::debug_println!("Result: {:?}", result); - result.map_err(|e| e.into()) + // result.map_err(|e| e.into()) + result } - /// 2. PSP-22 Metadata Interface: - /// - token_name - /// - token_symbol - /// - token_decimals + #[ink(message)] + pub fn approve(&self, id: AssetId, spender: AccountId32, value: Balance) -> Result<()> { + ink::env::debug_println!( + "PopApiFungiblesExample::approve: id: {:?}, spender {:?}, value: {:?}", + id, + spender, + value, + ); - /// 3. Asset Management: - /// - create - /// - start_destroy - /// - destroy_accounts - /// - destroy_approvals - /// - finish_destroy - /// - set_metadata - /// - clear_metadata + let result = api::approve(id, spender, value); + ink::env::debug_println!("Result: {:?}", result); + // result.map_err(|e| e.into()) + result + } #[ink(message)] - pub fn create(&self, id: AssetId, admin: AccountId32, min_balance: Balance) -> Result<()> { + pub fn increase_allowance( + &self, + id: AssetId, + spender: AccountId32, + value: Balance, + ) -> Result<()> { ink::env::debug_println!( - "PopApiFungiblesExample::create: id: {:?} admin: {:?} min_balance: {:?}", + "PopApiFungiblesExample::increase_allowance: id: {:?}, spender {:?}, value: {:?}", id, - admin, - min_balance, + spender, + value, ); - let result = api::create(id, admin, min_balance); + + let result = api::increase_allowance(id, spender, value); ink::env::debug_println!("Result: {:?}", result); - result.map_err(|e| e.into()) + // result.map_err(|e| e.into()) + result } #[ink(message)] - pub fn set_metadata( + pub fn decrease_allowance( &self, id: AssetId, - name: Vec, - symbol: Vec, - decimals: u8, + spender: AccountId32, + value: Balance, ) -> Result<()> { ink::env::debug_println!( - "PopApiFungiblesExample::set_metadata: id: {:?} name: {:?} symbol: {:?}, decimals: {:?}", + "PopApiFungiblesExample::decrease_allowance: id: {:?}, spender {:?}, value: {:?}", id, - name, - symbol, - decimals, + spender, + value, ); - let result = api::set_metadata(id, name, symbol, decimals); + + let result = api::decrease_allowance(id, spender, value); ink::env::debug_println!("Result: {:?}", result); - result.map_err(|e| e.into()) + // result.map_err(|e| e.into()) + result + } + + /// 2. PSP-22 Metadata Interface: + /// - token_name + /// - token_symbol + /// - token_decimals + + #[ink(message)] + pub fn token_name(&self, id: AssetId) -> Result> { + // api::token_name(id).map_err(|e| e.into()) + api::token_name(id) } #[ink(message)] - pub fn asset_exists(&self, id: AssetId) -> Result { - api::asset_exists(id).map_err(|e| e.into()) + pub fn token_symbol(&self, id: AssetId) -> Result> { + // api::token_symbol(id).map_err(|e| e.into()) + api::token_symbol(id) } + + #[ink(message)] + pub fn token_decimals(&self, id: AssetId) -> Result { + // api::token_decimals(id).map_err(|e| e.into()) + api::token_decimals(id) + } + + // 3. Asset Management: + // - create + // - start_destroy + // - destroy_accounts + // - destroy_approvals + // - finish_destroy + // - set_metadata + // - clear_metadata + + // #[ink(message)] + // pub fn create(&self, id: AssetId, admin: AccountId32, min_balance: Balance) -> Result<()> { + // ink::env::debug_println!( + // "PopApiFungiblesExample::create: id: {:?} admin: {:?} min_balance: {:?}", + // id, + // admin, + // min_balance, + // ); + // let result = api::create(id, admin, min_balance); + // ink::env::debug_println!("Result: {:?}", result); + // // result.map_err(|e| e.into()) + // result + // } + + // #[ink(message)] + // pub fn set_metadata( + // &self, + // id: AssetId, + // name: Vec, + // symbol: Vec, + // decimals: u8, + // ) -> Result<()> { + // ink::env::debug_println!( + // "PopApiFungiblesExample::set_metadata: id: {:?} name: {:?} symbol: {:?}, decimals: {:?}", + // id, + // name, + // symbol, + // decimals, + // ); + // let result = api::set_metadata(id, name, symbol, decimals); + // ink::env::debug_println!("Result: {:?}", result); + // // result.map_err(|e| e.into()) + // result + // } + // + // #[ink(message)] + // pub fn asset_exists(&self, id: AssetId) -> Result { + // // api::asset_exists(id).map_err(|e| e.into()) + // api::asset_exists(id) + // } } #[cfg(test)] diff --git a/pop-api/src/error.rs b/pop-api/src/error.rs index b8a56f55..54681e6d 100644 --- a/pop-api/src/error.rs +++ b/pop-api/src/error.rs @@ -14,79 +14,16 @@ impl From for StatusCode { } impl FromStatusCode for StatusCode { fn from_status_code(status_code: u32) -> Result<(), Self> { - match status_code { - 0 => Ok(()), - _ => { - let mut encoded = status_code.to_le_bytes(); - convert_unknown_errors(&mut encoded); - Err(StatusCode::from(u32::from_le_bytes(encoded))) - }, + if status_code == 0 { + return Ok(()); } + Err(StatusCode(status_code)) } } impl From for StatusCode { fn from(_: scale::Error) -> Self { - DecodingFailed.into() - } -} - -// If an unknown variant of the `DispatchError` is detected the error needs to be converted -// into the encoded value of `Error::Other`. This conversion is performed by shifting the bytes one -// position forward (discarding the last byte as it is not used) and setting the first byte to the -// encoded value of `Other` (0u8). This ensures the error is correctly categorized as an `Other` -// variant which provides all the necessary information to debug which error occurred in the runtime. -// -// Byte layout explanation: -// - Byte 0: index of the variant within `Error` -// - Byte 1: -// - Must be zero for `UNIT_ERRORS`. -// - Represents the nested error in `SINGLE_NESTED_ERRORS`. -// - Represents the first level of nesting in `DOUBLE_NESTED_ERRORS`. -// - Byte 2: -// - Represents the second level of nesting in `DOUBLE_NESTED_ERRORS`. -// - Byte 3: -// - Unused or represents further nested information. -// -// This mechanism ensures backward compatibility by correctly categorizing any unknown errors -// into the `Other` variant, thus preventing issues caused by breaking changes. -fn convert_unknown_errors(encoded_error: &mut [u8; 4]) { - let all_errors = [ - UNIT_ERRORS.as_slice(), - SINGLE_NESTED_ERRORS.as_slice(), - DOUBLE_NESTED_ERRORS.as_slice(), - // `DecodingFailed`. - &[255u8], - ] - .concat(); - // Unknown errors, i.e. an encoded value where the first byte is non-zero (indicating a variant - // in `Error`) but unknown. - if !all_errors.contains(&encoded_error[0]) { - encoded_error[..].rotate_right(1); - encoded_error[0] = 0u8; - } - convert_unknown_nested_errors(encoded_error); -} - -// If an unknown nested variant of the `DispatchError` is detected (i.e. when any of the subsequent -// bytes are non-zero). -fn convert_unknown_nested_errors(encoded_error: &mut [u8; 4]) { - // Converts single nested errors that are known to the Pop API as unit errors into `Other`. - if UNIT_ERRORS.contains(&encoded_error[0]) && encoded_error[1..].iter().any(|x| *x != 0u8) { - encoded_error[..].rotate_right(1); - encoded_error[0] = 0u8; - // Converts double nested errors that are known to the Pop API as single nested errors into - // `Other`. - } else if SINGLE_NESTED_ERRORS.contains(&encoded_error[0]) - && encoded_error[2..].iter().any(|x| *x != 0u8) - { - encoded_error[..].rotate_right(1); - encoded_error[0] = 0u8; - } else if DOUBLE_NESTED_ERRORS.contains(&encoded_error[0]) - && encoded_error[3..].iter().any(|x| *x != 0u8) - { - encoded_error[..].rotate_right(1); - encoded_error[0] = 0u8; + StatusCode(255u32) } } @@ -136,32 +73,7 @@ pub enum Error { DecodingFailed = 255, } -// Unit `Error` variants. -// (variant: index): -// - CannotLookup: 1, -// - BadOrigin: 2, -// - ConsumerRemaining: 4, -// - NoProviders: 5, -// - TooManyConsumers: 6, -// - Exhausted: 10, -// - Corruption: 11, -// - Unavailable: 12, -// - RootNotAllowed: 13, -// - DecodingFailed: 255, -const UNIT_ERRORS: [u8; 10] = [1, 2, 4, 5, 6, 10, 11, 12, 13, 255]; - -// Single nested `Error` variants. -// (variant: index): -// - Token: 7, -// - Arithmetic: 8, -// - Transaction: 9, -const SINGLE_NESTED_ERRORS: [u8; 3] = [7, 8, 9]; - -// Double nested `Error` variants -// (variant: index): -// - Module: 3, -const DOUBLE_NESTED_ERRORS: [u8; 1] = [3]; - +#[cfg(test)] impl From for StatusCode { fn from(value: Error) -> Self { let mut encoded_error = value.encode(); @@ -175,8 +87,15 @@ impl From for StatusCode { impl From for Error { fn from(value: StatusCode) -> Self { - let encoded: [u8; 4] = value.0.to_le_bytes(); - Error::decode(&mut &encoded[..]).unwrap_or(DecodingFailed) + let mut encoded: [u8; 4] = value.0.to_le_bytes(); + match Error::decode(&mut &encoded[..]) { + Err(_) => { + encoded[..].rotate_right(1); + encoded[0] = 0u8; + Error::decode(&mut &encoded[..]).unwrap_or(DecodingFailed) + }, + Ok(error) => error, + } } } @@ -286,28 +205,19 @@ mod tests { into_status_code([error_code, 1, 0, 0]), (Other { dispatch_error_index: error_code, error_index: 1, error: 0 }).into(), ); - assert_eq!( - into_error([error_code, 1, 0, 0]), - Other { dispatch_error_index: error_code, error_index: 1, error: 0 }, - ); + assert_eq!(into_error([error_code, 1, 0, 0]), errors[i]); // Unexpected third byte nested. assert_eq!( into_status_code([error_code, 1, 1, 0]), (Other { dispatch_error_index: error_code, error_index: 1, error: 1 }).into(), ); - assert_eq!( - into_error([error_code, 1, 1, 0]), - Other { dispatch_error_index: error_code, error_index: 1, error: 1 }, - ); + assert_eq!(into_error([error_code, 1, 1, 0]), errors[i]); // Unexpected fourth byte nested. assert_eq!( into_status_code([error_code, 1, 1, 1]), (Other { dispatch_error_index: error_code, error_index: 1, error: 1 }).into(), ); - assert_eq!( - into_error([error_code, 1, 1, 1]), - Other { dispatch_error_index: error_code, error_index: 1, error: 1 }, - ); + assert_eq!(into_error([error_code, 1, 1, 1]), errors[i]); } } @@ -341,19 +251,13 @@ mod tests { into_status_code([error_code, 1, 1, 0]), (Other { dispatch_error_index: error_code, error_index: 1, error: 1 }).into(), ); - assert_eq!( - into_error([error_code, 1, 1, 0]), - Other { dispatch_error_index: error_code, error_index: 1, error: 1 }, - ); + assert_eq!(into_error([error_code, 1, 1, 0]), errors[i][1]); // Unexpected fourth byte nested. assert_eq!( into_status_code([error_code, 1, 1, 1]), (Other { dispatch_error_index: error_code, error_index: 1, error: 1 }).into(), ); - assert_eq!( - into_error([error_code, 1, 1, 1]), - Other { dispatch_error_index: error_code, error_index: 1, error: 1 }, - ); + assert_eq!(into_error([error_code, 1, 1, 1]), errors[i][1]); } } @@ -385,9 +289,37 @@ mod tests { into_status_code([3, 1, 1, 1]), (Other { dispatch_error_index: 3, error_index: 1, error: 1 }).into(), ); + assert_eq!(into_error([3, 1, 1, 1]), Module { index: 1, error: 1 }); + } + + #[test] + fn single_nested_unknown_variants() { + // Unknown `TokenError` variant. + assert_eq!( + into_error([7, 10, 0, 0]), + Other { dispatch_error_index: 7, error_index: 10, error: 0 } + ); + assert_eq!( + into_status_code([7, 10, 0, 0]), + Other { dispatch_error_index: 7, error_index: 10, error: 0 }.into() + ); + // Unknown `Arithmetic` variant. + assert_eq!( + into_error([8, 3, 0, 0]), + Other { dispatch_error_index: 8, error_index: 3, error: 0 } + ); + assert_eq!( + into_status_code([8, 3, 0, 0]), + Other { dispatch_error_index: 8, error_index: 3, error: 0 }.into() + ); + // Unknown `Transactional` variant. + assert_eq!( + into_error([9, 2, 0, 0]), + Other { dispatch_error_index: 9, error_index: 2, error: 0 } + ); assert_eq!( - into_error([3, 1, 1, 1]), - Other { dispatch_error_index: 3, error_index: 1, error: 1 }, + into_status_code([9, 2, 0, 0]), + Other { dispatch_error_index: 9, error_index: 2, error: 0 }.into() ); } diff --git a/pop-api/src/lib.rs b/pop-api/src/lib.rs index 04d08bce..53bbadc6 100644 --- a/pop-api/src/lib.rs +++ b/pop-api/src/lib.rs @@ -1,9 +1,9 @@ #![cfg_attr(not(feature = "std"), no_std, no_main)] use ink::{prelude::vec::Vec, ChainExtensionInstance}; -pub use sp_runtime::{MultiAddress, MultiSignature}; +pub use sp_runtime::MultiAddress; -use crate::error::{Error, StatusCode}; +use crate::error::StatusCode; use primitives::{storage_keys::*, AccountId as AccountId32}; #[cfg(feature = "assets")] pub use v0::assets; @@ -62,12 +62,14 @@ pub trait PopApi { fn send_xcm(xcm: primitives::cross_chain::CrossChainMessage) -> Result<()>; } +#[inline] fn dispatch(call: RuntimeCall) -> Result<()> { <::ChainExtension as ChainExtensionInstance>::instantiate( ) .dispatch(call) } +#[inline] fn read_state(key: RuntimeStateKeys) -> Result> { <::ChainExtension as ChainExtensionInstance>::instantiate( ) diff --git a/pop-api/src/primitives.rs b/pop-api/src/primitives.rs index e174a111..17419d5b 100644 --- a/pop-api/src/primitives.rs +++ b/pop-api/src/primitives.rs @@ -1 +1,2 @@ pub use pop_primitives::*; +pub use sp_runtime::MultiAddress; diff --git a/pop-api/src/v0/assets/fungibles.rs b/pop-api/src/v0/assets/fungibles.rs index eaf1c6f5..e7c3f41c 100644 --- a/pop-api/src/v0/assets/fungibles.rs +++ b/pop-api/src/v0/assets/fungibles.rs @@ -1,7 +1,12 @@ -use crate::{assets, primitives::AssetId, AccountId, Balance, MultiAddress, StatusCode}; use ink::prelude::vec::Vec; use scale::Encode; +use crate::{ + assets, + primitives::{AssetId, MultiAddress}, + AccountId, Balance, StatusCode, +}; + type Result = core::result::Result; /// Local Fungibles: @@ -26,6 +31,7 @@ type Result = core::result::Result; /// /// # Returns /// The total supply of the token, or an error if the operation fails. +#[inline] pub fn total_supply(id: AssetId) -> Result { assets::total_supply(id) } @@ -39,6 +45,7 @@ pub fn total_supply(id: AssetId) -> Result { /// /// # Returns /// The balance of the specified account, or an error if the operation fails. +#[inline] pub fn balance_of(id: AssetId, owner: AccountId) -> Result { assets::balance_of(id, owner) } @@ -53,6 +60,7 @@ pub fn balance_of(id: AssetId, owner: AccountId) -> Result { /// /// # Returns /// The remaining allowance, or an error if the operation fails. +#[inline] pub fn allowance(id: AssetId, owner: AccountId, spender: AccountId) -> Result { assets::allowance(id, owner, spender) } @@ -67,6 +75,7 @@ pub fn allowance(id: AssetId, owner: AccountId, spender: AccountId) -> Result>, @@ -87,19 +96,15 @@ pub fn transfer( /// /// # Returns /// Returns `Ok(())` if successful, or an error if the transfer fails. +#[inline] pub fn transfer_from( id: AssetId, - from: Option>>, - to: Option>>, + from: impl Into>, + to: impl Into>, value: Balance, _data: &[u8], ) -> Result<()> { - match (from, to) { - (None, Some(to)) => assets::mint(id, to, value), - (Some(from), None) => assets::burn(id, from, value), - (Some(from), Some(to)) => assets::transfer_approved(id, from, to, value), - _ => Ok(()), - } + assets::transfer_approved(id, from, to, value) } /// Approves an account to spend a specified number of tokens on behalf of the caller. @@ -111,16 +116,10 @@ pub fn transfer_from( /// /// # Returns /// Returns `Ok(())` if successful, or an error if the approval fails. -// #[allow(unused_variables)] -// fn approve(id: AssetId, spender: AccountId, value: Balance) -> Result<()> { -// todo!() -// // TODO: read allowance and increase or decrease. -// // Ok(dispatch(RuntimeCall::Assets(AssetsCall::ApproveTransfer { -// // id: id.into(), -// // delegate: spender.into(), -// // amount: Compact(value), -// // }))?) -// } +#[inline] +pub fn approve(id: AssetId, spender: AccountId, value: Balance) -> Result<()> { + assets::approve_transfer(id, spender, value) +} /// Increases the allowance of a spender. /// @@ -131,13 +130,10 @@ pub fn transfer_from( /// /// # Returns /// Returns `Ok(())` if successful, or an error if the operation fails. -// fn increase_allowance(id: AssetId, spender: AccountId, value: Balance) -> Result<()> { -// Ok(dispatch(RuntimeCall::Assets(AssetsCall::ApproveTransfer { -// id: id.into(), -// delegate: spender.into(), -// amount: Compact(value), -// }))?) -// } +#[inline] +pub fn increase_allowance(id: AssetId, spender: AccountId, value: Balance) -> Result<()> { + assets::approve_transfer(id, spender, value) +} /// Decreases the allowance of a spender. /// @@ -148,20 +144,11 @@ pub fn transfer_from( /// /// # Returns /// Returns `Ok(())` if successful, or an error if the operation fails. -// #[allow(unused_variables)] -// fn decrease_allowance(id: AssetId, spender: AccountId, value: Balance) -> Result<()> { -// todo!() -// // TODO: cancel_approval + approve_transfer -// // Ok(dispatch(RuntimeCall::Assets(AssetsCall::CancelApproval { -// // id: id.into(), -// // delegate: delegate.into(), -// // }))?) -// // Ok(dispatch(RuntimeCall::Assets(AssetsCall::ApproveTransfer { -// // id: id.into(), -// // delegate: spender.into(), -// // amount: Compact(value), -// // }))?) -// } +#[inline] +pub fn decrease_allowance(id: AssetId, spender: AccountId, value: Balance) -> Result<()> { + assets::cancel_approval(id, spender.clone())?; + assets::approve_transfer(id, spender, value) +} /// 2. PSP-22 Metadata Interface: /// - token_name @@ -175,11 +162,10 @@ pub fn transfer_from( /// /// # Returns /// The name of the token as a byte vector, or an error if the operation fails. -// #[allow(unused_variables)] -// pub fn token_name(id: AssetId) -> Result>> { -// todo!() -// // Ok(state::read(RuntimeStateKeys::Assets(AssetsKeys::TokenName(id)))?) -// } +#[inline] +pub fn token_name(id: AssetId) -> Result> { + assets::token_name(id) +} /// Returns the token symbol for a given asset ID. /// @@ -188,10 +174,10 @@ pub fn transfer_from( /// /// # Returns /// The symbol of the token as a byte vector, or an error if the operation fails. -// #[allow(unused_variables)] -// fn token_symbol(id: AssetId) -> Result>> { -// todo!() -// } +#[inline] +pub fn token_symbol(id: AssetId) -> Result> { + assets::token_symbol(id) +} /// Returns the token decimals for a given asset ID. /// @@ -200,118 +186,114 @@ pub fn transfer_from( /// /// # Returns /// The number of decimals of the token as a byte vector, or an error if the operation fails. -// #[allow(unused_variables)] -// fn token_decimals(id: AssetId) -> Result>> { -// todo!() -// } - -/// 3. Asset Management: -/// - create -/// - start_destroy -/// - destroy_accounts -/// - destroy_approvals -/// - finish_destroy -/// - set_metadata -/// - clear_metadata - -/// Create a new token with a given asset ID. -/// -/// # Arguments -/// * `id` - The ID of the asset. -/// * `admin` - The account that will administer the asset. -/// * `min_balance` - The minimum balance required for accounts holding this asset. -/// -/// # Returns -/// Returns `Ok(())` if successful, or an error if the creation fails. -pub fn create( - id: AssetId, - admin: impl Into>, - min_balance: Balance, -) -> Result<()> { - assets::create(id, admin, min_balance) +#[inline] +pub fn token_decimals(id: AssetId) -> Result { + assets::token_decimals(id) } -/// Start the process of destroying a token with a given asset ID. -/// -/// # Arguments -/// * `id` - The ID of the asset. -/// -/// # Returns -/// Returns `Ok(())` if successful, or an error if the operation fails. -// fn start_destroy(id: AssetId) -> Result<()> { -// Ok(dispatch(RuntimeCall::Assets(AssetsCall::StartDestroy { -// id: id.into(), -// }))?) +// /// 3. Asset Management: +// /// - create +// /// - start_destroy +// /// - destroy_accounts +// /// - destroy_approvals +// /// - finish_destroy +// /// - set_metadata +// /// - clear_metadata +// +// /// Create a new token with a given asset ID. +// /// +// /// # Arguments +// /// * `id` - The ID of the asset. +// /// * `admin` - The account that will administer the asset. +// /// * `min_balance` - The minimum balance required for accounts holding this asset. +// /// +// /// # Returns +// /// Returns `Ok(())` if successful, or an error if the creation fails. +// // pub fn create(id: AssetId, admin: impl Into>, min_balance: Balance) -> Result<()> { +// // assets::create(id, admin, min_balance) +// // } +// +// /// Start the process of destroying a token with a given asset ID. +// /// +// /// # Arguments +// /// * `id` - The ID of the asset. +// /// +// /// # Returns +// /// Returns `Ok(())` if successful, or an error if the operation fails. +// // fn start_destroy(id: AssetId) -> Result<()> { +// // Ok(dispatch(RuntimeCall::Assets(AssetsCall::StartDestroy { +// // id: id.into(), +// // }))?) +// // } +// +// /// Destroy all accounts associated with a token with a given asset ID. +// /// +// /// # Arguments +// /// * `id` - The ID of the asset. +// /// +// /// # Returns +// /// Returns `Ok(())` if successful, or an error if the operation fails. +// // fn destroy_accounts(id: AssetId) -> Result<()> { +// // Ok(dispatch(RuntimeCall::Assets(AssetsCall::DestroyAccounts { +// // id: id.into(), +// // }))?) +// // } +// +// /// Destroy all approvals associated with a token with a given asset ID. +// /// +// /// # Arguments +// /// * `id` - The ID of the asset. +// /// +// /// # Returns +// /// Returns `Ok(())` if successful, or an error if the operation fails. +// // fn destroy_approvals(id: AssetId) -> Result<()> { +// // Ok(dispatch(RuntimeCall::Assets(AssetsCall::DestroyApprovals { +// // id: id.into(), +// // }))?) +// // } +// +// /// Complete the process of destroying a token with a given asset ID. +// /// +// /// # Arguments +// /// * `id` - The ID of the asset. +// /// +// /// # Returns +// /// Returns `Ok(())` if successful, or an error if the operation fails. +// // fn finish_destroy(id: AssetId) -> Result<()> { +// // Ok(dispatch(RuntimeCall::Assets(AssetsCall::FinishDestroy { +// // id: id.into(), +// // }))?) +// // } +// +// /// Set the metadata for a token with a given asset ID. +// /// +// /// # Arguments +// /// * `id` - The ID of the asset. +// /// +// /// # Returns +// /// Returns `Ok(())` if successful, or an error if the operation fails. +// // pub fn set_metadata(id: AssetId, name: Vec, symbol: Vec, decimals: u8) -> Result<()> { +// // assets::set_metadata(id, name, symbol, decimals) +// // } +// +// /// Clear the metadata for a token with a given asset ID. +// /// +// /// # Arguments +// /// * `id` - The ID of the asset. +// /// +// /// # Returns +// /// Returns `Ok(())` if successful, or an error if the operation fails. +// // fn clear_metadata(id: AssetId) -> Result<()> { +// // Ok(dispatch(RuntimeCall::Assets(AssetsCall::ClearMetadata { +// // id: id.into(), +// // }))?) +// // } +// +// pub fn asset_exists(id: AssetId) -> Result { +// assets::asset_exists(id) // } -/// Destroy all accounts associated with a token with a given asset ID. -/// -/// # Arguments -/// * `id` - The ID of the asset. -/// -/// # Returns -/// Returns `Ok(())` if successful, or an error if the operation fails. -// fn destroy_accounts(id: AssetId) -> Result<()> { -// Ok(dispatch(RuntimeCall::Assets(AssetsCall::DestroyAccounts { -// id: id.into(), -// }))?) -// } - -/// Destroy all approvals associated with a token with a given asset ID. -/// -/// # Arguments -/// * `id` - The ID of the asset. -/// -/// # Returns -/// Returns `Ok(())` if successful, or an error if the operation fails. -// fn destroy_approvals(id: AssetId) -> Result<()> { -// Ok(dispatch(RuntimeCall::Assets(AssetsCall::DestroyApprovals { -// id: id.into(), -// }))?) -// } - -/// Complete the process of destroying a token with a given asset ID. -/// -/// # Arguments -/// * `id` - The ID of the asset. -/// -/// # Returns -/// Returns `Ok(())` if successful, or an error if the operation fails. -// fn finish_destroy(id: AssetId) -> Result<()> { -// Ok(dispatch(RuntimeCall::Assets(AssetsCall::FinishDestroy { -// id: id.into(), -// }))?) -// } - -/// Set the metadata for a token with a given asset ID. -/// -/// # Arguments -/// * `id` - The ID of the asset. -/// -/// # Returns -/// Returns `Ok(())` if successful, or an error if the operation fails. -pub fn set_metadata(id: AssetId, name: Vec, symbol: Vec, decimals: u8) -> Result<()> { - assets::set_metadata(id, name, symbol, decimals) -} - -/// Clear the metadata for a token with a given asset ID. -/// -/// # Arguments -/// * `id` - The ID of the asset. -/// -/// # Returns -/// Returns `Ok(())` if successful, or an error if the operation fails. -// fn clear_metadata(id: AssetId) -> Result<()> { -// Ok(dispatch(RuntimeCall::Assets(AssetsCall::ClearMetadata { -// id: id.into(), -// }))?) -// } - -pub fn asset_exists(id: AssetId) -> Result { - assets::asset_exists(id) -} - -#[derive(Debug, Copy, Clone, PartialEq, Eq, Encode, scale::Decode)] +#[derive(Encode)] #[cfg_attr(feature = "std", derive(scale_info::TypeInfo))] pub enum FungiblesError { Other(StatusCode), @@ -359,11 +341,13 @@ impl From for FungiblesError { #[cfg(test)] mod tests { + use scale::Decode; + use super::FungiblesError; - use crate::error::{ + use crate::StatusCode; + use pop_primitives::{ ArithmeticError::*, Error::{self, *}, - StatusCode, TokenError::*, TransactionalError::*, }; @@ -373,6 +357,18 @@ mod tests { status_code.into() } + #[test] + fn status_code_vs_encoded() { + assert_eq!(u32::decode(&mut &[3u8, 10, 2, 0][..]).unwrap(), 133635u32); + assert_eq!(u32::decode(&mut &[3u8, 52, 0, 0][..]).unwrap(), 13315u32); + assert_eq!(u32::decode(&mut &[3u8, 52, 1, 0][..]).unwrap(), 78851u32); + assert_eq!(u32::decode(&mut &[3u8, 52, 2, 0][..]).unwrap(), 144387u32); + assert_eq!(u32::decode(&mut &[3u8, 52, 3, 0][..]).unwrap(), 209923u32); + assert_eq!(u32::decode(&mut &[3u8, 52, 5, 0][..]).unwrap(), 340995u32); + assert_eq!(u32::decode(&mut &[3u8, 52, 7, 0][..]).unwrap(), 472067u32); + assert_eq!(u32::decode(&mut &[3u8, 52, 10, 0][..]).unwrap(), 668675u32); + } + #[test] fn conversion_status_code_into_fungibles_error_works() { let errors = vec![ diff --git a/pop-api/src/v0/assets/mod.rs b/pop-api/src/v0/assets/mod.rs index 778387cb..22e32d47 100644 --- a/pop-api/src/v0/assets/mod.rs +++ b/pop-api/src/v0/assets/mod.rs @@ -1,10 +1,9 @@ -#![allow(dead_code)] - -use crate::{Balance, MultiAddress, RuntimeCall, *}; use ink::prelude::vec::Vec; -use primitives::AssetId; use scale::{Compact, Encode}; +use crate::{state::read, Balance, RuntimeCall, *}; +use primitives::{AssetId, MultiAddress}; + pub mod fungibles; type Result = core::result::Result; @@ -44,65 +43,62 @@ type Result = core::result::Result; /// - block /// Issue a new class of fungible assets from a public origin. -pub(crate) fn create( - id: AssetId, - admin: impl Into>, - min_balance: Balance, -) -> Result<()> { - dispatch(RuntimeCall::Assets(AssetsCall::Create { - id: id.into(), - admin: admin.into(), - min_balance, - })) -} - -/// Start the process of destroying a fungible asset class. -pub(crate) fn start_destroy(id: AssetId) -> Result<()> { - dispatch(RuntimeCall::Assets(AssetsCall::StartDestroy { id: id.into() })) -} - -/// Destroy all accounts associated with a given asset. -pub(crate) fn destroy_accounts(id: AssetId) -> Result<()> { - dispatch(RuntimeCall::Assets(AssetsCall::DestroyAccounts { id: id.into() })) -} - -/// Destroy all approvals associated with a given asset up to the max (see runtime configuration Assets `RemoveItemsLimit`). -pub(crate) fn destroy_approvals(id: AssetId) -> Result<()> { - dispatch(RuntimeCall::Assets(AssetsCall::DestroyApprovals { id: id.into() })) -} - -/// Complete destroying asset and unreserve currency. -pub(crate) fn finish_destroy(id: AssetId) -> Result<()> { - dispatch(RuntimeCall::Assets(AssetsCall::FinishDestroy { id: id.into() })) -} - -/// Mint assets of a particular class. -pub(crate) fn mint( - id: AssetId, - beneficiary: impl Into>, - amount: Balance, -) -> Result<()> { - dispatch(RuntimeCall::Assets(AssetsCall::Mint { - id: id.into(), - beneficiary: beneficiary.into(), - amount: Compact(amount), - })) -} - -/// Reduce the balance of `who` by as much as possible up to `amount` assets of `id`. -pub(crate) fn burn( - id: AssetId, - who: impl Into>, - amount: Balance, -) -> Result<()> { - dispatch(RuntimeCall::Assets(AssetsCall::Burn { - id: id.into(), - who: who.into(), - amount: Compact(amount), - })) -} - -/// Move some assets from the sender account to another. +// pub(crate) fn create( +// id: AssetId, +// admin: impl Into>, +// min_balance: Balance, +// ) -> Result<()> { +// dispatch(RuntimeCall::Assets(AssetsCall::Create { +// id: id.into(), +// admin: admin.into(), +// min_balance, +// })) +// } +// +// /// Start the process of destroying a fungible asset class. +// pub(crate) fn start_destroy(id: AssetId) -> Result<()> { +// dispatch(RuntimeCall::Assets(AssetsCall::StartDestroy { id: id.into() })) +// } +// +// /// Destroy all accounts associated with a given asset. +// pub(crate) fn destroy_accounts(id: AssetId) -> Result<()> { +// dispatch(RuntimeCall::Assets(AssetsCall::DestroyAccounts { id: id.into() })) +// } +// +// /// Destroy all approvals associated with a given asset up to the max (see runtime configuration Assets `RemoveItemsLimit`). +// pub(crate) fn destroy_approvals(id: AssetId) -> Result<()> { +// dispatch(RuntimeCall::Assets(AssetsCall::DestroyApprovals { id: id.into() })) +// } +// +// /// Complete destroying asset and unreserve currency. +// pub(crate) fn finish_destroy(id: AssetId) -> Result<()> { +// dispatch(RuntimeCall::Assets(AssetsCall::FinishDestroy { id: id.into() })) +// } + +// /// Mint assets of a particular class. +// pub(crate) fn mint( +// id: AssetId, +// beneficiary: impl Into>, +// amount: Balance, +// ) -> Result<()> { +// dispatch(RuntimeCall::Assets(AssetsCall::Mint { +// id: id.into(), +// beneficiary: beneficiary.into(), +// amount: Compact(amount), +// })) +// } +// +// /// Reduce the balance of `who` by as much as possible up to `amount` assets of `id`. +// pub(crate) fn burn(id: AssetId, who: impl Into>, amount: Balance) -> Result<()> { +// dispatch(RuntimeCall::Assets(AssetsCall::Burn { +// id: id.into(), +// who: who.into(), +// amount: Compact(amount), +// })) +// } + +// /// Move some assets from the sender account to another. +#[inline] pub(crate) fn transfer( id: AssetId, target: impl Into>, @@ -115,98 +111,96 @@ pub(crate) fn transfer( })) } -/// Move some assets from the sender account to another, keeping the sender account alive. -pub(crate) fn transfer_keep_alive( - id: AssetId, - target: impl Into>, - amount: Balance, -) -> Result<()> { - dispatch(RuntimeCall::Assets(AssetsCall::TransferKeepAlive { - id: id.into(), - target: target.into(), - amount: Compact(amount), - })) -} - -/// Move some assets from one account to another. Sender should be the Admin of the asset `id`. -pub(crate) fn force_transfer( - id: AssetId, - source: impl Into>, - dest: impl Into>, - amount: Balance, -) -> Result<()> { - dispatch(RuntimeCall::Assets(AssetsCall::ForceTransfer { - id: id.into(), - source: source.into(), - dest: dest.into(), - amount: Compact(amount), - })) -} - -/// Disallow further unprivileged transfers of an asset `id` from an account `who`. `who` -/// must already exist as an entry in `Account`s of the asset. If you want to freeze an -/// account that does not have an entry, use `touch_other` first. -pub(crate) fn freeze(id: AssetId, who: impl Into>) -> Result<()> { - dispatch(RuntimeCall::Assets(AssetsCall::Freeze { id: id.into(), who: who.into() })) -} - -/// Allow unprivileged transfers to and from an account again. -pub(crate) fn thaw(id: AssetId, who: impl Into>) -> Result<()> { - dispatch(RuntimeCall::Assets(AssetsCall::Thaw { id: id.into(), who: who.into() })) -} - -/// Disallow further unprivileged transfers for the asset class. -pub(crate) fn freeze_asset(id: AssetId) -> Result<()> { - dispatch(RuntimeCall::Assets(AssetsCall::FreezeAsset { id: id.into() })) -} - -/// Allow unprivileged transfers for the asset again. -pub(crate) fn thaw_asset(id: AssetId) -> Result<()> { - dispatch(RuntimeCall::Assets(AssetsCall::ThawAsset { id: id.into() })) -} - -/// Change the Owner of an asset. -pub(crate) fn transfer_ownership( - id: AssetId, - owner: impl Into>, -) -> Result<()> { - dispatch(RuntimeCall::Assets(AssetsCall::TransferOwnership { - id: id.into(), - owner: owner.into(), - })) -} - -/// Change the Issuer, Admin and Freezer of an asset. -pub(crate) fn set_team( - id: AssetId, - issuer: impl Into>, - admin: impl Into>, - freezer: impl Into>, -) -> Result<()> { - dispatch(RuntimeCall::Assets(AssetsCall::SetTeam { - id: id.into(), - issuer: issuer.into(), - admin: admin.into(), - freezer: freezer.into(), - })) -} +// /// Move some assets from the sender account to another, keeping the sender account alive. +// pub(crate) fn transfer_keep_alive( +// id: AssetId, +// target: impl Into>, +// amount: Balance, +// ) -> Result<()> { +// dispatch(RuntimeCall::Assets(AssetsCall::TransferKeepAlive { +// id: id.into(), +// target: target.into(), +// amount: Compact(amount), +// })) +// } +// +// /// Move some assets from one account to another. Sender should be the Admin of the asset `id`. +// pub(crate) fn force_transfer( +// id: AssetId, +// source: impl Into>, +// dest: impl Into>, +// amount: Balance, +// ) -> Result<()> { +// dispatch(RuntimeCall::Assets(AssetsCall::ForceTransfer { +// id: id.into(), +// source: source.into(), +// dest: dest.into(), +// amount: Compact(amount), +// })) +// } +// +// /// Disallow further unprivileged transfers of an asset `id` from an account `who`. `who` +// /// must already exist as an entry in `Account`s of the asset. If you want to freeze an +// /// account that does not have an entry, use `touch_other` first. +// pub(crate) fn freeze(id: AssetId, who: impl Into>) -> Result<()> { +// dispatch(RuntimeCall::Assets(AssetsCall::Freeze { id: id.into(), who: who.into() })) +// } +// +// /// Allow unprivileged transfers to and from an account again. +// pub(crate) fn thaw(id: AssetId, who: impl Into>) -> Result<()> { +// dispatch(RuntimeCall::Assets(AssetsCall::Thaw { id: id.into(), who: who.into() })) +// } +// +// /// Disallow further unprivileged transfers for the asset class. +// pub(crate) fn freeze_asset(id: AssetId) -> Result<()> { +// dispatch(RuntimeCall::Assets(AssetsCall::FreezeAsset { id: id.into() })) +// } +// +// /// Allow unprivileged transfers for the asset again. +// pub(crate) fn thaw_asset(id: AssetId) -> Result<()> { +// dispatch(RuntimeCall::Assets(AssetsCall::ThawAsset { id: id.into() })) +// } +// +// /// Change the Owner of an asset. +// pub(crate) fn transfer_ownership(id: AssetId, owner: impl Into>) -> Result<()> { +// dispatch(RuntimeCall::Assets(AssetsCall::TransferOwnership { +// id: id.into(), +// owner: owner.into(), +// })) +// } +// +// /// Change the Issuer, Admin and Freezer of an asset. +// pub(crate) fn set_team( +// id: AssetId, +// issuer: impl Into>, +// admin: impl Into>, +// freezer: impl Into>, +// ) -> Result<()> { +// dispatch(RuntimeCall::Assets(AssetsCall::SetTeam { +// id: id.into(), +// issuer: issuer.into(), +// admin: admin.into(), +// freezer: freezer.into(), +// })) +// } /// Set the metadata for an asset. -pub(crate) fn set_metadata( - id: AssetId, - name: Vec, - symbol: Vec, - decimals: u8, -) -> Result<()> { - dispatch(RuntimeCall::Assets(AssetsCall::SetMetadata { id: id.into(), name, symbol, decimals })) -} - -/// Clear the metadata for an asset. -pub(crate) fn clear_metadata(id: AssetId) -> Result<()> { - dispatch(RuntimeCall::Assets(AssetsCall::ClearMetadata { id: id.into() })) -} - -/// Approve an amount of asset for transfer by a delegated third-party account. +// pub(crate) fn set_metadata( +// id: AssetId, +// name: Vec, +// symbol: Vec, +// decimals: u8, +// ) -> Result<()> { +// dispatch(RuntimeCall::Assets(AssetsCall::SetMetadata { id: id.into(), name, symbol, decimals })) +// } + +// /// Clear the metadata for an asset. +// pub(crate) fn clear_metadata(id: AssetId) -> Result<()> { +// dispatch(RuntimeCall::Assets(AssetsCall::ClearMetadata { id: id.into() })) +// } + +// /// Approve an amount of asset for transfer by a delegated third-party account. +#[inline] pub(crate) fn approve_transfer( id: AssetId, delegate: impl Into>, @@ -220,6 +214,7 @@ pub(crate) fn approve_transfer( } /// Cancel all of some asset approved for delegated transfer by a third-party account. +#[inline] pub(crate) fn cancel_approval( id: AssetId, delegate: impl Into>, @@ -230,21 +225,22 @@ pub(crate) fn cancel_approval( })) } -/// Cancel all of some asset approved for delegated transfer by a third-party account. -pub(crate) fn force_cancel_approval( - id: AssetId, - owner: impl Into>, - delegate: impl Into>, -) -> Result<()> { - dispatch(RuntimeCall::Assets(AssetsCall::ForceCancelApproval { - id: id.into(), - owner: owner.into(), - delegate: delegate.into(), - })) -} +// /// Cancel all of some asset approved for delegated transfer by a third-party account. +// pub(crate) fn force_cancel_approval( +// id: AssetId, +// owner: impl Into>, +// delegate: impl Into>, +// ) -> Result<()> { +// dispatch(RuntimeCall::Assets(AssetsCall::ForceCancelApproval { +// id: id.into(), +// owner: owner.into(), +// delegate: delegate.into(), +// })) +// } /// Transfer some asset balance from a previously delegated account to some third-party /// account. +#[inline] pub(crate) fn transfer_approved( id: AssetId, owner: impl Into>, @@ -258,58 +254,81 @@ pub(crate) fn transfer_approved( amount: Compact(amount), })) } - -/// Create an asset account for non-provider assets. -pub(crate) fn touch(id: AssetId) -> Result<()> { - dispatch(RuntimeCall::Assets(AssetsCall::Touch { id: id.into() })) -} - -/// Return the deposit (if any) of an asset account or a consumer reference (if any) of an -/// account. -pub(crate) fn refund(id: AssetId, allow_burn: bool) -> Result<()> { - dispatch(RuntimeCall::Assets(AssetsCall::Refund { id: id.into(), allow_burn })) -} - -/// Sets the minimum balance of an asset. -pub(crate) fn set_min_balance(id: AssetId, min_balance: Balance) -> Result<()> { - dispatch(RuntimeCall::Assets(AssetsCall::SetMinBalance { - id: id.into(), - min_balance: Compact(min_balance), - })) -} - -/// Create an asset account for `who`. -pub(crate) fn touch_other(id: AssetId, who: impl Into>) -> Result<()> { - dispatch(RuntimeCall::Assets(AssetsCall::TouchOther { id: id.into(), who: who.into() })) -} - -/// Return the deposit (if any) of a target asset account. Useful if you are the depositor. -pub(crate) fn refund_other(id: AssetId, who: impl Into>) -> Result<()> { - dispatch(RuntimeCall::Assets(AssetsCall::RefundOther { id: id.into(), who: who.into() })) -} - -/// Disallow further unprivileged transfers of an asset `id` to and from an account `who`. -pub(crate) fn block(id: AssetId, who: impl Into>) -> Result<()> { - dispatch(RuntimeCall::Assets(AssetsCall::Block { id: id.into(), who: who.into() })) -} +// +// /// Create an asset account for non-provider assets. +// pub(crate) fn touch(id: AssetId) -> Result<()> { +// dispatch(RuntimeCall::Assets(AssetsCall::Touch { id: id.into() })) +// } +// +// /// Return the deposit (if any) of an asset account or a consumer reference (if any) of an +// /// account. +// pub(crate) fn refund(id: AssetId, allow_burn: bool) -> Result<()> { +// dispatch(RuntimeCall::Assets(AssetsCall::Refund { id: id.into(), allow_burn })) +// } +// +// /// Sets the minimum balance of an asset. +// pub(crate) fn set_min_balance(id: AssetId, min_balance: Balance) -> Result<()> { +// dispatch(RuntimeCall::Assets(AssetsCall::SetMinBalance { +// id: id.into(), +// min_balance: Compact(min_balance), +// })) +// } +// +// /// Create an asset account for `who`. +// pub(crate) fn touch_other(id: AssetId, who: impl Into>) -> Result<()> { +// dispatch(RuntimeCall::Assets(AssetsCall::TouchOther { id: id.into(), who: who.into() })) +// } +// +// /// Return the deposit (if any) of a target asset account. Useful if you are the depositor. +// pub(crate) fn refund_other(id: AssetId, who: impl Into>) -> Result<()> { +// dispatch(RuntimeCall::Assets(AssetsCall::RefundOther { id: id.into(), who: who.into() })) +// } +// +// /// Disallow further unprivileged transfers of an asset `id` to and from an account `who`. +// pub(crate) fn block(id: AssetId, who: impl Into>) -> Result<()> { +// dispatch(RuntimeCall::Assets(AssetsCall::Block { id: id.into(), who: who.into() })) +// } /// 2. Read state functions /// - total_supply -/// - - +/// - balance_of +/// - allowance +/// - asset_exists +/// - token_name +/// - token_symbol +/// - token_decimals +// +#[inline] pub(crate) fn total_supply(id: AssetId) -> Result { state::read(RuntimeStateKeys::Assets(AssetsKeys::TotalSupply(id))) } +#[inline] pub(crate) fn balance_of(id: AssetId, owner: AccountId) -> Result { state::read(RuntimeStateKeys::Assets(AssetsKeys::BalanceOf(id, owner))) } +#[inline] pub(crate) fn allowance(id: AssetId, owner: AccountId, spender: AccountId) -> Result { state::read(RuntimeStateKeys::Assets(AssetsKeys::Allowance(id, owner, spender))) } -pub(crate) fn asset_exists(id: AssetId) -> Result { - state::read(RuntimeStateKeys::Assets(AssetsKeys::AssetExists(id))) +// pub(crate) fn asset_exists(id: AssetId) -> Result { +// state::read(RuntimeStateKeys::Assets(AssetsKeys::AssetExists(id))) +// } + +#[inline] +pub(crate) fn token_name(id: AssetId) -> Result> { + state::read(RuntimeStateKeys::Assets(AssetsKeys::TokenName(id))) +} +// +#[inline] +pub(crate) fn token_symbol(id: AssetId) -> Result> { + state::read(RuntimeStateKeys::Assets(AssetsKeys::TokenSymbol(id))) +} + +#[inline] +pub(crate) fn token_decimals(id: AssetId) -> Result { + state::read(RuntimeStateKeys::Assets(AssetsKeys::TokenDecimals(id))) } // Parameters to extrinsics representing an asset id (`AssetIdParameter`) and a balance amount (`Balance`) are expected @@ -321,63 +340,63 @@ pub(crate) fn asset_exists(id: AssetId) -> Result { type AssetIdParameter = Compact; // Balance amount that is compact encoded. type BalanceParameter = Compact; - +// #[derive(Encode)] pub(crate) enum AssetsCall { - #[codec(index = 0)] - Create { id: AssetIdParameter, admin: MultiAddress, min_balance: Balance }, - #[codec(index = 2)] - StartDestroy { id: AssetIdParameter }, - #[codec(index = 3)] - DestroyAccounts { id: AssetIdParameter }, - #[codec(index = 4)] - DestroyApprovals { id: AssetIdParameter }, - #[codec(index = 5)] - FinishDestroy { id: AssetIdParameter }, - #[codec(index = 6)] - Mint { - id: AssetIdParameter, - beneficiary: MultiAddress, - amount: BalanceParameter, - }, - #[codec(index = 7)] - Burn { id: AssetIdParameter, who: MultiAddress, amount: BalanceParameter }, - #[codec(index = 8)] - Transfer { id: AssetIdParameter, target: MultiAddress, amount: BalanceParameter }, + // #[codec(index = 0)] + // Create { id: AssetIdParameter, admin: MultiAddress, min_balance: Balance }, + // #[codec(index = 2)] + // StartDestroy { id: AssetIdParameter }, + // #[codec(index = 3)] + // DestroyAccounts { id: AssetIdParameter }, + // #[codec(index = 4)] + // DestroyApprovals { id: AssetIdParameter }, + // #[codec(index = 5)] + // FinishDestroy { id: AssetIdParameter }, + // #[codec(index = 6)] + // Mint { + // id: AssetIdParameter, + // beneficiary: MultiAddress, + // amount: BalanceParameter, + // }, + // #[codec(index = 7)] + // Burn { id: AssetIdParameter, who: MultiAddress, amount: BalanceParameter }, + // #[codec(index = 8)] + // Transfer { id: AssetIdParameter, target: MultiAddress, amount: BalanceParameter }, #[codec(index = 9)] TransferKeepAlive { id: AssetIdParameter, target: MultiAddress, amount: BalanceParameter, }, - #[codec(index = 10)] - ForceTransfer { - id: AssetIdParameter, - source: MultiAddress, - dest: MultiAddress, - amount: BalanceParameter, - }, - #[codec(index = 11)] - Freeze { id: AssetIdParameter, who: MultiAddress }, - #[codec(index = 12)] - Thaw { id: AssetIdParameter, who: MultiAddress }, - #[codec(index = 13)] - FreezeAsset { id: AssetIdParameter }, - #[codec(index = 14)] - ThawAsset { id: AssetIdParameter }, - #[codec(index = 15)] - TransferOwnership { id: AssetIdParameter, owner: MultiAddress }, - #[codec(index = 16)] - SetTeam { - id: AssetIdParameter, - issuer: MultiAddress, - admin: MultiAddress, - freezer: MultiAddress, - }, - #[codec(index = 17)] - SetMetadata { id: AssetIdParameter, name: Vec, symbol: Vec, decimals: u8 }, - #[codec(index = 18)] - ClearMetadata { id: AssetIdParameter }, + // #[codec(index = 10)] + // ForceTransfer { + // id: AssetIdParameter, + // source: MultiAddress, + // dest: MultiAddress, + // amount: BalanceParameter, + // }, + // #[codec(index = 11)] + // Freeze { id: AssetIdParameter, who: MultiAddress }, + // #[codec(index = 12)] + // Thaw { id: AssetIdParameter, who: MultiAddress }, + // #[codec(index = 13)] + // FreezeAsset { id: AssetIdParameter }, + // #[codec(index = 14)] + // ThawAsset { id: AssetIdParameter }, + // #[codec(index = 15)] + // TransferOwnership { id: AssetIdParameter, owner: MultiAddress }, + // #[codec(index = 16)] + // SetTeam { + // id: AssetIdParameter, + // issuer: MultiAddress, + // admin: MultiAddress, + // freezer: MultiAddress, + // }, + // #[codec(index = 17)] + // SetMetadata { id: AssetIdParameter, name: Vec, symbol: Vec, decimals: u8 }, + // #[codec(index = 18)] + // ClearMetadata { id: AssetIdParameter }, #[codec(index = 22)] ApproveTransfer { id: AssetIdParameter, @@ -386,12 +405,12 @@ pub(crate) enum AssetsCall { }, #[codec(index = 23)] CancelApproval { id: AssetIdParameter, delegate: MultiAddress }, - #[codec(index = 24)] - ForceCancelApproval { - id: AssetIdParameter, - owner: MultiAddress, - delegate: MultiAddress, - }, + // #[codec(index = 24)] + // ForceCancelApproval { + // id: AssetIdParameter, + // owner: MultiAddress, + // delegate: MultiAddress, + // }, #[codec(index = 25)] TransferApproved { id: AssetIdParameter, @@ -399,96 +418,97 @@ pub(crate) enum AssetsCall { destination: MultiAddress, amount: BalanceParameter, }, - #[codec(index = 26)] - Touch { id: AssetIdParameter }, - #[codec(index = 27)] - Refund { id: AssetIdParameter, allow_burn: bool }, - #[codec(index = 28)] - SetMinBalance { id: AssetIdParameter, min_balance: BalanceParameter }, - #[codec(index = 29)] - TouchOther { id: AssetIdParameter, who: MultiAddress }, - #[codec(index = 30)] - RefundOther { id: AssetIdParameter, who: MultiAddress }, - #[codec(index = 31)] - Block { id: AssetIdParameter, who: MultiAddress }, -} - -// TODO: Not being used atm but necessary if we want to provide access to the -// rest of the pallet, outside of the use cases. -#[derive(Debug, Copy, Clone, PartialEq, Eq, Encode, scale::Decode)] -#[cfg_attr(feature = "std", derive(scale_info::TypeInfo))] -pub enum AssetsError { - /// Account balance must be greater than or equal to the transfer amount. - BalanceLow, - /// The account to alter does not exist. - NoAccount, - /// The signing account has no permission to do the operation. - NoPermission, - /// The given asset ID is unknown. - Unknown, - /// The origin account is frozen. - Frozen, - /// The asset ID is already taken. - InUse, - /// Invalid witness data given. - BadWitness, - /// Minimum balance should be non-zero. - MinBalanceZero, - /// Unable to increment the consumer reference counters on the account. Either no provider - /// reference exists to allow a non-zero balance of a non-self-sufficient asset, or one - /// fewer then the maximum number of consumers has been reached. - UnavailableConsumer, - /// Invalid metadata given. - BadMetadata, - /// No approval exists that would allow the transfer. - Unapproved, - /// The source account would not survive the transfer and it needs to stay alive. - WouldDie, - /// The asset-account already exists. - AlreadyExists, - /// The asset-account doesn't have an associated deposit. - NoDeposit, - /// The operation would result in funds being burned. - WouldBurn, - /// The asset is a live asset and is actively being used. Usually emit for operations such - /// as `start_destroy` which require the asset to be in a destroying state. - LiveAsset, - /// The asset is not live, and likely being destroyed. - AssetNotLive, - /// The asset status is not the expected status. - IncorrectStatus, - /// The asset should be frozen before the given operation. - NotFrozen, - /// Callback action resulted in error. - CallbackFailed, + // // #[codec(index = 26)] + // // Touch { id: AssetIdParameter }, + // // #[codec(index = 27)] + // // Refund { id: AssetIdParameter, allow_burn: bool }, + // // #[codec(index = 28)] + // // SetMinBalance { id: AssetIdParameter, min_balance: BalanceParameter }, + // // #[codec(index = 29)] + // // TouchOther { id: AssetIdParameter, who: MultiAddress }, + // // #[codec(index = 30)] + // // RefundOther { id: AssetIdParameter, who: MultiAddress }, + // // #[codec(index = 31)] + // // Block { id: AssetIdParameter, who: MultiAddress }, + // } + + // // TODO: Not being used atm but necessary if we want to provide access to the + // // rest of the pallet, outside of the use cases. + // #[derive(Debug, Copy, Clone, PartialEq, Eq, Encode, scale::Decode)] + // #[cfg_attr(feature = "std", derive(scale_info::TypeInfo))] + // pub enum AssetsError { + // /// Account balance must be greater than or equal to the transfer amount. + // BalanceLow, + // /// The account to alter does not exist. + // NoAccount, + // /// The signing account has no permission to do the operation. + // NoPermission, + // /// The given asset ID is unknown. + // Unknown, + // /// The origin account is frozen. + // Frozen, + // /// The asset ID is already taken. + // InUse, + // /// Invalid witness data given. + // BadWitness, + // /// Minimum balance should be non-zero. + // MinBalanceZero, + // /// Unable to increment the consumer reference counters on the account. Either no provider + // /// reference exists to allow a non-zero balance of a non-self-sufficient asset, or one + // /// fewer then the maximum number of consumers has been reached. + // UnavailableConsumer, + // /// Invalid metadata given. + // BadMetadata, + // /// No approval exists that would allow the transfer. + // Unapproved, + // /// The source account would not survive the transfer and it needs to stay alive. + // WouldDie, + // /// The asset-account already exists. + // AlreadyExists, + // /// The asset-account doesn't have an associated deposit. + // NoDeposit, + // /// The operation would result in funds being burned. + // WouldBurn, + // /// The asset is a live asset and is actively being used. Usually emit for operations such + // /// as `start_destroy` which require the asset to be in a destroying state. + // LiveAsset, + // /// The asset is not live, and likely being destroyed. + // AssetNotLive, + // /// The asset status is not the expected status. + // IncorrectStatus, + // /// The asset should be frozen before the given operation. + // NotFrozen, + // /// Callback action resulted in error. + // CallbackFailed, } -impl TryFrom for AssetsError { - type Error = Error; - - fn try_from(status_code: u32) -> core::result::Result { - use AssetsError::*; - match status_code { - 0 => Ok(BalanceLow), - 1 => Ok(NoAccount), - 2 => Ok(NoPermission), - 3 => Ok(Unknown), - 4 => Ok(Frozen), - 5 => Ok(InUse), - 6 => Ok(BadWitness), - 7 => Ok(MinBalanceZero), - 8 => Ok(UnavailableConsumer), - 9 => Ok(BadMetadata), - 10 => Ok(Unapproved), - 11 => Ok(WouldDie), - 12 => Ok(AlreadyExists), - 13 => Ok(NoDeposit), - 14 => Ok(WouldBurn), - 15 => Ok(LiveAsset), - 16 => Ok(AssetNotLive), - 17 => Ok(IncorrectStatus), - 18 => Ok(NotFrozen), - _ => todo!(), - } - } -} +// +// impl TryFrom for AssetsError { +// type Error = Error; +// +// fn try_from(status_code: u32) -> core::result::Result { +// use AssetsError::*; +// match status_code { +// 0 => Ok(BalanceLow), +// 1 => Ok(NoAccount), +// 2 => Ok(NoPermission), +// 3 => Ok(Unknown), +// 4 => Ok(Frozen), +// 5 => Ok(InUse), +// 6 => Ok(BadWitness), +// 7 => Ok(MinBalanceZero), +// 8 => Ok(UnavailableConsumer), +// 9 => Ok(BadMetadata), +// 10 => Ok(Unapproved), +// 11 => Ok(WouldDie), +// 12 => Ok(AlreadyExists), +// 13 => Ok(NoDeposit), +// 14 => Ok(WouldBurn), +// 15 => Ok(LiveAsset), +// 16 => Ok(AssetNotLive), +// 17 => Ok(IncorrectStatus), +// 18 => Ok(NotFrozen), +// _ => todo!(), +// } +// } +// } diff --git a/pop-api/src/v0/state.rs b/pop-api/src/v0/state.rs index e3d38129..914a9603 100644 --- a/pop-api/src/v0/state.rs +++ b/pop-api/src/v0/state.rs @@ -1,6 +1,7 @@ -use crate::{primitives::storage_keys::RuntimeStateKeys, read_state, Error}; +use crate::{error::StatusCode, primitives::storage_keys::RuntimeStateKeys, read_state}; use scale::Decode; +#[inline] pub fn read(key: RuntimeStateKeys) -> crate::Result { - read_state(key).and_then(|v| T::decode(&mut &v[..]).map_err(|_e| Error::DecodingFailed.into())) + read_state(key).and_then(|v| T::decode(&mut &v[..]).map_err(|_e| StatusCode(255u32))) } diff --git a/primitives/src/lib.rs b/primitives/src/lib.rs index 3b91f713..dc0a5245 100644 --- a/primitives/src/lib.rs +++ b/primitives/src/lib.rs @@ -9,7 +9,7 @@ use {scale_decode::DecodeAsType, scale_encode::EncodeAsType, scale_info::TypeInf pub mod cross_chain; pub mod storage_keys; -#[derive(Encode, Decode, Debug, MaxEncodedLen, Eq, PartialEq, Ord, PartialOrd)] +#[derive(Encode, Decode, Clone, Debug, MaxEncodedLen, Eq, PartialEq, Ord, PartialOrd)] #[cfg_attr(feature = "std", derive(TypeInfo, DecodeAsType, EncodeAsType))] pub struct AccountId(pub [u8; 32]); diff --git a/primitives/src/storage_keys.rs b/primitives/src/storage_keys.rs index 748d0662..7992089b 100644 --- a/primitives/src/storage_keys.rs +++ b/primitives/src/storage_keys.rs @@ -47,10 +47,13 @@ pub enum NftsKeys { #[derive(Encode, Decode, Debug, MaxEncodedLen)] pub enum AssetsKeys { Allowance(AssetId, AccountId, AccountId), - /// Check if the asset exists. - AssetExists(AssetId), + // /// Check if the asset exists. + // // AssetExists(AssetId), /// Check balance. BalanceOf(AssetId, AccountId), /// Returns the total token supply for a given asset ID. TotalSupply(AssetId), + TokenDecimals(AssetId), + TokenSymbol(AssetId), + TokenName(AssetId), } From 7757319213cab9de78b0a3f26eda15cf513af454 Mon Sep 17 00:00:00 2001 From: Daanvdplas Date: Wed, 3 Jul 2024 08:18:27 +0200 Subject: [PATCH 015/112] refactor: runtime --- pop-api/Cargo.toml | 6 +- pop-api/examples/fungibles/Cargo.toml | 4 - pop-api/examples/fungibles/lib.rs | 4 +- pop-api/src/error.rs | 38 ++-- pop-api/src/lib.rs | 4 +- pop-api/src/v0/assets/fungibles.rs | 10 +- pop-api/src/v0/assets/mod.rs | 22 +- pop-api/src/v0/mod.rs | 3 +- pop-api/src/v0/state.rs | 2 +- runtime/devnet/src/extensions.rs | 295 +++++++++++--------------- 10 files changed, 168 insertions(+), 220 deletions(-) diff --git a/pop-api/Cargo.toml b/pop-api/Cargo.toml index a88d8892..82ee7613 100644 --- a/pop-api/Cargo.toml +++ b/pop-api/Cargo.toml @@ -8,8 +8,6 @@ edition = "2021" [dependencies] enumflags2 = { version = "0.7.7" } ink = { version = "5.0.0", default-features = false } -scale = { package = "parity-scale-codec", version = "3", default-features = false, features = ["derive"] } -scale-info = { version = "2.10.0", default-features = false, features = ["derive"] } sp-io = { version = "31.0.0", default-features = false, features = ["disable_panic_handler", "disable_oom", "disable_allocator"] } sp-runtime = { version = "32.0.0", default-features = false } @@ -26,9 +24,7 @@ std = [ "enumflags2/std", "ink/std", "pop-primitives/std", - "scale/std", - "scale-info/std", -"sp-io/std", + "sp-io/std", "sp-runtime/std", ] assets = ["pop-primitives/assets"] diff --git a/pop-api/examples/fungibles/Cargo.toml b/pop-api/examples/fungibles/Cargo.toml index 514f000f..565b0554 100755 --- a/pop-api/examples/fungibles/Cargo.toml +++ b/pop-api/examples/fungibles/Cargo.toml @@ -7,8 +7,6 @@ edition = "2021" [dependencies] ink = { version = "5.0.0", default-features = false } pop-api = { path = "../../../pop-api", default-features = false, features = ["assets"] } -scale = { package = "parity-scale-codec", version = "3", default-features = false, features = ["derive"] } -scale-info = { version = "2.6", default-features = false, features = ["derive"], optional = true } [lib] path = "lib.rs" @@ -18,8 +16,6 @@ default = ["std"] std = [ "ink/std", "pop-api/std", - "scale/std", - "scale-info/std", ] ink-as-dependency = [] e2e-tests = [] diff --git a/pop-api/examples/fungibles/lib.rs b/pop-api/examples/fungibles/lib.rs index bd51d760..1794fbe5 100755 --- a/pop-api/examples/fungibles/lib.rs +++ b/pop-api/examples/fungibles/lib.rs @@ -85,7 +85,7 @@ mod fungibles { to: AccountId32, value: Balance, // In the standard a `[u8]`, but the size needs to be known at compile time. - data: Vec, + _data: Vec, ) -> Result<()> { ink::env::debug_println!( "PopApiFungiblesExample::transfer_from: id: {:?}, from: {:?}, to: {:?} value: {:?}", @@ -95,7 +95,7 @@ mod fungibles { value, ); - let result = api::transfer_from(id, from, to, value, &data); + let result = api::transfer_from(id, from, to, value); ink::env::debug_println!("Result: {:?}", result); // result.map_err(|e| e.into()) result diff --git a/pop-api/src/error.rs b/pop-api/src/error.rs index 54681e6d..8989464f 100644 --- a/pop-api/src/error.rs +++ b/pop-api/src/error.rs @@ -1,10 +1,7 @@ -use ink::env::chain_extension::FromStatusCode; -use scale::{Decode, Encode}; +use ink::{env::chain_extension::FromStatusCode, scale::Decode}; -use Error::*; - -#[derive(Debug, Copy, Clone, PartialEq, Eq, Encode, Decode)] -#[cfg_attr(feature = "std", derive(scale_info::TypeInfo))] +#[derive(Debug, PartialEq, Eq)] +#[ink::scale_derive(Encode, Decode, TypeInfo)] pub struct StatusCode(pub u32); impl From for StatusCode { @@ -14,21 +11,21 @@ impl From for StatusCode { } impl FromStatusCode for StatusCode { fn from_status_code(status_code: u32) -> Result<(), Self> { - if status_code == 0 { - return Ok(()); + match status_code { + 0 => Ok(()), + _ => Err(StatusCode(status_code)), } - Err(StatusCode(status_code)) } } -impl From for StatusCode { - fn from(_: scale::Error) -> Self { +impl From for StatusCode { + fn from(_: ink::scale::Error) -> Self { StatusCode(255u32) } } -#[derive(Debug, Copy, Clone, PartialEq, Eq, Encode, Decode)] -#[cfg_attr(feature = "std", derive(scale_info::TypeInfo))] +#[derive(Debug, PartialEq, Eq)] +#[ink::scale_derive(Encode, Decode, TypeInfo)] #[repr(u8)] pub enum Error { /// Some unknown error occurred. Go to the Pop API docs section `Pop API error`. @@ -70,6 +67,7 @@ pub enum Error { Unavailable = 12, /// Root origin is not allowed. RootNotAllowed = 13, + UnknownFunctionId = 254, DecodingFailed = 255, } @@ -92,15 +90,15 @@ impl From for Error { Err(_) => { encoded[..].rotate_right(1); encoded[0] = 0u8; - Error::decode(&mut &encoded[..]).unwrap_or(DecodingFailed) + Error::decode(&mut &encoded[..]).unwrap_or(Error::DecodingFailed) }, Ok(error) => error, } } } -#[derive(Debug, Copy, Clone, PartialEq, Eq, scale::Encode, scale::Decode)] -#[cfg_attr(feature = "std", derive(scale_info::TypeInfo))] +#[derive(Debug, PartialEq, Eq)] +#[ink::scale_derive(Encode, Decode, TypeInfo)] pub enum TokenError { /// Funds are unavailable. FundsUnavailable, @@ -125,8 +123,8 @@ pub enum TokenError { Blocked, } -#[derive(Debug, Copy, Clone, PartialEq, Eq, scale::Encode, scale::Decode)] -#[cfg_attr(feature = "std", derive(scale_info::TypeInfo))] +#[derive(Debug, PartialEq, Eq)] +#[ink::scale_derive(Encode, Decode, TypeInfo)] pub enum ArithmeticError { /// Underflow. Underflow, @@ -136,8 +134,8 @@ pub enum ArithmeticError { DivisionByZero, } -#[derive(Debug, Copy, Clone, PartialEq, Eq, scale::Encode, scale::Decode)] -#[cfg_attr(feature = "std", derive(scale_info::TypeInfo))] +#[derive(Debug, PartialEq, Eq)] +#[ink::scale_derive(Encode, Decode, TypeInfo)] pub enum TransactionalError { /// Too many transactional layers have been spawned. LimitReached, diff --git a/pop-api/src/lib.rs b/pop-api/src/lib.rs index 53bbadc6..55307f3e 100644 --- a/pop-api/src/lib.rs +++ b/pop-api/src/lib.rs @@ -27,8 +27,8 @@ type BlockNumber = ::BlockNumber; pub type Result = core::result::Result; -#[derive(Debug, Clone, PartialEq, Eq)] -#[cfg_attr(feature = "std", derive(scale_info::TypeInfo))] +#[derive(Debug, PartialEq, Eq, Clone)] +#[ink::scale_derive(Encode, Decode, TypeInfo)] pub enum Environment {} impl ink::env::Environment for Environment { diff --git a/pop-api/src/v0/assets/fungibles.rs b/pop-api/src/v0/assets/fungibles.rs index e7c3f41c..376ca898 100644 --- a/pop-api/src/v0/assets/fungibles.rs +++ b/pop-api/src/v0/assets/fungibles.rs @@ -1,5 +1,4 @@ use ink::prelude::vec::Vec; -use scale::Encode; use crate::{ assets, @@ -102,7 +101,6 @@ pub fn transfer_from( from: impl Into>, to: impl Into>, value: Balance, - _data: &[u8], ) -> Result<()> { assets::transfer_approved(id, from, to, value) } @@ -293,8 +291,8 @@ pub fn token_decimals(id: AssetId) -> Result { // assets::asset_exists(id) // } -#[derive(Encode)] -#[cfg_attr(feature = "std", derive(scale_info::TypeInfo))] +#[derive(Debug, PartialEq, Eq)] +#[ink::scale_derive(Encode, Decode, TypeInfo)] pub enum FungiblesError { Other(StatusCode), /// The asset is not live; either frozen or being destroyed. @@ -344,13 +342,13 @@ mod tests { use scale::Decode; use super::FungiblesError; - use crate::StatusCode; - use pop_primitives::{ + use crate::error::{ ArithmeticError::*, Error::{self, *}, TokenError::*, TransactionalError::*, }; + use crate::StatusCode; fn into_fungibles_error(error: Error) -> FungiblesError { let status_code: StatusCode = error.into(); diff --git a/pop-api/src/v0/assets/mod.rs b/pop-api/src/v0/assets/mod.rs index 22e32d47..241c5020 100644 --- a/pop-api/src/v0/assets/mod.rs +++ b/pop-api/src/v0/assets/mod.rs @@ -1,5 +1,4 @@ -use ink::prelude::vec::Vec; -use scale::{Compact, Encode}; +use ink::{prelude::vec::Vec, scale::Compact}; use crate::{state::read, Balance, RuntimeCall, *}; use primitives::{AssetId, MultiAddress}; @@ -97,7 +96,7 @@ type Result = core::result::Result; // })) // } -// /// Move some assets from the sender account to another. +/// Move some assets from the sender account to another. #[inline] pub(crate) fn transfer( id: AssetId, @@ -199,7 +198,7 @@ pub(crate) fn transfer( // dispatch(RuntimeCall::Assets(AssetsCall::ClearMetadata { id: id.into() })) // } -// /// Approve an amount of asset for transfer by a delegated third-party account. +/// Approve an amount of asset for transfer by a delegated third-party account. #[inline] pub(crate) fn approve_transfer( id: AssetId, @@ -300,17 +299,17 @@ pub(crate) fn transfer_approved( // #[inline] pub(crate) fn total_supply(id: AssetId) -> Result { - state::read(RuntimeStateKeys::Assets(AssetsKeys::TotalSupply(id))) + read(RuntimeStateKeys::Assets(AssetsKeys::TotalSupply(id))) } #[inline] pub(crate) fn balance_of(id: AssetId, owner: AccountId) -> Result { - state::read(RuntimeStateKeys::Assets(AssetsKeys::BalanceOf(id, owner))) + read(RuntimeStateKeys::Assets(AssetsKeys::BalanceOf(id, owner))) } #[inline] pub(crate) fn allowance(id: AssetId, owner: AccountId, spender: AccountId) -> Result { - state::read(RuntimeStateKeys::Assets(AssetsKeys::Allowance(id, owner, spender))) + read(RuntimeStateKeys::Assets(AssetsKeys::Allowance(id, owner, spender))) } // pub(crate) fn asset_exists(id: AssetId) -> Result { // state::read(RuntimeStateKeys::Assets(AssetsKeys::AssetExists(id))) @@ -318,17 +317,17 @@ pub(crate) fn allowance(id: AssetId, owner: AccountId, spender: AccountId) -> Re #[inline] pub(crate) fn token_name(id: AssetId) -> Result> { - state::read(RuntimeStateKeys::Assets(AssetsKeys::TokenName(id))) + read(RuntimeStateKeys::Assets(AssetsKeys::TokenName(id))) } // #[inline] pub(crate) fn token_symbol(id: AssetId) -> Result> { - state::read(RuntimeStateKeys::Assets(AssetsKeys::TokenSymbol(id))) + read(RuntimeStateKeys::Assets(AssetsKeys::TokenSymbol(id))) } #[inline] pub(crate) fn token_decimals(id: AssetId) -> Result { - state::read(RuntimeStateKeys::Assets(AssetsKeys::TokenDecimals(id))) + read(RuntimeStateKeys::Assets(AssetsKeys::TokenDecimals(id))) } // Parameters to extrinsics representing an asset id (`AssetIdParameter`) and a balance amount (`Balance`) are expected @@ -341,7 +340,8 @@ type AssetIdParameter = Compact; // Balance amount that is compact encoded. type BalanceParameter = Compact; // -#[derive(Encode)] +#[derive(Debug, PartialEq, Eq)] +#[ink::scale_derive(Encode, Decode, TypeInfo)] pub(crate) enum AssetsCall { // #[codec(index = 0)] // Create { id: AssetIdParameter, admin: MultiAddress, min_balance: Balance }, diff --git a/pop-api/src/v0/mod.rs b/pop-api/src/v0/mod.rs index 20dc6476..f91c4271 100644 --- a/pop-api/src/v0/mod.rs +++ b/pop-api/src/v0/mod.rs @@ -8,7 +8,8 @@ pub mod cross_chain; pub mod nfts; pub mod state; -#[derive(scale::Encode)] +#[derive(Debug, PartialEq, Eq)] +#[ink::scale_derive(Encode, Decode, TypeInfo)] pub(crate) enum RuntimeCall { #[codec(index = 10)] #[cfg(feature = "balances")] diff --git a/pop-api/src/v0/state.rs b/pop-api/src/v0/state.rs index 914a9603..afe48ba8 100644 --- a/pop-api/src/v0/state.rs +++ b/pop-api/src/v0/state.rs @@ -1,5 +1,5 @@ use crate::{error::StatusCode, primitives::storage_keys::RuntimeStateKeys, read_state}; -use scale::Decode; +use ink::scale::Decode; #[inline] pub fn read(key: RuntimeStateKeys) -> crate::Result { diff --git a/runtime/devnet/src/extensions.rs b/runtime/devnet/src/extensions.rs index 904d18ce..6f98bf96 100644 --- a/runtime/devnet/src/extensions.rs +++ b/runtime/devnet/src/extensions.rs @@ -57,24 +57,132 @@ where E: Ext, { log::debug!(target:LOG_TARGET, " extension called "); - match v0::FuncId::try_from(env.func_id())? { - v0::FuncId::Dispatch => match dispatch::(env) { - Ok(()) => Ok(RetVal::Converging(0)), - Err(e) => Ok(RetVal::Converging(convert_to_status_code(e))), - }, - v0::FuncId::ReadState => { - read_state::(env)?; - Ok(RetVal::Converging(0)) - }, - v0::FuncId::SendXcm => { - send_xcm::(env)?; - Ok(RetVal::Converging(0)) + let mut env = env.buf_in_buf_out(); + let contract_host_weight = ContractSchedule::::get().host_fn_weights; + // debug_message weight is a good approximation of the additional overhead of going + // from contract layer to substrate layer. + // reference: https://github.com/paritytech/ink-examples/blob/b8d2caa52cf4691e0ddd7c919e4462311deb5ad0/psp22-extension/runtime/psp22-extension-example.rs#L236 + env.charge_weight(contract_host_weight.debug_message)?; + + let result = match v0::FuncId::try_from(env.func_id()) { + Ok(function) => { + // calculate weight for reading bytes of `len` + // reference: https://github.com/paritytech/polkadot-sdk/blob/117a9433dac88d5ac00c058c9b39c511d47749d2/substrate/frame/contracts/src/wasm/runtime.rs#L267 + let len = env.in_len(); + env.charge_weight(contract_host_weight.return_per_byte.saturating_mul(len.into()))?; + match function { + v0::FuncId::Dispatch => dispatch::(&mut env, len), + v0::FuncId::ReadState => read_state::(&mut env), + v0::FuncId::SendXcm => send_xcm::(&mut env), + } }, + Err(e) => Err(e), + }; + + // Convert any error to a status code and return Ok with RetVal::Converging + match result { + Ok(_) => Ok(RetVal::Converging(0)), + Err(e) => Ok(RetVal::Converging(convert_to_status_code(e))), } } } + +fn dispatch(env: &mut Environment, len: u32) -> Result<(), DispatchError> +where + T: pallet_contracts::Config + + frame_system::Config, + RuntimeOrigin: From>, + E: Ext, +{ + const LOG_PREFIX: &str = " dispatch |"; + + // read the input as RuntimeCall + let call: RuntimeCall = env.read_as_unbounded(len)?; + log::debug!(target: LOG_TARGET, "Read input as call successfully"); + // contract is the origin by default + let origin: RuntimeOrigin = RawOrigin::Signed(env.ext().address().clone()).into(); + dispatch_call::(env, call, origin, LOG_PREFIX) +} + +fn read_state(env: &mut Environment) -> Result<(), DispatchError> +where + T: pallet_contracts::Config + + pallet_assets::Config + + pallet_nfts::Config + + cumulus_pallet_parachain_system::Config + + frame_system::Config, + E: Ext, +{ + const LOG_PREFIX: &str = " read_state |"; + + let key: RuntimeStateKeys = env.read_as()?; + let result = match key { + RuntimeStateKeys::Nfts(key) => read_nfts_state::(key, env), + RuntimeStateKeys::ParachainSystem(key) => read_parachain_system_state::(key, env), + RuntimeStateKeys::Assets(key) => read_assets_state::(key, env), + }? + .encode(); + + log::trace!( + target:LOG_TARGET, + "{} result: {:?}.", LOG_PREFIX, result + ); + env.write(&result, false, None) +} + +fn send_xcm(env: &mut Environment) -> Result<(), DispatchError> +where + T: pallet_contracts::Config + + frame_system::Config< + RuntimeOrigin = RuntimeOrigin, + AccountId = AccountId, + RuntimeCall = RuntimeCall, + >, + E: Ext, +{ + const LOG_PREFIX: &str = " send_xcm |"; + + // read the input as CrossChainMessage + let xc_call: CrossChainMessage = env.read_as::()?; + // Determine the call to dispatch + let (dest, message) = match xc_call { + CrossChainMessage::Relay(message) => { + let dest = Location::parent().into_versioned(); + let assets: Asset = (Here, 10 * UNIT).into(); + let beneficiary: Location = + AccountId32 { id: (env.ext().address().clone()).into(), network: None }.into(); + let message = Xcm::builder() + .withdraw_asset(assets.clone().into()) + .buy_execution(assets.clone(), Unlimited) + .transact( + SovereignAccount, + Weight::from_parts(250_000_000, 10_000), + message.encode().into(), + ) + .refund_surplus() + .deposit_asset(assets.into(), beneficiary) + .build(); + (dest, message) + }, + }; + + // TODO: revisit to replace with signed contract origin + let origin: RuntimeOrigin = RawOrigin::Root.into(); + + // Generate runtime call to dispatch + let call = RuntimeCall::PolkadotXcm(pallet_xcm::Call::send { + dest: Box::new(dest), + message: Box::new(VersionedXcm::V4(message)), + }); + + dispatch_call::(env, call, origin, LOG_PREFIX) +} + pub(crate) fn convert_to_status_code(error: DispatchError) -> u32 { - let mut encoded_error = error.encode(); + let mut encoded_error = match error { + DispatchError::Other("UnknownFunctionId") => vec![254, 0, 0, 0], + _ => error.encode(), + }; // Resize the encoded value to 4 bytes in order to decode the value in a u32 (4 bytes). encoded_error.resize(4, 0); u32::decode(&mut &encoded_error[..]).expect("qid, resized to 4 bytes line above") @@ -99,8 +207,7 @@ impl TryFrom for v0::FuncId { 0x2 => Self::SendXcm, _ => { log::error!("called an unregistered `func_id`: {:}", func_id); - // TODO: Other error. - return Err(DispatchError::Other("unimplemented func_id")); + return Err(DispatchError::Other("UnknownFuncId")); }, }; @@ -143,101 +250,6 @@ where } } -fn charge_overhead_weight( - env: &mut Environment, - len: u32, - log_prefix: &str, -) -> Result -where - T: pallet_contracts::Config, - E: Ext, -{ - let contract_host_weight = ContractSchedule::::get().host_fn_weights; - - // calculate weight for reading bytes of `len` - // reference: https://github.com/paritytech/polkadot-sdk/blob/117a9433dac88d5ac00c058c9b39c511d47749d2/substrate/frame/contracts/src/wasm/runtime.rs#L267 - let base_weight: Weight = contract_host_weight.return_per_byte.saturating_mul(len.into()); - - // debug_message weight is a good approximation of the additional overhead of going - // from contract layer to substrate layer. - // reference: https://github.com/paritytech/ink-examples/blob/b8d2caa52cf4691e0ddd7c919e4462311deb5ad0/psp22-extension/runtime/psp22-extension-example.rs#L236 - let overhead = contract_host_weight.debug_message; - - let charged_weight = env.charge_weight(base_weight.saturating_add(overhead))?; - log::debug!(target: LOG_TARGET, "{} charged weight: {:?}", log_prefix, charged_weight); - - Ok(charged_weight) -} - -fn dispatch(env: Environment) -> Result<(), DispatchError> -where - T: pallet_contracts::Config - + frame_system::Config, - RuntimeOrigin: From>, - E: Ext, -{ - const LOG_PREFIX: &str = " dispatch |"; - - let mut env = env.buf_in_buf_out(); - let len = env.in_len(); - - charge_overhead_weight::(&mut env, len, LOG_PREFIX)?; - - // read the input as RuntimeCall - let call: RuntimeCall = env.read_as_unbounded(len)?; - - log::debug!(target: LOG_TARGET, "Read input as call successfully"); - - // contract is the origin by default - let origin: RuntimeOrigin = RawOrigin::Signed(env.ext().address().clone()).into(); - - dispatch_call::(&mut env, call, origin, LOG_PREFIX) -} - -fn read_state(env: Environment) -> Result<(), DispatchError> -where - T: pallet_contracts::Config - + pallet_assets::Config - + pallet_nfts::Config - + cumulus_pallet_parachain_system::Config - + frame_system::Config, - E: Ext, -{ - const LOG_PREFIX: &str = " read_state |"; - - let mut env = env.buf_in_buf_out(); - - // To be conservative, we charge the weight for reading the input bytes of a fixed-size type. - let base_weight: Weight = ContractSchedule::::get() - .host_fn_weights - .return_per_byte - .saturating_mul(env.in_len().into()); - let charged_weight = env.charge_weight(base_weight)?; - - log::debug!(target:LOG_TARGET, "{} charged weight: {:?}", LOG_PREFIX, charged_weight); - - let key: RuntimeStateKeys = env.read_as()?; - - let result = match key { - RuntimeStateKeys::Nfts(key) => read_nfts_state::(key, &mut env), - RuntimeStateKeys::ParachainSystem(key) => { - read_parachain_system_state::(key, &mut env) - }, - RuntimeStateKeys::Assets(key) => read_assets_state::(key, &mut env), - }? - .encode(); - - log::trace!( - target:LOG_TARGET, - "{} result: {:?}.", LOG_PREFIX, result - ); - env.write(&result, false, None).map_err(|e| { - log::trace!(target: LOG_TARGET, "{:?}", e); - // TODO: Other error. - DispatchError::Other("unable to write results to contract memory") - }) -} - fn read_parachain_system_state( key: ParachainSystemKeys, env: &mut Environment, @@ -320,10 +332,10 @@ where ) .encode()) }, - AssetsKeys::AssetExists(id) => { - env.charge_weight(T::DbWeight::get().reads(1_u64))?; - Ok(pallet_assets::Pallet::::asset_exists(id).encode()) - }, + // AssetsKeys::AssetExists(id) => { + // env.charge_weight(T::DbWeight::get().reads(1_u64))?; + // Ok(pallet_assets::Pallet::::asset_exists(id).encode()) + // }, AssetsKeys::BalanceOf(id, owner) => { env.charge_weight(T::DbWeight::get().reads(1_u64))?; Ok(pallet_assets::Pallet::::balance(id, &owner.0.into()) @@ -333,63 +345,10 @@ where env.charge_weight(T::DbWeight::get().reads(1_u64))?; Ok(pallet_assets::Pallet::::total_supply(id).encode()) }, + _ => todo!(), } } -fn send_xcm(env: Environment) -> Result<(), DispatchError> -where - T: pallet_contracts::Config - + frame_system::Config< - RuntimeOrigin = RuntimeOrigin, - AccountId = AccountId, - RuntimeCall = RuntimeCall, - >, - E: Ext, -{ - const LOG_PREFIX: &str = " send_xcm |"; - - let mut env = env.buf_in_buf_out(); - let len = env.in_len(); - - let _ = charge_overhead_weight::(&mut env, len, LOG_PREFIX)?; - - // read the input as CrossChainMessage - let xc_call: CrossChainMessage = env.read_as::()?; - - // Determine the call to dispatch - let (dest, message) = match xc_call { - CrossChainMessage::Relay(message) => { - let dest = Location::parent().into_versioned(); - let assets: Asset = (Here, 10 * UNIT).into(); - let beneficiary: Location = - AccountId32 { id: (env.ext().address().clone()).into(), network: None }.into(); - let message = Xcm::builder() - .withdraw_asset(assets.clone().into()) - .buy_execution(assets.clone(), Unlimited) - .transact( - SovereignAccount, - Weight::from_parts(250_000_000, 10_000), - message.encode().into(), - ) - .refund_surplus() - .deposit_asset(assets.into(), beneficiary) - .build(); - (dest, message) - }, - }; - - // TODO: revisit to replace with signed contract origin - let origin: RuntimeOrigin = RawOrigin::Root.into(); - - // Generate runtime call to dispatch - let call = RuntimeCall::PolkadotXcm(pallet_xcm::Call::send { - dest: Box::new(dest), - message: Box::new(VersionedXcm::V4(message)), - }); - - dispatch_call::(&mut env, call, origin, LOG_PREFIX) -} - #[cfg(test)] mod tests { use super::*; From 924df85ebd353cd56ff816f722fc8cdb4a6c5956 Mon Sep 17 00:00:00 2001 From: Daanvdplas Date: Tue, 2 Jul 2024 15:51:16 +0200 Subject: [PATCH 016/112] refactor: draft final design --- Cargo.lock | 3 +- pop-api/Cargo.toml | 4 +- pop-api/examples/fungibles/lib.rs | 119 ++--- pop-api/integration-tests/Cargo.toml | 4 +- .../integration-tests/src/local_fungibles.rs | 11 +- pop-api/src/error.rs | 335 ------------ pop-api/src/lib.rs | 85 ++- pop-api/src/primitives.rs | 1 - pop-api/src/v0/assets/fungibles.rs | 45 +- pop-api/src/v0/assets/mod.rs | 446 +++------------- pop-api/src/v0/balances.rs | 30 +- pop-api/src/v0/cross_chain/mod.rs | 29 +- pop-api/src/v0/mod.rs | 15 - pop-api/src/v0/nfts.rs | 37 +- pop-api/src/v0/state.rs | 7 - primitives/Cargo.toml | 7 - primitives/src/lib.rs | 124 ++++- primitives/src/storage_keys.rs | 13 +- runtime/devnet/Cargo.toml | 3 +- .../src/{extensions.rs => extensions/mod.rs} | 496 +++++++++++------- runtime/devnet/src/extensions/v0/assets.rs | 39 ++ runtime/devnet/src/extensions/v0/error.rs | 298 +++++++++++ runtime/devnet/src/extensions/v0/mod.rs | 2 + runtime/testnet/Cargo.toml | 2 +- runtime/testnet/src/extensions.rs | 18 +- 25 files changed, 1013 insertions(+), 1160 deletions(-) delete mode 100644 pop-api/src/error.rs delete mode 100644 pop-api/src/v0/state.rs rename runtime/devnet/src/{extensions.rs => extensions/mod.rs} (79%) create mode 100644 runtime/devnet/src/extensions/v0/assets.rs create mode 100644 runtime/devnet/src/extensions/v0/error.rs create mode 100644 runtime/devnet/src/extensions/v0/mod.rs diff --git a/Cargo.lock b/Cargo.lock index d798562b..cf7abf73 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -9675,8 +9675,6 @@ version = "0.0.0" dependencies = [ "bounded-collections 0.1.9", "parity-scale-codec", - "scale-decode", - "scale-encode", "scale-info", ] @@ -9744,6 +9742,7 @@ dependencies = [ "polkadot-runtime-common", "pop-primitives", "pop-runtime-common", + "rand", "scale-info", "smallvec", "sp-api", diff --git a/pop-api/Cargo.toml b/pop-api/Cargo.toml index 82ee7613..dc48ea8a 100644 --- a/pop-api/Cargo.toml +++ b/pop-api/Cargo.toml @@ -9,9 +9,8 @@ edition = "2021" enumflags2 = { version = "0.7.7" } ink = { version = "5.0.0", default-features = false } sp-io = { version = "31.0.0", default-features = false, features = ["disable_panic_handler", "disable_oom", "disable_allocator"] } -sp-runtime = { version = "32.0.0", default-features = false } -pop-primitives = { path = "../primitives", features = ["devnet"], default-features = false } +pop-primitives = { path = "../primitives", default-features = false } [lib] name = "pop_api" @@ -25,7 +24,6 @@ std = [ "ink/std", "pop-primitives/std", "sp-io/std", - "sp-runtime/std", ] assets = ["pop-primitives/assets"] balances = [] diff --git a/pop-api/examples/fungibles/lib.rs b/pop-api/examples/fungibles/lib.rs index 1794fbe5..03841b74 100755 --- a/pop-api/examples/fungibles/lib.rs +++ b/pop-api/examples/fungibles/lib.rs @@ -8,13 +8,13 @@ use ink::prelude::vec::Vec; use pop_api::{ assets::fungibles::{self as api}, - error::StatusCode, - primitives::{AccountId as AccountId32, AssetId}, + primitives::AssetId, + StatusCode, }; pub type Result = core::result::Result; -#[ink::contract(env = pop_api::Environment)] +#[ink::contract] mod fungibles { use super::*; @@ -41,141 +41,84 @@ mod fungibles { #[ink(message)] pub fn total_supply(&self, id: AssetId) -> Result { - // api::total_supply(id).map_err(|e| e.into()) api::total_supply(id) } #[ink(message)] - pub fn balance_of(&self, id: AssetId, owner: AccountId32) -> Result { - // api::balance_of(id, owner).map_err(|e| e.into()) + pub fn balance_of(&self, id: AssetId, owner: AccountId) -> Balance { api::balance_of(id, owner) } #[ink(message)] - pub fn allowance( - &self, - id: AssetId, - owner: AccountId32, - spender: AccountId32, - ) -> Result { - // api::allowance(id, owner, spender).map_err(|e| e.into()) + pub fn allowance(&self, id: AssetId, owner: AccountId, spender: AccountId) -> Balance { api::allowance(id, owner, spender) } #[ink(message)] - pub fn transfer(&self, id: AssetId, to: AccountId32, value: Balance) -> Result<()> { - ink::env::debug_println!( - "PopApiFungiblesExample::transfer: id: {:?}, to: {:?} value: {:?}", - id, - to, - value, - ); - - let result = api::transfer(id, to, value); - ink::env::debug_println!("Result: {:?}", result); - // result.map_err(|e| e.into()) - result + pub fn transfer(&self, id: AssetId, to: AccountId, value: Balance) -> Result<()> { + api::transfer(id, to, value)?; + Ok(()) } #[ink(message)] pub fn transfer_from( &self, id: AssetId, - from: AccountId32, - to: AccountId32, + from: AccountId, + to: AccountId, value: Balance, // In the standard a `[u8]`, but the size needs to be known at compile time. _data: Vec, ) -> Result<()> { - ink::env::debug_println!( - "PopApiFungiblesExample::transfer_from: id: {:?}, from: {:?}, to: {:?} value: {:?}", - id, - from, - to, - value, - ); - - let result = api::transfer_from(id, from, to, value); - ink::env::debug_println!("Result: {:?}", result); - // result.map_err(|e| e.into()) - result + api::transfer_from(id, from, to, value)?; + Ok(()) } #[ink(message)] - pub fn approve(&self, id: AssetId, spender: AccountId32, value: Balance) -> Result<()> { - ink::env::debug_println!( - "PopApiFungiblesExample::approve: id: {:?}, spender {:?}, value: {:?}", - id, - spender, - value, - ); - - let result = api::approve(id, spender, value); - ink::env::debug_println!("Result: {:?}", result); - // result.map_err(|e| e.into()) - result + pub fn approve(&self, id: AssetId, spender: AccountId, value: Balance) -> Result<()> { + api::approve(id, spender, value)?; + Ok(()) } #[ink(message)] pub fn increase_allowance( &self, id: AssetId, - spender: AccountId32, + spender: AccountId, value: Balance, ) -> Result<()> { - ink::env::debug_println!( - "PopApiFungiblesExample::increase_allowance: id: {:?}, spender {:?}, value: {:?}", - id, - spender, - value, - ); - - let result = api::increase_allowance(id, spender, value); - ink::env::debug_println!("Result: {:?}", result); - // result.map_err(|e| e.into()) - result + api::increase_allowance(id, spender, value)?; + Ok(()) } #[ink(message)] pub fn decrease_allowance( &self, id: AssetId, - spender: AccountId32, + spender: AccountId, value: Balance, ) -> Result<()> { - ink::env::debug_println!( - "PopApiFungiblesExample::decrease_allowance: id: {:?}, spender {:?}, value: {:?}", - id, - spender, - value, - ); - - let result = api::decrease_allowance(id, spender, value); - ink::env::debug_println!("Result: {:?}", result); - // result.map_err(|e| e.into()) - result + api::decrease_allowance(id, spender, value)?; + Ok(()) } - /// 2. PSP-22 Metadata Interface: - /// - token_name - /// - token_symbol - /// - token_decimals + // 2. PSP-22 Metadata Interface: + // - token_name + // - token_symbol + // - token_decimals #[ink(message)] - pub fn token_name(&self, id: AssetId) -> Result> { - // api::token_name(id).map_err(|e| e.into()) + pub fn token_name(&self, id: AssetId) -> Vec { api::token_name(id) } #[ink(message)] - pub fn token_symbol(&self, id: AssetId) -> Result> { - // api::token_symbol(id).map_err(|e| e.into()) + pub fn token_symbol(&self, id: AssetId) -> Vec { api::token_symbol(id) } #[ink(message)] - pub fn token_decimals(&self, id: AssetId) -> Result { - // api::token_decimals(id).map_err(|e| e.into()) + pub fn token_decimals(&self, id: AssetId) -> u8 { api::token_decimals(id) } @@ -189,7 +132,7 @@ mod fungibles { // - clear_metadata // #[ink(message)] - // pub fn create(&self, id: AssetId, admin: AccountId32, min_balance: Balance) -> Result<()> { + // pub fn create(&self, id: AssetId, admin: AccountId, min_balance: Balance) -> Result<()> { // ink::env::debug_println!( // "PopApiFungiblesExample::create: id: {:?} admin: {:?} min_balance: {:?}", // id, @@ -198,8 +141,8 @@ mod fungibles { // ); // let result = api::create(id, admin, min_balance); // ink::env::debug_println!("Result: {:?}", result); - // // result.map_err(|e| e.into()) - // result + // result.map_err(|e| e.into()) + // result // } // #[ink(message)] diff --git a/pop-api/integration-tests/Cargo.toml b/pop-api/integration-tests/Cargo.toml index 84769433..c855a884 100644 --- a/pop-api/integration-tests/Cargo.toml +++ b/pop-api/integration-tests/Cargo.toml @@ -10,7 +10,7 @@ frame-support = { version = "29.0.0", default-features = false } frame-system = { version = "29.0.0", default-features = false } pallet-balances = { version = "29.0.2", default-features = false } pallet-contracts = { version = "28.0.0", default-features = false } -pop-api = { path = "../.", default-features = false, features = ["assets"] } +pop-primitives = { path = "../../primitives", default-features = false, features = ["assets"] } pop-runtime-devnet = { path = "../../runtime/devnet", default-features = false } sp-io = { version = "31.0.0", default-features = false } sp-runtime = { version = "32.0.0", default-features = false } @@ -23,7 +23,7 @@ std = [ "frame-system/std", "pallet-balances/std", "pallet-contracts/std", - "pop-api/std", + "pop-primitives/std", "pop-runtime-devnet/std", "scale/std", "sp-io/std", diff --git a/pop-api/integration-tests/src/local_fungibles.rs b/pop-api/integration-tests/src/local_fungibles.rs index 1b3c6633..968c43eb 100644 --- a/pop-api/integration-tests/src/local_fungibles.rs +++ b/pop-api/integration-tests/src/local_fungibles.rs @@ -1,5 +1,5 @@ use super::*; -use pop_api::error::{ +use pop_primitives::error::{ ArithmeticError::*, Error::{self, *}, TokenError::*, @@ -8,7 +8,10 @@ use pop_api::error::{ const ASSET_ID: AssetId = 1; fn decoded(result: ExecReturnValue) -> T { - ::decode(&mut &result.data[2..]).unwrap() + match ::decode(&mut &result.data[2..]) { + Ok(value) => value, + Err(_) => panic!("\nTest failed by trying to decode result: {:?} into `T`\n", result), + } } fn allowance( @@ -78,7 +81,9 @@ fn transfer( ) -> ExecReturnValue { let function = function_selector("transfer"); let params = [function, asset_id.encode(), to.encode(), value.encode()].concat(); - do_bare_call(addr, params, 0).expect("should work") + let result = do_bare_call(addr, params, 0).expect("should work"); + println!("Transfer result: {:?}", result); + result } fn transfer_from( diff --git a/pop-api/src/error.rs b/pop-api/src/error.rs deleted file mode 100644 index 8989464f..00000000 --- a/pop-api/src/error.rs +++ /dev/null @@ -1,335 +0,0 @@ -use ink::{env::chain_extension::FromStatusCode, scale::Decode}; - -#[derive(Debug, PartialEq, Eq)] -#[ink::scale_derive(Encode, Decode, TypeInfo)] -pub struct StatusCode(pub u32); - -impl From for StatusCode { - fn from(value: u32) -> Self { - StatusCode(value) - } -} -impl FromStatusCode for StatusCode { - fn from_status_code(status_code: u32) -> Result<(), Self> { - match status_code { - 0 => Ok(()), - _ => Err(StatusCode(status_code)), - } - } -} - -impl From for StatusCode { - fn from(_: ink::scale::Error) -> Self { - StatusCode(255u32) - } -} - -#[derive(Debug, PartialEq, Eq)] -#[ink::scale_derive(Encode, Decode, TypeInfo)] -#[repr(u8)] -pub enum Error { - /// Some unknown error occurred. Go to the Pop API docs section `Pop API error`. - Other { - // Index within the `DispatchError` - dispatch_error_index: u8, - // Index within the `DispatchError` variant. - error_index: u8, - // Index for further nesting, e.g. pallet error. - error: u8, - } = 0, - /// Failed to lookup some data. - CannotLookup = 1, - /// A bad origin. - BadOrigin = 2, - /// A custom error in a module. - Module { - index: u8, - error: u8, - } = 3, - /// At least one consumer is remaining so the account cannot be destroyed. - ConsumerRemaining = 4, - /// There are no providers so the account cannot be created. - NoProviders = 5, - /// There are too many consumers so the account cannot be created. - TooManyConsumers = 6, - /// An error to do with tokens. - Token(TokenError) = 7, - /// An arithmetic error. - Arithmetic(ArithmeticError) = 8, - /// The number of transactional layers has been reached, or we are not in a transactional - /// layer. - Transactional(TransactionalError) = 9, - /// Resources exhausted, e.g. attempt to read/write data which is too large to manipulate. - Exhausted = 10, - /// The state is corrupt; this is generally not going to fix itself. - Corruption = 11, - /// Some resource (e.g. a preimage) is unavailable right now. This might fix itself later. - Unavailable = 12, - /// Root origin is not allowed. - RootNotAllowed = 13, - UnknownFunctionId = 254, - DecodingFailed = 255, -} - -#[cfg(test)] -impl From for StatusCode { - fn from(value: Error) -> Self { - let mut encoded_error = value.encode(); - // Resize the encoded value to 4 bytes in order to decode the value in a u32 (4 bytes). - encoded_error.resize(4, 0); - StatusCode::from( - u32::decode(&mut &encoded_error[..]).expect("qid, resized to 4 bytes line above"), - ) - } -} - -impl From for Error { - fn from(value: StatusCode) -> Self { - let mut encoded: [u8; 4] = value.0.to_le_bytes(); - match Error::decode(&mut &encoded[..]) { - Err(_) => { - encoded[..].rotate_right(1); - encoded[0] = 0u8; - Error::decode(&mut &encoded[..]).unwrap_or(Error::DecodingFailed) - }, - Ok(error) => error, - } - } -} - -#[derive(Debug, PartialEq, Eq)] -#[ink::scale_derive(Encode, Decode, TypeInfo)] -pub enum TokenError { - /// Funds are unavailable. - FundsUnavailable, - /// Some part of the balance gives the only provider reference to the account and thus cannot - /// be (re)moved. - OnlyProvider, - /// Account cannot exist with the funds that would be given. - BelowMinimum, - /// Account cannot be created. - CannotCreate, - /// The asset in question is unknown. - UnknownAsset, - /// Funds exist but are frozen. - Frozen, - /// Operation is not supported by the asset. - Unsupported, - /// Account cannot be created for a held balance. - CannotCreateHold, - /// Withdrawal would cause unwanted loss of account. - NotExpendable, - /// Account cannot receive the assets. - Blocked, -} - -#[derive(Debug, PartialEq, Eq)] -#[ink::scale_derive(Encode, Decode, TypeInfo)] -pub enum ArithmeticError { - /// Underflow. - Underflow, - /// Overflow. - Overflow, - /// Division by zero. - DivisionByZero, -} - -#[derive(Debug, PartialEq, Eq)] -#[ink::scale_derive(Encode, Decode, TypeInfo)] -pub enum TransactionalError { - /// Too many transactional layers have been spawned. - LimitReached, - /// A transactional layer was expected, but does not exist. - NoLayer, -} - -#[cfg(test)] -mod tests { - use super::*; - use crate::error::{ArithmeticError::*, TokenError::*, TransactionalError::*}; - - #[test] - fn u32_always_encodes_to_4_bytes() { - assert_eq!(0u32.encode().len(), 4); - assert_eq!(u32::MAX.encode().len(), 4); - } - - // Decodes 4 bytes into a `u32` and converts it into `StatusCode`. - fn into_status_code(encoded_error: [u8; 4]) -> StatusCode { - let decoded_u32 = u32::decode(&mut &encoded_error[..]).unwrap(); - StatusCode::from_status_code(decoded_u32).unwrap_err() - } - - // Decodes 4 bytes into a `u32` and converts it into `Error`. - fn into_error(encoded_error: [u8; 4]) -> Error { - let decoded_u32 = u32::decode(&mut &encoded_error[..]).unwrap(); - let status_code = StatusCode::from_status_code(decoded_u32).unwrap_err(); - status_code.into() - } - - // Tests the `From` implementation for `Error`. - // - // Unit variants: - // If the encoded value indicates a nested `Error` which is known by the Pop API version as a - // unit variant, the encoded value is converted into `Error::Other`. - // - // Example: the error `BadOrigin` (encoded: `[2, 0, 0, 0]`) with a non-zero value for one - // of the bytes [1..4]: `[2, 0, 1, 0]` is converted into `[0, 2, 0, 1]`. This is decoded to - // `Error::Other { dispatch_error: 2, index: 0, error: 1 }`. - #[test] - fn unit_error_variants() { - let errors = vec![ - CannotLookup, - BadOrigin, - ConsumerRemaining, - NoProviders, - TooManyConsumers, - Exhausted, - Corruption, - Unavailable, - RootNotAllowed, - DecodingFailed, - ]; - // Four scenarios, 2 tests each: - // 1. Compare a `StatusCode`, which is converted from an encoded value, with a `StatusCode` - // converted from an `Error`. - // 2. Compare an `Error, which is converted from an encoded value, with the expected `Error`. - for (i, &error_code) in UNIT_ERRORS.iter().enumerate() { - // No nesting and unit variant correctly returned. - assert_eq!(into_status_code([error_code, 0, 0, 0]), errors[i].into()); - assert_eq!(into_error([error_code, 0, 0, 0]), errors[i]); - // Unexpected second byte nested. - assert_eq!( - into_status_code([error_code, 1, 0, 0]), - (Other { dispatch_error_index: error_code, error_index: 1, error: 0 }).into(), - ); - assert_eq!(into_error([error_code, 1, 0, 0]), errors[i]); - // Unexpected third byte nested. - assert_eq!( - into_status_code([error_code, 1, 1, 0]), - (Other { dispatch_error_index: error_code, error_index: 1, error: 1 }).into(), - ); - assert_eq!(into_error([error_code, 1, 1, 0]), errors[i]); - // Unexpected fourth byte nested. - assert_eq!( - into_status_code([error_code, 1, 1, 1]), - (Other { dispatch_error_index: error_code, error_index: 1, error: 1 }).into(), - ); - assert_eq!(into_error([error_code, 1, 1, 1]), errors[i]); - } - } - - // Single nested variants: - // If the encoded value indicates a double nested `Error` which is known by the Pop API version - // as a single nested variant, the encoded value is converted into `Error::Other`. - // - // Example: the error `Arithmetic(Overflow)` (encoded: `[8, 1, 0, 0]`) with a non-zero - // value for one of the bytes [2..4]: `[8, 1, 1, 0]` is converted into `[0, 8, 1, 1]`. This is - // decoded to `Error::Other { dispatch_error: 8, index: 1, error: 1 }`. - #[test] - fn single_nested_error_variants() { - let errors = vec![ - [Token(FundsUnavailable), Token(OnlyProvider)], - [Arithmetic(Underflow), Arithmetic(Overflow)], - [Transactional(LimitReached), Transactional(NoLayer)], - ]; - // Four scenarios, 2 tests each: - // 1. Compare a `StatusCode`, which is converted from an encoded value, with a `StatusCode` - // converted from an `Error`. - // 2. Compare an `Error, which is converted from an encoded value, with the expected `Error`. - for (i, &error_code) in SINGLE_NESTED_ERRORS.iter().enumerate() { - // No nesting and unit variant correctly returned. - assert_eq!(into_status_code([error_code, 0, 0, 0]), errors[i][0].into()); - assert_eq!(into_error([error_code, 0, 0, 0]), errors[i][0]); - // Allowed single nesting variant correctly returned. - assert_eq!(into_status_code([error_code, 1, 0, 0]), errors[i][1].into()); - assert_eq!(into_error([error_code, 1, 0, 0]), errors[i][1]); - // Unexpected third byte nested. - assert_eq!( - into_status_code([error_code, 1, 1, 0]), - (Other { dispatch_error_index: error_code, error_index: 1, error: 1 }).into(), - ); - assert_eq!(into_error([error_code, 1, 1, 0]), errors[i][1]); - // Unexpected fourth byte nested. - assert_eq!( - into_status_code([error_code, 1, 1, 1]), - (Other { dispatch_error_index: error_code, error_index: 1, error: 1 }).into(), - ); - assert_eq!(into_error([error_code, 1, 1, 1]), errors[i][1]); - } - } - - // Double nested variants: - // If the encoded value indicates a triple nested `Error` which is known by the Pop API version - // as a double nested variant, the encoded value is converted into `Error::Other`. - // - // Example: the error `Module { index: 10, error 5 }` (encoded: `[3, 10, 5, 0]`) with a non-zero - // value for the last byte: `[3, 10, 5, 3]` is converted into `[0, 3, 10, 5]`. This is - // decoded to `Error::Other { dispatch_error: 3, index: 10, error: 5 }`. - #[test] - fn double_nested_error_variants() { - // Four scenarios, 2 tests each: - // 1. Compare a `StatusCode`, which is converted from an encoded value, with a `StatusCode` - // converted from an `Error`. - // 2. Compare an `Error, which is converted from an encoded value, with the expected `Error`. - // - // No nesting and unit variant correctly returned. - assert_eq!(into_status_code([3, 0, 0, 0]), (Module { index: 0, error: 0 }).into()); - assert_eq!(into_error([3, 0, 0, 0]), Module { index: 0, error: 0 }); - // Allowed single nesting and variant correctly returned. - assert_eq!(into_status_code([3, 1, 0, 0]), (Module { index: 1, error: 0 }).into()); - assert_eq!(into_error([3, 1, 0, 0]), Module { index: 1, error: 0 }); - // Allowed double nesting and variant correctly returned. - assert_eq!(into_status_code([3, 1, 1, 0]), (Module { index: 1, error: 1 }).into()); - assert_eq!(into_error([3, 1, 1, 0]), Module { index: 1, error: 1 }); - // Unexpected fourth byte nested. - assert_eq!( - into_status_code([3, 1, 1, 1]), - (Other { dispatch_error_index: 3, error_index: 1, error: 1 }).into(), - ); - assert_eq!(into_error([3, 1, 1, 1]), Module { index: 1, error: 1 }); - } - - #[test] - fn single_nested_unknown_variants() { - // Unknown `TokenError` variant. - assert_eq!( - into_error([7, 10, 0, 0]), - Other { dispatch_error_index: 7, error_index: 10, error: 0 } - ); - assert_eq!( - into_status_code([7, 10, 0, 0]), - Other { dispatch_error_index: 7, error_index: 10, error: 0 }.into() - ); - // Unknown `Arithmetic` variant. - assert_eq!( - into_error([8, 3, 0, 0]), - Other { dispatch_error_index: 8, error_index: 3, error: 0 } - ); - assert_eq!( - into_status_code([8, 3, 0, 0]), - Other { dispatch_error_index: 8, error_index: 3, error: 0 }.into() - ); - // Unknown `Transactional` variant. - assert_eq!( - into_error([9, 2, 0, 0]), - Other { dispatch_error_index: 9, error_index: 2, error: 0 } - ); - assert_eq!( - into_status_code([9, 2, 0, 0]), - Other { dispatch_error_index: 9, error_index: 2, error: 0 }.into() - ); - } - - #[test] - fn test_random_encoded_values() { - assert_eq!( - into_error([100, 100, 100, 100]), - Other { dispatch_error_index: 100, error_index: 100, error: 100 } - ); - assert_eq!( - into_error([200, 200, 200, 200]), - Other { dispatch_error_index: 200, error_index: 200, error: 200 } - ); - } -} diff --git a/pop-api/src/lib.rs b/pop-api/src/lib.rs index 55307f3e..cb27b17f 100644 --- a/pop-api/src/lib.rs +++ b/pop-api/src/lib.rs @@ -1,10 +1,8 @@ #![cfg_attr(not(feature = "std"), no_std, no_main)] -use ink::{prelude::vec::Vec, ChainExtensionInstance}; -pub use sp_runtime::MultiAddress; +use ink::env::{chain_extension::FromStatusCode, DefaultEnvironment, Environment}; +use primitives::error::Error; -use crate::error::StatusCode; -use primitives::{storage_keys::*, AccountId as AccountId32}; #[cfg(feature = "assets")] pub use v0::assets; #[cfg(feature = "balances")] @@ -13,72 +11,49 @@ pub use v0::balances; pub use v0::cross_chain; #[cfg(feature = "nfts")] pub use v0::nfts; -use v0::{state, RuntimeCall}; -pub mod error; pub mod primitives; pub mod v0; -type AccountId = AccountId32; -// TODO: do the same as the AccountId above and check expanded macro code. -type Balance = ::Balance; +type AccountId = ::AccountId; +type Balance = ::Balance; #[cfg(any(feature = "nfts", feature = "cross-chain"))] -type BlockNumber = ::BlockNumber; +type BlockNumber = ::BlockNumber; pub type Result = core::result::Result; -#[derive(Debug, PartialEq, Eq, Clone)] +#[derive(Debug, Copy, Clone, PartialEq, Eq)] #[ink::scale_derive(Encode, Decode, TypeInfo)] -pub enum Environment {} +pub struct StatusCode(pub u32); -impl ink::env::Environment for Environment { - const MAX_EVENT_TOPICS: usize = - ::MAX_EVENT_TOPICS; - - type AccountId = ::AccountId; - type Balance = ::Balance; - type Hash = ::Hash; - type BlockNumber = ::BlockNumber; - type Timestamp = ::Timestamp; - - type ChainExtension = PopApi; +impl From for StatusCode { + fn from(value: u32) -> Self { + StatusCode(value) + } } - -#[ink::chain_extension(extension = 909)] -pub trait PopApi { - type ErrorCode = StatusCode; - - #[ink(function = 0)] - #[allow(private_interfaces)] - fn dispatch(call: RuntimeCall) -> Result<()>; - - #[ink(function = 1)] - #[allow(private_interfaces)] - fn read_state(key: RuntimeStateKeys) -> Result>; - - #[cfg(feature = "cross-chain")] - #[ink(function = 2)] - #[allow(private_interfaces)] - fn send_xcm(xcm: primitives::cross_chain::CrossChainMessage) -> Result<()>; +impl FromStatusCode for StatusCode { + fn from_status_code(status_code: u32) -> Result<()> { + match status_code { + 0 => Ok(()), + _ => Err(StatusCode(status_code)), + } + } } -#[inline] -fn dispatch(call: RuntimeCall) -> Result<()> { - <::ChainExtension as ChainExtensionInstance>::instantiate( - ) - .dispatch(call) +impl From for StatusCode { + fn from(_: ink::scale::Error) -> Self { + StatusCode(255u32) + } } -#[inline] -fn read_state(key: RuntimeStateKeys) -> Result> { - <::ChainExtension as ChainExtensionInstance>::instantiate( - ) - .read_state(key) +impl From for Error { + fn from(value: StatusCode) -> Self { + value.0.into() + } } -#[cfg(feature = "cross-chain")] -fn send_xcm(xcm: primitives::cross_chain::CrossChainMessage) -> Result<()> { - <::ChainExtension as ChainExtensionInstance>::instantiate( - ) - .send_xcm(xcm) +impl From for StatusCode { + fn from(value: Error) -> Self { + StatusCode::from(u32::from(value)) + } } diff --git a/pop-api/src/primitives.rs b/pop-api/src/primitives.rs index 17419d5b..e174a111 100644 --- a/pop-api/src/primitives.rs +++ b/pop-api/src/primitives.rs @@ -1,2 +1 @@ pub use pop_primitives::*; -pub use sp_runtime::MultiAddress; diff --git a/pop-api/src/v0/assets/fungibles.rs b/pop-api/src/v0/assets/fungibles.rs index 376ca898..8d0de768 100644 --- a/pop-api/src/v0/assets/fungibles.rs +++ b/pop-api/src/v0/assets/fungibles.rs @@ -1,12 +1,6 @@ use ink::prelude::vec::Vec; -use crate::{ - assets, - primitives::{AssetId, MultiAddress}, - AccountId, Balance, StatusCode, -}; - -type Result = core::result::Result; +use crate::{assets, primitives::AssetId, AccountId, Balance, Result, StatusCode}; /// Local Fungibles: /// 1. PSP-22 Interface @@ -45,7 +39,7 @@ pub fn total_supply(id: AssetId) -> Result { /// # Returns /// The balance of the specified account, or an error if the operation fails. #[inline] -pub fn balance_of(id: AssetId, owner: AccountId) -> Result { +pub fn balance_of(id: AssetId, owner: AccountId) -> Balance { assets::balance_of(id, owner) } @@ -60,7 +54,7 @@ pub fn balance_of(id: AssetId, owner: AccountId) -> Result { /// # Returns /// The remaining allowance, or an error if the operation fails. #[inline] -pub fn allowance(id: AssetId, owner: AccountId, spender: AccountId) -> Result { +pub fn allowance(id: AssetId, owner: AccountId, spender: AccountId) -> Balance { assets::allowance(id, owner, spender) } @@ -75,11 +69,7 @@ pub fn allowance(id: AssetId, owner: AccountId, spender: AccountId) -> Result>, - value: Balance, -) -> Result<()> { +pub fn transfer(id: AssetId, to: AccountId, value: Balance) -> Result<()> { assets::transfer(id, to, value) } @@ -96,12 +86,7 @@ pub fn transfer( /// # Returns /// Returns `Ok(())` if successful, or an error if the transfer fails. #[inline] -pub fn transfer_from( - id: AssetId, - from: impl Into>, - to: impl Into>, - value: Balance, -) -> Result<()> { +pub fn transfer_from(id: AssetId, from: AccountId, to: AccountId, value: Balance) -> Result<()> { assets::transfer_approved(id, from, to, value) } @@ -161,7 +146,7 @@ pub fn decrease_allowance(id: AssetId, spender: AccountId, value: Balance) -> Re /// # Returns /// The name of the token as a byte vector, or an error if the operation fails. #[inline] -pub fn token_name(id: AssetId) -> Result> { +pub fn token_name(id: AssetId) -> Vec { assets::token_name(id) } @@ -173,7 +158,7 @@ pub fn token_name(id: AssetId) -> Result> { /// # Returns /// The symbol of the token as a byte vector, or an error if the operation fails. #[inline] -pub fn token_symbol(id: AssetId) -> Result> { +pub fn token_symbol(id: AssetId) -> Vec { assets::token_symbol(id) } @@ -185,7 +170,7 @@ pub fn token_symbol(id: AssetId) -> Result> { /// # Returns /// The number of decimals of the token as a byte vector, or an error if the operation fails. #[inline] -pub fn token_decimals(id: AssetId) -> Result { +pub fn token_decimals(id: AssetId) -> u8 { assets::token_decimals(id) } @@ -291,6 +276,7 @@ pub fn token_decimals(id: AssetId) -> Result { // assets::asset_exists(id) // } +// TODO: further implement the rest of the interfaces and conclude on the FungiblesError. #[derive(Debug, PartialEq, Eq)] #[ink::scale_derive(Encode, Decode, TypeInfo)] pub enum FungiblesError { @@ -311,13 +297,13 @@ pub enum FungiblesError { NoPermission, /// The given asset ID is unknown. Unknown, - // // TODO: - // // - Originally `InsufficientBalance` for the deposit but this would result in the same error - // // as the error when there is insufficient balance for transferring an asset. + // - Originally `InsufficientBalance` for the deposit but this would result in the same error + // as the error when there is insufficient balance for transferring an asset. /// No balance for creation of assets or fees. NoBalance, } +// TODO: include conversions from TokenError and add conversions based on added interfaces. impl From for FungiblesError { fn from(value: StatusCode) -> Self { let encoded = value.0.to_le_bytes(); @@ -339,10 +325,10 @@ impl From for FungiblesError { #[cfg(test)] mod tests { - use scale::Decode; + use ink::scale::Decode; use super::FungiblesError; - use crate::error::{ + use crate::primitives::error::{ ArithmeticError::*, Error::{self, *}, TokenError::*, @@ -355,6 +341,7 @@ mod tests { status_code.into() } + // If we ever want to change the conversion from bytes to `u32`. #[test] fn status_code_vs_encoded() { assert_eq!(u32::decode(&mut &[3u8, 10, 2, 0][..]).unwrap(), 133635u32); @@ -373,6 +360,7 @@ mod tests { Other { dispatch_error_index: 5, error_index: 5, error: 1 }, CannotLookup, BadOrigin, + // `ModuleError` other than assets module. Module { index: 2, error: 5 }, ConsumerRemaining, NoProviders, @@ -384,6 +372,7 @@ mod tests { Corruption, Unavailable, RootNotAllowed, + UnknownFunctionId, DecodingFailed, ]; for error in errors { diff --git a/pop-api/src/v0/assets/mod.rs b/pop-api/src/v0/assets/mod.rs index 241c5020..22657323 100644 --- a/pop-api/src/v0/assets/mod.rs +++ b/pop-api/src/v0/assets/mod.rs @@ -1,17 +1,18 @@ -use ink::{prelude::vec::Vec, scale::Compact}; +use ink::{env::chain_extension::ChainExtensionMethod, prelude::vec::Vec, scale::Decode}; -use crate::{state::read, Balance, RuntimeCall, *}; -use primitives::{AssetId, MultiAddress}; +use crate::{primitives::AssetId, AccountId, Balance, Result, StatusCode}; pub mod fungibles; -type Result = core::result::Result; +const ASSETS_MODULE: u8 = 52; +const VERSION: u8 = 0; /// [Pallet Assets](https://github.com/paritytech/polkadot-sdk/blob/master/substrate/frame/assets/src/lib.rs): /// 1. Dispatchables /// 2. Read state functions /// /// 1. Dispatchables within pallet assets (TrustBackedAssets instance): +const DISPATCH: u8 = 0; /// - create /// - start_destroy /// - destroy_accounts @@ -21,25 +22,12 @@ type Result = core::result::Result; /// - burn /// - transfer /// - transfer_keep_alive -/// - force_transfer -/// - freeze -/// - thaw -/// - freeze_asset -/// - thaw_asset -/// - transfer_ownership -/// - set_team +const TRANSFER_KEEP_ALIVE: u8 = 9; /// - set_metadata /// - clear_metadata /// - approve_transfer /// - cancel_approval -/// - force_cancel_approval /// - transfer_approved -/// - touch -/// - refund -/// - set_min_balance -/// - touch_other -/// - refund_other -/// - block /// Issue a new class of fungible assets from a public origin. // pub(crate) fn create( @@ -98,16 +86,18 @@ type Result = core::result::Result; /// Move some assets from the sender account to another. #[inline] -pub(crate) fn transfer( - id: AssetId, - target: impl Into>, - amount: Balance, -) -> Result<()> { - dispatch(RuntimeCall::Assets(AssetsCall::TransferKeepAlive { - id: id.into(), - target: target.into(), - amount: Compact(amount), - })) +pub fn transfer(id: AssetId, target: AccountId, amount: Balance) -> Result<()> { + ChainExtensionMethod::build(u32::from_le_bytes([ + VERSION, + DISPATCH, + ASSETS_MODULE, + // TODO: E.D. is always respected with transferring tokens via the API. + TRANSFER_KEEP_ALIVE, + ])) + .input::<(AssetId, AccountId, Balance)>() + .output::, true>() + .handle_error_code::() + .call(&(id, target, amount)) } // /// Move some assets from the sender account to another, keeping the sender account alive. @@ -122,68 +112,8 @@ pub(crate) fn transfer( // amount: Compact(amount), // })) // } -// -// /// Move some assets from one account to another. Sender should be the Admin of the asset `id`. -// pub(crate) fn force_transfer( -// id: AssetId, -// source: impl Into>, -// dest: impl Into>, -// amount: Balance, -// ) -> Result<()> { -// dispatch(RuntimeCall::Assets(AssetsCall::ForceTransfer { -// id: id.into(), -// source: source.into(), -// dest: dest.into(), -// amount: Compact(amount), -// })) -// } -// -// /// Disallow further unprivileged transfers of an asset `id` from an account `who`. `who` -// /// must already exist as an entry in `Account`s of the asset. If you want to freeze an -// /// account that does not have an entry, use `touch_other` first. -// pub(crate) fn freeze(id: AssetId, who: impl Into>) -> Result<()> { -// dispatch(RuntimeCall::Assets(AssetsCall::Freeze { id: id.into(), who: who.into() })) -// } -// -// /// Allow unprivileged transfers to and from an account again. -// pub(crate) fn thaw(id: AssetId, who: impl Into>) -> Result<()> { -// dispatch(RuntimeCall::Assets(AssetsCall::Thaw { id: id.into(), who: who.into() })) -// } -// -// /// Disallow further unprivileged transfers for the asset class. -// pub(crate) fn freeze_asset(id: AssetId) -> Result<()> { -// dispatch(RuntimeCall::Assets(AssetsCall::FreezeAsset { id: id.into() })) -// } -// -// /// Allow unprivileged transfers for the asset again. -// pub(crate) fn thaw_asset(id: AssetId) -> Result<()> { -// dispatch(RuntimeCall::Assets(AssetsCall::ThawAsset { id: id.into() })) -// } -// -// /// Change the Owner of an asset. -// pub(crate) fn transfer_ownership(id: AssetId, owner: impl Into>) -> Result<()> { -// dispatch(RuntimeCall::Assets(AssetsCall::TransferOwnership { -// id: id.into(), -// owner: owner.into(), -// })) -// } -// -// /// Change the Issuer, Admin and Freezer of an asset. -// pub(crate) fn set_team( -// id: AssetId, -// issuer: impl Into>, -// admin: impl Into>, -// freezer: impl Into>, -// ) -> Result<()> { -// dispatch(RuntimeCall::Assets(AssetsCall::SetTeam { -// id: id.into(), -// issuer: issuer.into(), -// admin: admin.into(), -// freezer: freezer.into(), -// })) -// } -/// Set the metadata for an asset. +// /// Set the metadata for an asset. // pub(crate) fn set_metadata( // id: AssetId, // name: Vec, @@ -200,315 +130,111 @@ pub(crate) fn transfer( /// Approve an amount of asset for transfer by a delegated third-party account. #[inline] -pub(crate) fn approve_transfer( - id: AssetId, - delegate: impl Into>, - amount: Balance, -) -> Result<()> { - dispatch(RuntimeCall::Assets(AssetsCall::ApproveTransfer { - id: id.into(), - delegate: delegate.into(), - amount: Compact(amount), - })) +pub fn approve_transfer(id: AssetId, delegate: AccountId, amount: Balance) -> Result<()> { + ChainExtensionMethod::build(u32::from_le_bytes([0u8, 0, 52, 69])) + .input::<(AssetId, AccountId, Balance)>() + .output::, true>() + .handle_error_code::() + .call(&(id, delegate, amount)) } /// Cancel all of some asset approved for delegated transfer by a third-party account. #[inline] -pub(crate) fn cancel_approval( - id: AssetId, - delegate: impl Into>, -) -> Result<()> { - dispatch(RuntimeCall::Assets(AssetsCall::CancelApproval { - id: id.into(), - delegate: delegate.into(), - })) +pub fn cancel_approval(id: AssetId, delegate: AccountId) -> Result<()> { + ChainExtensionMethod::build(0) + .input::<(AssetId, AccountId)>() + .output::, true>() + .handle_error_code::() + .call(&(id, delegate)) } -// /// Cancel all of some asset approved for delegated transfer by a third-party account. -// pub(crate) fn force_cancel_approval( -// id: AssetId, -// owner: impl Into>, -// delegate: impl Into>, -// ) -> Result<()> { -// dispatch(RuntimeCall::Assets(AssetsCall::ForceCancelApproval { -// id: id.into(), -// owner: owner.into(), -// delegate: delegate.into(), -// })) -// } - /// Transfer some asset balance from a previously delegated account to some third-party /// account. #[inline] -pub(crate) fn transfer_approved( +pub fn transfer_approved( id: AssetId, - owner: impl Into>, - destination: impl Into>, + from: AccountId, + to: AccountId, amount: Balance, ) -> Result<()> { - dispatch(RuntimeCall::Assets(AssetsCall::TransferApproved { - id: id.into(), - owner: owner.into(), - destination: destination.into(), - amount: Compact(amount), - })) + ChainExtensionMethod::build(0) + .input::<(AssetId, AccountId, AccountId, Balance)>() + .output::, true>() + .handle_error_code::() + .call(&(id, from, to, amount)) } -// -// /// Create an asset account for non-provider assets. -// pub(crate) fn touch(id: AssetId) -> Result<()> { -// dispatch(RuntimeCall::Assets(AssetsCall::Touch { id: id.into() })) -// } -// -// /// Return the deposit (if any) of an asset account or a consumer reference (if any) of an -// /// account. -// pub(crate) fn refund(id: AssetId, allow_burn: bool) -> Result<()> { -// dispatch(RuntimeCall::Assets(AssetsCall::Refund { id: id.into(), allow_burn })) -// } -// -// /// Sets the minimum balance of an asset. -// pub(crate) fn set_min_balance(id: AssetId, min_balance: Balance) -> Result<()> { -// dispatch(RuntimeCall::Assets(AssetsCall::SetMinBalance { -// id: id.into(), -// min_balance: Compact(min_balance), -// })) -// } -// -// /// Create an asset account for `who`. -// pub(crate) fn touch_other(id: AssetId, who: impl Into>) -> Result<()> { -// dispatch(RuntimeCall::Assets(AssetsCall::TouchOther { id: id.into(), who: who.into() })) -// } -// -// /// Return the deposit (if any) of a target asset account. Useful if you are the depositor. -// pub(crate) fn refund_other(id: AssetId, who: impl Into>) -> Result<()> { -// dispatch(RuntimeCall::Assets(AssetsCall::RefundOther { id: id.into(), who: who.into() })) -// } -// -// /// Disallow further unprivileged transfers of an asset `id` to and from an account `who`. -// pub(crate) fn block(id: AssetId, who: impl Into>) -> Result<()> { -// dispatch(RuntimeCall::Assets(AssetsCall::Block { id: id.into(), who: who.into() })) -// } /// 2. Read state functions +const READ_STATE: u8 = 1; /// - total_supply +const TOTAL_SUPPLY: u8 = 0; /// - balance_of /// - allowance /// - asset_exists /// - token_name /// - token_symbol /// - token_decimals -// + #[inline] -pub(crate) fn total_supply(id: AssetId) -> Result { - read(RuntimeStateKeys::Assets(AssetsKeys::TotalSupply(id))) +pub fn total_supply(id: AssetId) -> Result { + ChainExtensionMethod::build(u32::from_le_bytes([ + VERSION, + READ_STATE, + ASSETS_MODULE, + TOTAL_SUPPLY, + ])) + .input::() + .output::>, true>() + .handle_error_code::() + .call(&(id)) + .and_then(|v| Balance::decode(&mut &v[..]).map_err(|_e| StatusCode(255u32))) } #[inline] -pub(crate) fn balance_of(id: AssetId, owner: AccountId) -> Result { - read(RuntimeStateKeys::Assets(AssetsKeys::BalanceOf(id, owner))) +pub fn balance_of(id: AssetId, owner: AccountId) -> Balance { + ChainExtensionMethod::build(1) + .input::<(AssetId, AccountId)>() + .output::() + .ignore_error_code() + .call(&(id, owner)) } #[inline] -pub(crate) fn allowance(id: AssetId, owner: AccountId, spender: AccountId) -> Result { - read(RuntimeStateKeys::Assets(AssetsKeys::Allowance(id, owner, spender))) +pub fn allowance(id: AssetId, owner: AccountId, spender: AccountId) -> Balance { + ChainExtensionMethod::build(1) + .input::<(AssetId, AccountId, AccountId)>() + .output::() + .ignore_error_code() + .call(&(id, owner, spender)) } -// pub(crate) fn asset_exists(id: AssetId) -> Result { -// state::read(RuntimeStateKeys::Assets(AssetsKeys::AssetExists(id))) -// } #[inline] -pub(crate) fn token_name(id: AssetId) -> Result> { - read(RuntimeStateKeys::Assets(AssetsKeys::TokenName(id))) +pub fn token_name(id: AssetId) -> Vec { + ChainExtensionMethod::build(1) + .input::() + .output::, false>() + .ignore_error_code() + .call(&(id)) } // #[inline] -pub(crate) fn token_symbol(id: AssetId) -> Result> { - read(RuntimeStateKeys::Assets(AssetsKeys::TokenSymbol(id))) +pub fn token_symbol(id: AssetId) -> Vec { + ChainExtensionMethod::build(1) + .input::() + .output::, false>() + .ignore_error_code() + .call(&(id)) } #[inline] -pub(crate) fn token_decimals(id: AssetId) -> Result { - read(RuntimeStateKeys::Assets(AssetsKeys::TokenDecimals(id))) +pub fn token_decimals(id: AssetId) -> u8 { + ChainExtensionMethod::build(1) + .input::() + .output::() + .ignore_error_code() + .call(&(id)) } -// Parameters to extrinsics representing an asset id (`AssetIdParameter`) and a balance amount (`Balance`) are expected -// to be compact encoded. The pop api handles that for the developer. -// -// reference: https://substrate.stackexchange.com/questions/1873/what-is-the-meaning-of-palletcompact-in-pallet-development -// -// Asset id that is compact encoded. -type AssetIdParameter = Compact; -// Balance amount that is compact encoded. -type BalanceParameter = Compact; -// -#[derive(Debug, PartialEq, Eq)] -#[ink::scale_derive(Encode, Decode, TypeInfo)] -pub(crate) enum AssetsCall { - // #[codec(index = 0)] - // Create { id: AssetIdParameter, admin: MultiAddress, min_balance: Balance }, - // #[codec(index = 2)] - // StartDestroy { id: AssetIdParameter }, - // #[codec(index = 3)] - // DestroyAccounts { id: AssetIdParameter }, - // #[codec(index = 4)] - // DestroyApprovals { id: AssetIdParameter }, - // #[codec(index = 5)] - // FinishDestroy { id: AssetIdParameter }, - // #[codec(index = 6)] - // Mint { - // id: AssetIdParameter, - // beneficiary: MultiAddress, - // amount: BalanceParameter, - // }, - // #[codec(index = 7)] - // Burn { id: AssetIdParameter, who: MultiAddress, amount: BalanceParameter }, - // #[codec(index = 8)] - // Transfer { id: AssetIdParameter, target: MultiAddress, amount: BalanceParameter }, - #[codec(index = 9)] - TransferKeepAlive { - id: AssetIdParameter, - target: MultiAddress, - amount: BalanceParameter, - }, - // #[codec(index = 10)] - // ForceTransfer { - // id: AssetIdParameter, - // source: MultiAddress, - // dest: MultiAddress, - // amount: BalanceParameter, - // }, - // #[codec(index = 11)] - // Freeze { id: AssetIdParameter, who: MultiAddress }, - // #[codec(index = 12)] - // Thaw { id: AssetIdParameter, who: MultiAddress }, - // #[codec(index = 13)] - // FreezeAsset { id: AssetIdParameter }, - // #[codec(index = 14)] - // ThawAsset { id: AssetIdParameter }, - // #[codec(index = 15)] - // TransferOwnership { id: AssetIdParameter, owner: MultiAddress }, - // #[codec(index = 16)] - // SetTeam { - // id: AssetIdParameter, - // issuer: MultiAddress, - // admin: MultiAddress, - // freezer: MultiAddress, - // }, - // #[codec(index = 17)] - // SetMetadata { id: AssetIdParameter, name: Vec, symbol: Vec, decimals: u8 }, - // #[codec(index = 18)] - // ClearMetadata { id: AssetIdParameter }, - #[codec(index = 22)] - ApproveTransfer { - id: AssetIdParameter, - delegate: MultiAddress, - amount: BalanceParameter, - }, - #[codec(index = 23)] - CancelApproval { id: AssetIdParameter, delegate: MultiAddress }, - // #[codec(index = 24)] - // ForceCancelApproval { - // id: AssetIdParameter, - // owner: MultiAddress, - // delegate: MultiAddress, - // }, - #[codec(index = 25)] - TransferApproved { - id: AssetIdParameter, - owner: MultiAddress, - destination: MultiAddress, - amount: BalanceParameter, - }, - // // #[codec(index = 26)] - // // Touch { id: AssetIdParameter }, - // // #[codec(index = 27)] - // // Refund { id: AssetIdParameter, allow_burn: bool }, - // // #[codec(index = 28)] - // // SetMinBalance { id: AssetIdParameter, min_balance: BalanceParameter }, - // // #[codec(index = 29)] - // // TouchOther { id: AssetIdParameter, who: MultiAddress }, - // // #[codec(index = 30)] - // // RefundOther { id: AssetIdParameter, who: MultiAddress }, - // // #[codec(index = 31)] - // // Block { id: AssetIdParameter, who: MultiAddress }, - // } - - // // TODO: Not being used atm but necessary if we want to provide access to the - // // rest of the pallet, outside of the use cases. - // #[derive(Debug, Copy, Clone, PartialEq, Eq, Encode, scale::Decode)] - // #[cfg_attr(feature = "std", derive(scale_info::TypeInfo))] - // pub enum AssetsError { - // /// Account balance must be greater than or equal to the transfer amount. - // BalanceLow, - // /// The account to alter does not exist. - // NoAccount, - // /// The signing account has no permission to do the operation. - // NoPermission, - // /// The given asset ID is unknown. - // Unknown, - // /// The origin account is frozen. - // Frozen, - // /// The asset ID is already taken. - // InUse, - // /// Invalid witness data given. - // BadWitness, - // /// Minimum balance should be non-zero. - // MinBalanceZero, - // /// Unable to increment the consumer reference counters on the account. Either no provider - // /// reference exists to allow a non-zero balance of a non-self-sufficient asset, or one - // /// fewer then the maximum number of consumers has been reached. - // UnavailableConsumer, - // /// Invalid metadata given. - // BadMetadata, - // /// No approval exists that would allow the transfer. - // Unapproved, - // /// The source account would not survive the transfer and it needs to stay alive. - // WouldDie, - // /// The asset-account already exists. - // AlreadyExists, - // /// The asset-account doesn't have an associated deposit. - // NoDeposit, - // /// The operation would result in funds being burned. - // WouldBurn, - // /// The asset is a live asset and is actively being used. Usually emit for operations such - // /// as `start_destroy` which require the asset to be in a destroying state. - // LiveAsset, - // /// The asset is not live, and likely being destroyed. - // AssetNotLive, - // /// The asset status is not the expected status. - // IncorrectStatus, - // /// The asset should be frozen before the given operation. - // NotFrozen, - // /// Callback action resulted in error. - // CallbackFailed, -} - -// -// impl TryFrom for AssetsError { -// type Error = Error; -// -// fn try_from(status_code: u32) -> core::result::Result { -// use AssetsError::*; -// match status_code { -// 0 => Ok(BalanceLow), -// 1 => Ok(NoAccount), -// 2 => Ok(NoPermission), -// 3 => Ok(Unknown), -// 4 => Ok(Frozen), -// 5 => Ok(InUse), -// 6 => Ok(BadWitness), -// 7 => Ok(MinBalanceZero), -// 8 => Ok(UnavailableConsumer), -// 9 => Ok(BadMetadata), -// 10 => Ok(Unapproved), -// 11 => Ok(WouldDie), -// 12 => Ok(AlreadyExists), -// 13 => Ok(NoDeposit), -// 14 => Ok(WouldBurn), -// 15 => Ok(LiveAsset), -// 16 => Ok(AssetNotLive), -// 17 => Ok(IncorrectStatus), -// 18 => Ok(NotFrozen), -// _ => todo!(), -// } -// } +// pub(crate) fn asset_exists(id: AssetId) -> Result { +// state::read(RuntimeStateKeys::Assets(AssetsKeys::AssetExists(id))) // } diff --git a/pop-api/src/v0/balances.rs b/pop-api/src/v0/balances.rs index e14e6e32..bf029178 100644 --- a/pop-api/src/v0/balances.rs +++ b/pop-api/src/v0/balances.rs @@ -1,6 +1,9 @@ -use crate::{dispatch, primitives::MultiAddress, v0::RuntimeCall, AccountId, Error, StatusCode}; +use crate::{ + dispatch, primitives::MultiAddress, v0::RuntimeCall, AccountId, PopApiError, + PopApiError::UnknownStatusCode, +}; -type Result = core::result::Result; +type Result = core::result::Result; pub fn transfer_keep_alive( dest: impl Into>, @@ -14,7 +17,7 @@ pub fn transfer_keep_alive( #[derive(scale::Encode)] #[allow(dead_code)] -pub enum BalancesCall { +pub(crate) enum BalancesCall { #[codec(index = 3)] TransferKeepAlive { dest: MultiAddress, @@ -23,11 +26,9 @@ pub enum BalancesCall { }, } -// TODO: Not being used atm but necessary if we want to provide access to the -// rest of the pallet, outside of the use cases. #[derive(Debug, Copy, Clone, PartialEq, Eq, scale::Encode, scale::Decode)] #[cfg_attr(feature = "std", derive(scale_info::TypeInfo))] -pub enum BalancesError { +pub enum Error { /// Vesting balance too high to send value. VestingBalance, /// Account liquidity restrictions prevent withdrawal. @@ -54,11 +55,11 @@ pub enum BalancesError { DeltaZero, } -impl TryFrom for BalancesError { - type Error = Error; +impl TryFrom for Error { + type Error = PopApiError; fn try_from(status_code: u32) -> core::result::Result { - use BalancesError::*; + use Error::*; match status_code { 0 => Ok(VestingBalance), 1 => Ok(LiquidityRestrictions), @@ -72,7 +73,16 @@ impl TryFrom for BalancesError { 9 => Ok(TooManyFreezes), 10 => Ok(IssuanceDeactivated), 11 => Ok(DeltaZero), - _ => todo!(), + _ => Err(UnknownStatusCode(status_code)), + } + } +} + +impl From for Error { + fn from(error: PopApiError) -> Self { + match error { + PopApiError::Balances(e) => e, + _ => panic!("expected balances error"), } } } diff --git a/pop-api/src/v0/cross_chain/mod.rs b/pop-api/src/v0/cross_chain/mod.rs index ad58e0e8..6732c119 100644 --- a/pop-api/src/v0/cross_chain/mod.rs +++ b/pop-api/src/v0/cross_chain/mod.rs @@ -1,16 +1,12 @@ -use crate::{BlockNumber, ParachainSystemKeys, Result, RuntimeStateKeys}; - pub mod coretime; -pub fn relay_chain_block_number() -> Result { - crate::v0::state::read(RuntimeStateKeys::ParachainSystem( - ParachainSystemKeys::LastRelayChainBlockNumber, - )) -} +use crate::{PopApiError::UnknownStatusCode, *}; + +type Result = core::result::Result; #[derive(Debug, Copy, Clone, PartialEq, Eq, scale::Encode, scale::Decode)] #[cfg_attr(feature = "std", derive(scale_info::TypeInfo))] -pub enum CrossChainError { +pub enum Error { /// The desired destination was unreachable, generally because there is a no way of routing /// to it. Unreachable, @@ -66,11 +62,11 @@ pub enum CrossChainError { LocalExecutionIncomplete, } -impl TryFrom for CrossChainError { - type Error = crate::error::Error; +impl TryFrom for Error { + type Error = PopApiError; fn try_from(status_code: u32) -> core::result::Result { - use CrossChainError::*; + use Error::*; match status_code { 0 => Ok(Unreachable), 1 => Ok(SendFailure), @@ -96,7 +92,16 @@ impl TryFrom for CrossChainError { 21 => Ok(InvalidAssetUnknownReserve), 22 => Ok(InvalidAssetUnsupportedReserve), 23 => Ok(TooManyReserves), - _ => todo!(), + _ => Err(UnknownStatusCode(status_code)), + } + } +} + +impl From for Error { + fn from(error: PopApiError) -> Self { + match error { + PopApiError::Xcm(e) => e, + _ => panic!("expected xcm error"), } } } diff --git a/pop-api/src/v0/mod.rs b/pop-api/src/v0/mod.rs index f91c4271..310b360c 100644 --- a/pop-api/src/v0/mod.rs +++ b/pop-api/src/v0/mod.rs @@ -6,18 +6,3 @@ pub mod balances; pub mod cross_chain; #[cfg(feature = "nfts")] pub mod nfts; -pub mod state; - -#[derive(Debug, PartialEq, Eq)] -#[ink::scale_derive(Encode, Decode, TypeInfo)] -pub(crate) enum RuntimeCall { - #[codec(index = 10)] - #[cfg(feature = "balances")] - Balances(balances::BalancesCall), - #[codec(index = 50)] - #[cfg(feature = "nfts")] - Nfts(nfts::NftCalls), - #[codec(index = 52)] - #[cfg(feature = "assets")] - Assets(assets::AssetsCall), -} diff --git a/pop-api/src/v0/nfts.rs b/pop-api/src/v0/nfts.rs index 32539576..e111c8dc 100644 --- a/pop-api/src/v0/nfts.rs +++ b/pop-api/src/v0/nfts.rs @@ -1,21 +1,17 @@ +use super::RuntimeCall; +use crate::{PopApiError::UnknownStatusCode, *}; use ink::prelude::vec::Vec; +use primitives::{ApprovalsLimit, BoundedBTreeMap, KeyLimit, MultiAddress}; +pub use primitives::{CollectionId, ItemId}; use scale::Encode; - -use crate::{ - dispatch, - primitives::{ - nfts::{ApprovalsLimit, CollectionId, ItemId, KeyLimit}, - BoundedBTreeMap, BoundedVec, - }, - state, AccountId, Balance, BlockNumber, MultiAddress, NftsKeys, RuntimeCall, RuntimeStateKeys, - StatusCode, -}; pub use types::*; type Result = core::result::Result; type StringLimit = u32; type MaxTips = u32; +type Result = core::result::Result; + /// Issue a new collection of non-fungible items pub fn create( admin: impl Into>, @@ -524,7 +520,7 @@ pub(crate) enum NftCalls { #[derive(Debug, Copy, Clone, PartialEq, Eq, Encode, scale::Decode)] #[cfg_attr(feature = "std", derive(scale_info::TypeInfo))] -pub enum NftsError { +pub enum Error { /// The signing account has no permission to do the operation. NoPermission, /// The given item ID is unknown. @@ -617,11 +613,11 @@ pub enum NftsError { WitnessRequired, } -impl TryFrom for NftsError { - type Error = crate::error::Error; +impl TryFrom for Error { + type Error = PopApiError; fn try_from(status_code: u32) -> core::result::Result { - use NftsError::*; + use Error::*; match status_code { 0 => Ok(NoPermission), 1 => Ok(UnknownCollection), @@ -668,7 +664,16 @@ impl TryFrom for NftsError { 42 => Ok(WrongNamespace), 43 => Ok(CollectionNotEmpty), 44 => Ok(WitnessRequired), - _ => todo!(), + _ => Err(UnknownStatusCode(status_code)), + } + } +} + +impl From for Error { + fn from(error: PopApiError) -> Self { + match error { + PopApiError::Nfts(e) => e, + _ => panic!("expected nfts error"), } } } @@ -677,7 +682,7 @@ impl TryFrom for NftsError { mod types { use super::*; use crate::{ - primitives::nfts::{CollectionId, ItemId}, + primitives::{CollectionId, ItemId}, Balance, BlockNumber, }; pub use enumflags2::{bitflags, BitFlags}; diff --git a/pop-api/src/v0/state.rs b/pop-api/src/v0/state.rs deleted file mode 100644 index afe48ba8..00000000 --- a/pop-api/src/v0/state.rs +++ /dev/null @@ -1,7 +0,0 @@ -use crate::{error::StatusCode, primitives::storage_keys::RuntimeStateKeys, read_state}; -use ink::scale::Decode; - -#[inline] -pub fn read(key: RuntimeStateKeys) -> crate::Result { - read_state(key).and_then(|v| T::decode(&mut &v[..]).map_err(|_e| StatusCode(255u32))) -} diff --git a/primitives/Cargo.toml b/primitives/Cargo.toml index cb19b0ab..5cbd6d6c 100644 --- a/primitives/Cargo.toml +++ b/primitives/Cargo.toml @@ -6,10 +6,7 @@ edition = "2021" [dependencies] bounded-collections = { version = "0.1", default-features = false } - scale = { package = "parity-scale-codec", version = "3", default-features = false, features = ["derive"] } -scale-decode = { version = "0.10.0", default-features = false, features = ["derive"], optional = true } -scale-encode = { version = "0.5.0", default-features = false, features = ["derive"], optional = true } scale-info = { version = "2.10", default-features = false, features = ["derive"], optional = true } [features] @@ -17,12 +14,8 @@ default = ["std"] std = [ "bounded-collections/std", "scale/std", - "scale-decode/std", - "scale-encode/std", "scale-info/std", ] -devnet = [] -testnet = [] assets = [] cross-chain = [] nfts = [] diff --git a/primitives/src/lib.rs b/primitives/src/lib.rs index dc0a5245..9d31653a 100644 --- a/primitives/src/lib.rs +++ b/primitives/src/lib.rs @@ -3,14 +3,15 @@ pub use bounded_collections::{BoundedBTreeMap, BoundedBTreeSet, BoundedVec}; use scale::{Decode, Encode, MaxEncodedLen}; #[cfg(feature = "std")] -use {scale_decode::DecodeAsType, scale_encode::EncodeAsType, scale_info::TypeInfo}; +use scale_info::TypeInfo; +pub use v0::error; #[cfg(feature = "cross-chain")] pub mod cross_chain; pub mod storage_keys; -#[derive(Encode, Decode, Clone, Debug, MaxEncodedLen, Eq, PartialEq, Ord, PartialOrd)] -#[cfg_attr(feature = "std", derive(TypeInfo, DecodeAsType, EncodeAsType))] +#[derive(Encode, Decode, Debug, MaxEncodedLen, Eq, PartialEq)] +#[cfg_attr(feature = "std", derive(TypeInfo))] pub struct AccountId(pub [u8; 32]); // Identifier for the class of asset. @@ -29,3 +30,120 @@ pub mod nfts { /// The maximum approvals an item could have. pub type ApprovalsLimit = ConstU32<20>; } + +pub mod v0 { + use super::*; + pub mod error { + use super::*; + + #[derive(Encode, Decode, Debug, Eq, PartialEq)] + #[cfg_attr(feature = "std", derive(TypeInfo))] + #[repr(u8)] + pub enum Error { + /// Some unknown error occurred. Go to the Pop API docs section `Pop API error`. + Other { + // Index within the `DispatchError` + dispatch_error_index: u8, + // Index within the `DispatchError` variant. + error_index: u8, + // Index for further nesting, e.g. pallet error. + error: u8, + } = 0, + /// Failed to lookup some data. + CannotLookup = 1, + /// A bad origin. + BadOrigin = 2, + /// A custom error in a module. + Module { index: u8, error: u8 } = 3, + /// At least one consumer is remaining so the account cannot be destroyed. + ConsumerRemaining = 4, + /// There are no providers so the account cannot be created. + NoProviders = 5, + /// There are too many consumers so the account cannot be created. + TooManyConsumers = 6, + /// An error to do with tokens. + Token(TokenError) = 7, + /// An arithmetic error. + Arithmetic(ArithmeticError) = 8, + /// The number of transactional layers has been reached, or we are not in a transactional + /// layer. + Transactional(TransactionalError) = 9, + /// Resources exhausted, e.g. attempt to read/write data which is too large to manipulate. + Exhausted = 10, + /// The state is corrupt; this is generally not going to fix itself. + Corruption = 11, + /// Some resource (e.g. a preimage) is unavailable right now. This might fix itself later. + Unavailable = 12, + /// Root origin is not allowed. + RootNotAllowed = 13, + /// Unknown function id. + UnknownFunctionId = 254, + /// Decoding failed on the runtime. + DecodingFailed = 255, + } + + impl From for Error { + fn from(value: u32) -> Self { + let encoded = value.to_le_bytes(); + Error::decode(&mut &encoded[..]).unwrap_or(Error::DecodingFailed) + } + } + + impl From for u32 { + fn from(value: Error) -> Self { + let mut encoded_error = value.encode(); + // Resize the encoded value to 4 bytes in order to decode the value in a u32 (4 bytes). + encoded_error.resize(4, 0); + u32::from_le_bytes( + encoded_error.try_into().expect("qid, resized to 4 bytes line above"), + ) + } + } + + #[derive(Encode, Decode, Clone, Debug, MaxEncodedLen, Eq, PartialEq, Ord, PartialOrd)] + #[cfg_attr(feature = "std", derive(TypeInfo))] + pub enum TokenError { + /// Funds are unavailable. + FundsUnavailable, + /// Some part of the balance gives the only provider reference to the account and thus cannot + /// be (re)moved. + OnlyProvider, + /// Account cannot exist with the funds that would be given. + BelowMinimum, + /// Account cannot be created. + CannotCreate, + /// The asset in question is unknown. + UnknownAsset, + /// Funds exist but are frozen. + Frozen, + /// Operation is not supported by the asset. + Unsupported, + /// Account cannot be created for a held balance. + CannotCreateHold, + /// Withdrawal would cause unwanted loss of account. + NotExpendable, + /// Account cannot receive the assets. + Blocked, + } + + #[derive(Encode, Decode, Debug, Eq, PartialEq)] + #[cfg_attr(feature = "std", derive(TypeInfo))] + pub enum ArithmeticError { + /// Underflow. + Underflow, + /// Overflow. + Overflow, + /// Division by zero. + DivisionByZero, + } + + #[derive(Encode, Decode, Debug, Eq, PartialEq)] + #[cfg_attr(feature = "std", derive(TypeInfo))] + pub enum TransactionalError { + /// Too many transactional layers have been spawned. + LimitReached, + /// A transactional layer was expected, but does not exist. + NoLayer, + } + } +} diff --git a/primitives/src/storage_keys.rs b/primitives/src/storage_keys.rs index 7992089b..e42dbca0 100644 --- a/primitives/src/storage_keys.rs +++ b/primitives/src/storage_keys.rs @@ -46,14 +46,11 @@ pub enum NftsKeys { #[cfg(feature = "assets")] #[derive(Encode, Decode, Debug, MaxEncodedLen)] pub enum AssetsKeys { - Allowance(AssetId, AccountId, AccountId), - // /// Check if the asset exists. - // // AssetExists(AssetId), - /// Check balance. - BalanceOf(AssetId, AccountId), - /// Returns the total token supply for a given asset ID. TotalSupply(AssetId), - TokenDecimals(AssetId), - TokenSymbol(AssetId), + BalanceOf(AssetId, AccountId), + Allowance(AssetId, AccountId, AccountId), TokenName(AssetId), + TokenSymbol(AssetId), + TokenDecimals(AssetId), + // AssetExists(AssetId), } diff --git a/runtime/devnet/Cargo.toml b/runtime/devnet/Cargo.toml index 5f52b855..7db68576 100644 --- a/runtime/devnet/Cargo.toml +++ b/runtime/devnet/Cargo.toml @@ -89,8 +89,9 @@ parachain-info.workspace = true [dev-dependencies] env_logger = "0.11.2" -hex = "0.4.3" enumflags2 = "0.7.9" +hex = "0.4.3" +rand = "0.8.5" [features] default = ["std"] diff --git a/runtime/devnet/src/extensions.rs b/runtime/devnet/src/extensions/mod.rs similarity index 79% rename from runtime/devnet/src/extensions.rs rename to runtime/devnet/src/extensions/mod.rs index 6f98bf96..ac52d5bd 100644 --- a/runtime/devnet/src/extensions.rs +++ b/runtime/devnet/src/extensions/mod.rs @@ -1,18 +1,22 @@ +use codec::{Compact, Decode, Encode}; use cumulus_pallet_parachain_system::RelaychainDataProvider; use frame_support::traits::{Contains, OriginTrait}; use frame_support::{ dispatch::{GetDispatchInfo, RawOrigin}, pallet_prelude::*, traits::{ - fungibles::{approvals::Inspect as ApprovalInspect, Inspect}, + fungibles::approvals::Inspect as ApprovalInspect, nonfungibles_v2::Inspect as NonFungiblesInspect, }, }; use pallet_contracts::chain_extension::{ - BufInBufOutState, ChainExtension, ChargedAmount, Environment, Ext, InitState, RetVal, + BufInBufOutState, ChainExtension, Environment, Ext, InitState, RetVal, }; use sp_core::crypto::UncheckedFrom; -use sp_runtime::traits::{BlockNumberProvider, Dispatchable}; +use sp_runtime::{ + traits::{BlockNumberProvider, Dispatchable}, + DispatchError, MultiAddress, +}; use sp_std::{boxed::Box, vec::Vec}; use xcm::{ latest::{prelude::*, OriginKind::SovereignAccount}, @@ -20,17 +24,24 @@ use xcm::{ }; use crate::{ - config::assets::TrustBackedAssetsInstance, AccountId, AllowedApiCalls, RuntimeCall, - RuntimeOrigin, UNIT, + config::assets::TrustBackedAssetsInstance, AccountId, AllowedApiCalls, Balance, Runtime, + RuntimeCall, RuntimeOrigin, UNIT, }; use pop_primitives::{ cross_chain::CrossChainMessage, nfts::{CollectionId, ItemId}, - storage_keys::{AssetsKeys, NftsKeys, ParachainSystemKeys, RuntimeStateKeys}, + storage_keys::{ + AssetsKeys::{self, *}, + NftsKeys, ParachainSystemKeys, RuntimeStateKeys, + }, AssetId, }; +mod v0; + const LOG_TARGET: &str = "pop-api::extension"; +// Versions: +const V0: u8 = 0; type ContractSchedule = ::Schedule; @@ -58,53 +69,162 @@ where { log::debug!(target:LOG_TARGET, " extension called "); let mut env = env.buf_in_buf_out(); - let contract_host_weight = ContractSchedule::::get().host_fn_weights; - // debug_message weight is a good approximation of the additional overhead of going + // Charge weight for making a call from a contract to the runtime. + // `debug_message` weight is a good approximation of the additional overhead of going // from contract layer to substrate layer. // reference: https://github.com/paritytech/ink-examples/blob/b8d2caa52cf4691e0ddd7c919e4462311deb5ad0/psp22-extension/runtime/psp22-extension-example.rs#L236 + let contract_host_weight = ContractSchedule::::get().host_fn_weights; env.charge_weight(contract_host_weight.debug_message)?; - let result = match v0::FuncId::try_from(env.func_id()) { - Ok(function) => { - // calculate weight for reading bytes of `len` + // Extract version and function_id from first two bytes. + let (version, function_id) = { + let bytes = env.func_id().to_le_bytes(); + (bytes[0], bytes[1]) + }; + // Extract pallet index and call / key index from last two bytes. + let (pallet_index, call_index) = { + let bytes = env.ext_id().to_le_bytes(); + (bytes[0], bytes[1]) + }; + + let result = match FuncId::try_from(function_id) { + Ok(function_id) => { + // Read encoded parameters from buffer and calculate weight for reading `len` bytes`. // reference: https://github.com/paritytech/polkadot-sdk/blob/117a9433dac88d5ac00c058c9b39c511d47749d2/substrate/frame/contracts/src/wasm/runtime.rs#L267 let len = env.in_len(); env.charge_weight(contract_host_weight.return_per_byte.saturating_mul(len.into()))?; - match function { - v0::FuncId::Dispatch => dispatch::(&mut env, len), - v0::FuncId::ReadState => read_state::(&mut env), - v0::FuncId::SendXcm => send_xcm::(&mut env), + let params = env.read(len)?; + log::debug!(target: LOG_TARGET, "Read input successfully"); + match function_id { + FuncId::Dispatch => { + dispatch::(&mut env, version, pallet_index, call_index, params) + }, + FuncId::ReadState => { + read_state::(&mut env, version, pallet_index, call_index, params) + }, + // TODO + FuncId::SendXcm => send_xcm::(&mut env), } }, Err(e) => Err(e), }; - // Convert any error to a status code and return Ok with RetVal::Converging match result { Ok(_) => Ok(RetVal::Converging(0)), - Err(e) => Ok(RetVal::Converging(convert_to_status_code(e))), + Err(e) => Ok(RetVal::Converging(convert_to_status_code(e, version))), } } } -fn dispatch(env: &mut Environment, len: u32) -> Result<(), DispatchError> +fn dispatch( + env: &mut Environment, + version: u8, + pallet_index: u8, + call_index: u8, + params: Vec, +) -> Result<(), DispatchError> where - T: pallet_contracts::Config - + frame_system::Config, + T: frame_system::Config, RuntimeOrigin: From>, E: Ext, { const LOG_PREFIX: &str = " dispatch |"; - - // read the input as RuntimeCall - let call: RuntimeCall = env.read_as_unbounded(len)?; - log::debug!(target: LOG_TARGET, "Read input as call successfully"); - // contract is the origin by default + let call = construct_call(version, pallet_index, call_index, params) + .map_err(|_| DispatchError::Other("DecodingFailed"))?; + // Contract is the origin by default. let origin: RuntimeOrigin = RawOrigin::Signed(env.ext().address().clone()).into(); dispatch_call::(env, call, origin, LOG_PREFIX) } -fn read_state(env: &mut Environment) -> Result<(), DispatchError> +fn dispatch_call( + env: &mut Environment, + call: RuntimeCall, + mut origin: RuntimeOrigin, + log_prefix: &str, +) -> Result<(), DispatchError> +where + T: frame_system::Config, + RuntimeOrigin: From>, + E: Ext, +{ + let charged_dispatch_weight = env.charge_weight(call.get_dispatch_info().weight)?; + log::debug!(target:LOG_TARGET, "{} Inputted RuntimeCall: {:?}", log_prefix, call); + origin.add_filter(AllowedApiCalls::contains); + match call.dispatch(origin) { + Ok(info) => { + log::debug!(target:LOG_TARGET, "{} success, actual weight: {:?}", log_prefix, info.actual_weight); + // Refund weight if the actual weight is less than the charged weight. + if let Some(actual_weight) = info.actual_weight { + env.adjust_weight(charged_dispatch_weight, actual_weight); + } + Ok(()) + }, + Err(err) => { + log::debug!(target:LOG_TARGET, "{} failed: error: {:?}", log_prefix, err.error); + Err(err.error) + }, + } +} + +fn construct_call( + version: u8, + pallet_index: u8, + call_index: u8, + params: Vec, +) -> Result { + match pallet_index { + 52 => { + let call = versioned_construct_assets_call(version, call_index, params)?; + Ok(RuntimeCall::Assets(call)) + }, + _ => Err(DispatchError::Other("UnknownFunctionId")), + } +} + +fn construct_key( + version: u8, + pallet_index: u8, + call_index: u8, + params: Vec, +) -> Result { + match pallet_index { + 52 => { + let key = versioned_construct_assets_key(version, call_index, params)?; + Ok(RuntimeStateKeys::Assets(key)) + }, + _ => Err(DispatchError::Other("UnknownFunctionId")), + } +} + +fn versioned_construct_assets_call( + version: u8, + call_index: u8, + params: Vec, +) -> Result, DispatchError> { + match version { + V0 => v0::assets::construct_assets_call(call_index, params), + _ => Err(DispatchError::Other("UnknownFunctionId")), + } +} + +fn versioned_construct_assets_key( + version: u8, + call_index: u8, + params: Vec, +) -> Result { + match version { + V0 => v0::assets::construct_assets_key(call_index, params), + _ => Err(DispatchError::Other("UnknownFunctionId")), + } +} + +fn read_state( + env: &mut Environment, + version: u8, + pallet_index: u8, + call_index: u8, + params: Vec, +) -> Result<(), DispatchError> where T: pallet_contracts::Config + pallet_assets::Config @@ -114,15 +234,13 @@ where E: Ext, { const LOG_PREFIX: &str = " read_state |"; - - let key: RuntimeStateKeys = env.read_as()?; + let key = construct_key(version, pallet_index, call_index, params)?; let result = match key { RuntimeStateKeys::Nfts(key) => read_nfts_state::(key, env), RuntimeStateKeys::ParachainSystem(key) => read_parachain_system_state::(key, env), RuntimeStateKeys::Assets(key) => read_assets_state::(key, env), }? .encode(); - log::trace!( target:LOG_TARGET, "{} result: {:?}.", LOG_PREFIX, result @@ -141,10 +259,9 @@ where E: Ext, { const LOG_PREFIX: &str = " send_xcm |"; - - // read the input as CrossChainMessage + // Read the input as CrossChainMessage. let xc_call: CrossChainMessage = env.read_as::()?; - // Determine the call to dispatch + // Determine the call to dispatch. let (dest, message) = match xc_call { CrossChainMessage::Relay(message) => { let dest = Location::parent().into_versioned(); @@ -165,91 +282,85 @@ where (dest, message) }, }; - // TODO: revisit to replace with signed contract origin let origin: RuntimeOrigin = RawOrigin::Root.into(); - - // Generate runtime call to dispatch + // Generate runtime call to dispatch. let call = RuntimeCall::PolkadotXcm(pallet_xcm::Call::send { dest: Box::new(dest), message: Box::new(VersionedXcm::V4(message)), }); - dispatch_call::(env, call, origin, LOG_PREFIX) } -pub(crate) fn convert_to_status_code(error: DispatchError) -> u32 { +// Converts a `DispatchError` to a `u32` status code based on the version of the API the contract uses. +// The contract calling the chain extension can convert the status code to the descriptive `Error`. +// +// For `Error` see `pop_primitives::::error::Error`. +// +// The error encoding can vary per version, allowing for flexible and backward-compatible error handling. +// As a result, contracts maintain compatibility across different versions of the runtime. +// +// # Parameters +// +// - `error`: The `DispatchError` encountered during contract execution. +// - `version`: The version of the chain extension, used to determine the known errors. +pub(crate) fn convert_to_status_code(error: DispatchError, version: u8) -> u32 { + // "UnknownFunctionId" and "DecodingFailed" are mapped to specific errors in the API and will + // never change. let mut encoded_error = match error { DispatchError::Other("UnknownFunctionId") => vec![254, 0, 0, 0], + DispatchError::Other("DecodingFailed") => vec![255, 0, 0, 0], _ => error.encode(), }; // Resize the encoded value to 4 bytes in order to decode the value in a u32 (4 bytes). encoded_error.resize(4, 0); - u32::decode(&mut &encoded_error[..]).expect("qid, resized to 4 bytes line above") + let mut encoded_error = encoded_error.try_into().expect("qid, resized to 4 bytes line above"); + match version { + // If an unknown variant of the `DispatchError` is detected the error needs to be converted + // into the encoded value of `Error::Other`. This conversion is performed by shifting the bytes one + // position forward (discarding the last byte as it is not used) and setting the first byte to the + // encoded value of `Other` (0u8). This ensures the error is correctly categorized as an `Other` + // variant which provides all the necessary information to debug which error occurred in the runtime. + // + // Byte layout explanation: + // - Byte 0: index of the variant within `Error` + // - Byte 1: + // - Must be zero for `UNIT_ERRORS`. + // - Represents the nested error in `SINGLE_NESTED_ERRORS`. + // - Represents the first level of nesting in `DOUBLE_NESTED_ERRORS`. + // - Byte 2: + // - Represents the second level of nesting in `DOUBLE_NESTED_ERRORS`. + // - Byte 3: + // - Unused or represents further nested information. + 0 => v0::error::handle_unknown_error(&mut encoded_error), + _ => encoded_error = [254, 0, 0, 0], + } + u32::from_le_bytes(encoded_error) } -pub mod v0 { - #[derive(Debug)] - pub enum FuncId { - Dispatch, - ReadState, - SendXcm, - } +#[derive(Debug)] +pub enum FuncId { + Dispatch, + ReadState, + SendXcm, } -impl TryFrom for v0::FuncId { +impl TryFrom for FuncId { type Error = DispatchError; - fn try_from(func_id: u16) -> Result { + fn try_from(func_id: u8) -> Result { let id = match func_id { - 0x0 => Self::Dispatch, - 0x1 => Self::ReadState, - 0x2 => Self::SendXcm, + 0 => Self::Dispatch, + 1 => Self::ReadState, + 2 => Self::SendXcm, _ => { - log::error!("called an unregistered `func_id`: {:}", func_id); return Err(DispatchError::Other("UnknownFuncId")); }, }; - Ok(id) } } -fn dispatch_call( - env: &mut Environment, - call: RuntimeCall, - mut origin: RuntimeOrigin, - log_prefix: &str, -) -> Result<(), DispatchError> -where - T: frame_system::Config, - RuntimeOrigin: From>, - E: Ext, -{ - let charged_dispatch_weight = env.charge_weight(call.get_dispatch_info().weight)?; - - log::debug!(target:LOG_TARGET, "{} Inputted RuntimeCall: {:?}", log_prefix, call); - - origin.add_filter(AllowedApiCalls::contains); - - match call.dispatch(origin) { - Ok(info) => { - log::debug!(target:LOG_TARGET, "{} success, actual weight: {:?}", log_prefix, info.actual_weight); - - // refund weight if the actual weight is less than the charged weight - if let Some(actual_weight) = info.actual_weight { - env.adjust_weight(charged_dispatch_weight, actual_weight); - } - - Ok(()) - }, - Err(err) => { - log::debug!(target:LOG_TARGET, "{} failed: error: {:?}", log_prefix, err.error); - Err(err.error) - }, - } -} - fn read_parachain_system_state( key: ParachainSystemKeys, env: &mut Environment, @@ -323,7 +434,7 @@ where T: frame_system::Config, { match key { - AssetsKeys::Allowance(id, owner, spender) => { + Allowance(id, owner, spender) => { env.charge_weight(T::DbWeight::get().reads(1_u64))?; Ok(pallet_assets::Pallet::::allowance( id, @@ -336,12 +447,12 @@ where // env.charge_weight(T::DbWeight::get().reads(1_u64))?; // Ok(pallet_assets::Pallet::::asset_exists(id).encode()) // }, - AssetsKeys::BalanceOf(id, owner) => { + BalanceOf(id, owner) => { env.charge_weight(T::DbWeight::get().reads(1_u64))?; Ok(pallet_assets::Pallet::::balance(id, &owner.0.into()) .encode()) }, - AssetsKeys::TotalSupply(id) => { + TotalSupply(id) => { env.charge_weight(T::DbWeight::get().reads(1_u64))?; Ok(pallet_assets::Pallet::::total_supply(id).encode()) }, @@ -354,88 +465,51 @@ mod tests { use super::*; use crate::{Assets, Runtime, System}; use sp_runtime::BuildStorage; + // Test ensuring `func_id()` and `ext_id()` work as expected, i.e. extracting the first two + // bytes and the last two bytes, respectively, from a 4 byte array. + #[test] + fn test_byte_extraction() { + use rand::Rng; - fn new_test_ext() -> sp_io::TestExternalities { - let t = frame_system::GenesisConfig::::default() - .build_storage() - .expect("Frame system builds valid default genesis config"); - let mut ext = sp_io::TestExternalities::new(t); - ext.execute_with(|| System::set_block_number(1)); - ext - } + // Helper functions + fn func_id(id: u32) -> u16 { + (id & 0x0000FFFF) as u16 + } + fn ext_id(id: u32) -> u16 { + (id >> 16) as u16 + } - #[test] - fn encoding_decoding_dispatch_error() { - use codec::{Decode, Encode}; - use sp_runtime::{ArithmeticError, DispatchError, ModuleError, TokenError}; + // Number of test iterations + let test_iterations = 1_000_000; - new_test_ext().execute_with(|| { - let error = DispatchError::Module(ModuleError { - index: 255, - error: [2, 0, 0, 0], - message: Some("error message"), - }); - let encoded = error.encode(); - let decoded = DispatchError::decode(&mut &encoded[..]).unwrap(); - assert_eq!(encoded, vec![3, 255, 2, 0, 0, 0]); - assert_eq!( - decoded, - // `message` is skipped for encoding. - DispatchError::Module(ModuleError { - index: 255, - error: [2, 0, 0, 0], - message: None - }) - ); - println!("Encoded Module Error: {:?}", encoded); + // Create a random number generator + let mut rng = rand::thread_rng(); - // Example pallet assets Error into ModuleError. - let index = - <::PalletInfo as frame_support::traits::PalletInfo>::index::< - Assets, - >() - .expect("Every active module has an index in the runtime; qed") as u8; + // Run the test for a large number of random 4-byte arrays + for _ in 0..test_iterations { + // Generate a random 4-byte array + let bytes: [u8; 4] = rng.gen(); - let mut error = - pallet_assets::Error::NotFrozen::.encode(); - error.resize(MAX_MODULE_ERROR_ENCODED_SIZE, 0); - let error = DispatchError::Module(ModuleError { - index, - error: TryInto::try_into(error).expect("should work"), - message: None, - }); - let encoded = error.encode(); - let decoded = DispatchError::decode(&mut &encoded[..]).unwrap(); - assert_eq!(encoded, vec![3, 52, 18, 0, 0, 0]); - assert_eq!( - decoded, - DispatchError::Module(ModuleError { - index: 52, - error: [18, 0, 0, 0], - message: None - }) - ); - println!("Encoded Module Error: {:?}", encoded); + // Convert the 4-byte array to a u32 value + let value = u32::from_le_bytes(bytes); - // Example DispatchError::Token - let error = DispatchError::Token(TokenError::UnknownAsset); - let encoded = error.encode(); - assert_eq!(encoded, vec![7, 4]); - println!("Encoded Token Error: {:?}", encoded); + // Extract the first two bytes (least significant 2 bytes) + let first_two_bytes = func_id(value); - // Example DispatchError::Arithmetic - let error = DispatchError::Arithmetic(ArithmeticError::Overflow); - let encoded = error.encode(); - assert_eq!(encoded, vec![8, 1]); - println!("Encoded Arithmetic Error: {:?}", encoded); - }); + // Extract the last two bytes (most significant 2 bytes) + let last_two_bytes = ext_id(value); + + // Check if the first two bytes match the expected value + assert_eq!([bytes[0], bytes[1]], first_two_bytes.to_le_bytes()); + + // Check if the last two bytes match the expected value + assert_eq!([bytes[2], bytes[3]], last_two_bytes.to_le_bytes()); + } } + // Test showing all the different type of variants and its encoding. #[test] fn encoding_of_enum() { - use codec::{Decode, Encode}; - - // Comprehensive enum with all different type of variants. #[derive(Debug, PartialEq, Encode, Decode)] enum ComprehensiveEnum { SimpleVariant, @@ -494,39 +568,77 @@ mod tests { println!("{:?} -> {:?}", enum_nested_enum_struct, enum_nested_enum_struct.encode()); } + fn new_test_ext() -> sp_io::TestExternalities { + let t = frame_system::GenesisConfig::::default() + .build_storage() + .expect("Frame system builds valid default genesis config"); + let mut ext = sp_io::TestExternalities::new(t); + ext.execute_with(|| System::set_block_number(1)); + ext + } + #[test] - fn dispatch_error_to_status_code() { - // Create all the different `DispatchError` variants with its respective `PopApiError`. - let test_cases = vec![ - (DispatchError::Other("hallo"), [0, 0, 0, 0]), - (DispatchError::CannotLookup, [1, 0, 0, 0]), - (DispatchError::BadOrigin, [2, 0, 0, 0]), - ( - DispatchError::Module(sp_runtime::ModuleError { - index: 1, + fn encoding_decoding_dispatch_error() { + use sp_runtime::{ArithmeticError, DispatchError, ModuleError, TokenError}; + + new_test_ext().execute_with(|| { + let error = DispatchError::Module(ModuleError { + index: 255, + error: [2, 0, 0, 0], + message: Some("error message"), + }); + let encoded = error.encode(); + let decoded = DispatchError::decode(&mut &encoded[..]).unwrap(); + assert_eq!(encoded, vec![3, 255, 2, 0, 0, 0]); + assert_eq!( + decoded, + // `message` is skipped for encoding. + DispatchError::Module(ModuleError { + index: 255, error: [2, 0, 0, 0], - message: Some("hallo"), - }), - [3, 1, 2, 0], - ), - (DispatchError::ConsumerRemaining, [4, 0, 0, 0]), - (DispatchError::NoProviders, [5, 0, 0, 0]), - (DispatchError::TooManyConsumers, [6, 0, 0, 0]), - (DispatchError::Token(sp_runtime::TokenError::BelowMinimum), [7, 2, 0, 0]), - (DispatchError::Arithmetic(sp_runtime::ArithmeticError::Overflow), [8, 1, 0, 0]), - ( - DispatchError::Transactional(sp_runtime::TransactionalError::LimitReached), - [9, 0, 0, 0], - ), - (DispatchError::Exhausted, [10, 0, 0, 0]), - (DispatchError::Corruption, [11, 0, 0, 0]), - (DispatchError::Unavailable, [12, 0, 0, 0]), - (DispatchError::RootNotAllowed, [13, 0, 0, 0]), - ]; - for (error, encoded_error) in test_cases { - let status_code = crate::extensions::convert_to_status_code(error); - assert_eq!(status_code, u32::decode(&mut &encoded_error[..]).unwrap()); - } + message: None + }) + ); + + // Example pallet assets Error into ModuleError. + let index = <::PalletInfo as frame_support::traits::PalletInfo>::index::< + Assets, + >() + .expect("Every active module has an index in the runtime; qed") as u8; + let mut error = + pallet_assets::Error::NotFrozen::.encode(); + error.resize(MAX_MODULE_ERROR_ENCODED_SIZE, 0); + let error = DispatchError::Module(ModuleError { + index, + error: TryInto::try_into(error).expect("should work"), + message: None, + }); + let encoded = error.encode(); + let decoded = DispatchError::decode(&mut &encoded[..]).unwrap(); + assert_eq!(encoded, vec![3, 52, 18, 0, 0, 0]); + assert_eq!( + decoded, + DispatchError::Module(ModuleError { + index: 52, + error: [18, 0, 0, 0], + message: None + }) + ); + + // Example DispatchError::Token + let error = DispatchError::Token(TokenError::UnknownAsset); + let encoded = error.encode(); + let decoded = DispatchError::decode(&mut &encoded[..]).unwrap(); + assert_eq!(encoded, vec![7, 4]); + assert_eq!(decoded, error); + + // Example DispatchError::Arithmetic + let error = DispatchError::Arithmetic(ArithmeticError::Overflow); + let encoded = error.encode(); + let decoded = DispatchError::decode(&mut &encoded[..]).unwrap(); + assert_eq!(encoded, vec![8, 1]); + assert_eq!(decoded, error); + }); } } // use enumflags2::BitFlags; diff --git a/runtime/devnet/src/extensions/v0/assets.rs b/runtime/devnet/src/extensions/v0/assets.rs new file mode 100644 index 00000000..912b116f --- /dev/null +++ b/runtime/devnet/src/extensions/v0/assets.rs @@ -0,0 +1,39 @@ +use crate::extensions::{ + AccountId, AssetId, + AssetsKeys::{self, TotalSupply}, + Balance, Compact, Decode, DispatchError, MultiAddress, Runtime, TrustBackedAssetsInstance, +}; + +pub(crate) fn construct_assets_key( + call_index: u8, + params: Vec, +) -> Result { + match call_index { + 0 => { + let id = ::decode(&mut ¶ms[..]) + .map_err(|_| DispatchError::Other("DecodingFailed"))?; + Ok(TotalSupply(id)) + }, + // other calls + _ => Err(DispatchError::Other("UnknownFunctionId")), + } +} + +pub(crate) fn construct_assets_call( + call_index: u8, + params: Vec, +) -> Result, DispatchError> { + match call_index { + 9 => { + let (id, target, amount) = <(AssetId, AccountId, Balance)>::decode(&mut ¶ms[..]) + .map_err(|_| DispatchError::Other("DecodingFailed"))?; + Ok(pallet_assets::Call::::transfer_keep_alive { + id: Compact(id), + target: MultiAddress::Id(target), + amount, + }) + }, + // other calls + _ => Err(DispatchError::Other("UnknownFunctionId")), + } +} diff --git a/runtime/devnet/src/extensions/v0/error.rs b/runtime/devnet/src/extensions/v0/error.rs new file mode 100644 index 00000000..b8af2250 --- /dev/null +++ b/runtime/devnet/src/extensions/v0/error.rs @@ -0,0 +1,298 @@ +#[cfg(test)] +use crate::extensions::convert_to_status_code; + +pub(crate) fn handle_unknown_error(encoded_error: &mut [u8; 4]) { + let unknown = match encoded_error[0] { + code if UNIT_ERRORS.contains(&code) => nested_errors(&encoded_error[1..], None), + // Single nested errors with a limit in their nesting. + // + // `TokenError`: has ten variants - translated to a limit of nine. + 7 => nested_errors(&encoded_error[1..], Some(9)), + // `ArithmeticError`: has 3 variants - translated to a limit of two. + 8 => nested_errors(&encoded_error[1..], Some(2)), + // `TransactionalError`: has 2 variants - translated to a limit of one. + 9 => nested_errors(&encoded_error[1..], Some(1)), + code if DOUBLE_NESTED_ERRORS.contains(&code) => nested_errors(&encoded_error[3..], None), + _ => true, + }; + if unknown { + encoded_error[..].rotate_right(1); + encoded_error[0] = 0u8; + } +} + +// Unit `Error` variants. +// (variant: index): +// - CannotLookup: 1, +// - BadOrigin: 2, +// - ConsumerRemaining: 4, +// - NoProviders: 5, +// - TooManyConsumers: 6, +// - Exhausted: 10, +// - Corruption: 11, +// - Unavailable: 12, +// - RootNotAllowed: 13, +// - UnknownFunctionId: 254, +// - DecodingFailed: 255, +const UNIT_ERRORS: [u8; 11] = [1, 2, 4, 5, 6, 10, 11, 12, 13, 254, 255]; + +#[cfg(test)] +const SINGLE_NESTED_ERRORS: [u8; 3] = [7, 8, 9]; + +// Double nested `Error` variants +// (variant: index): +// - Module: 3, +const DOUBLE_NESTED_ERRORS: [u8; 1] = [3]; + +// Checks for unknown nested errors within the `DispatchError`. +// - For single nested errors with a limit, it verifies if the nested value exceeds the limit. +// - For other nested errors, it checks if any subsequent bytes are non-zero. +// +// `nested_error` - The slice of bytes representing the nested error. +// `limit` - An optional limit for single nested errors. +fn nested_errors(nested_error: &[u8], limit: Option) -> bool { + match limit { + Some(l) => nested_error[0] > l || nested_error[1..].iter().any(|&x| x != 0u8), + None => nested_error.iter().any(|&x| x != 0u8), + } +} + +#[cfg(test)] +mod tests { + use super::*; + use pop_primitives::error::{ + ArithmeticError::*, + Error::{self, *}, + TokenError::*, + TransactionalError::*, + }; + use sp_runtime::DispatchError; + + // Compare all the different `DispatchError` variants with the expected `Error`. + #[test] + fn dispatch_error_to_error() { + let test_cases = vec![ + ( + DispatchError::Other(""), + (Other { dispatch_error_index: 0, error_index: 0, error: 0 }), + ), + (DispatchError::Other("UnknownFunctionId"), UnknownFunctionId), + (DispatchError::Other("DecodingFailed"), DecodingFailed), + (DispatchError::CannotLookup, CannotLookup), + (DispatchError::BadOrigin, BadOrigin), + ( + DispatchError::Module(sp_runtime::ModuleError { + index: 1, + error: [2, 0, 0, 0], + message: Some("hallo"), + }), + Module { index: 1, error: 2 }, + ), + (DispatchError::ConsumerRemaining, ConsumerRemaining), + (DispatchError::NoProviders, NoProviders), + (DispatchError::TooManyConsumers, TooManyConsumers), + (DispatchError::Token(sp_runtime::TokenError::BelowMinimum), Token(BelowMinimum)), + ( + DispatchError::Arithmetic(sp_runtime::ArithmeticError::Overflow), + Arithmetic(Overflow), + ), + ( + DispatchError::Transactional(sp_runtime::TransactionalError::LimitReached), + Transactional(LimitReached), + ), + (DispatchError::Exhausted, Exhausted), + (DispatchError::Corruption, Corruption), + (DispatchError::Unavailable, Unavailable), + (DispatchError::RootNotAllowed, RootNotAllowed), + ]; + for (dispatch_error, expected) in test_cases { + let status_code = crate::extensions::convert_to_status_code(dispatch_error, 0); + let error: Error = status_code.into(); + assert_eq!(error, expected); + } + } + + // Compare all the different `DispatchError::Other` possibilities with the expected `Error`. + #[test] + fn other_error() { + let test_cases = vec![ + ( + DispatchError::Other("Random"), + (Other { dispatch_error_index: 0, error_index: 0, error: 0 }), + ), + (DispatchError::Other("UnknownFunctionId"), UnknownFunctionId), + (DispatchError::Other("DecodingFailed"), DecodingFailed), + ]; + for (dispatch_error, expected) in test_cases { + let status_code = convert_to_status_code(dispatch_error, 0); + let error: Error = status_code.into(); + assert_eq!(error, expected); + } + } + + // Compare all the different `DispatchError::Module` nesting possibilities, which can not be + // handled, with the expected `Error`. See `double_nested_error_variants` fourth byte nesting. + #[test] + fn test_module_error() { + let test_cases = vec![ + DispatchError::Module(sp_runtime::ModuleError { + index: 1, + error: [2, 2, 0, 0], + message: Some("Random"), + }), + DispatchError::Module(sp_runtime::ModuleError { + index: 1, + error: [2, 2, 2, 0], + message: Some("Random"), + }), + DispatchError::Module(sp_runtime::ModuleError { + index: 1, + error: [2, 2, 2, 2], + message: Some("Random"), + }), + ]; + for dispatch_error in test_cases { + let status_code = convert_to_status_code(dispatch_error, 0); + let error: Error = status_code.into(); + assert_eq!(error, Other { dispatch_error_index: 3, error_index: 1, error: 2 }); + } + } + + // Converts 4 bytes into `Error` and handles unknown errors (used in `convert_to_status_code`). + fn into_error(mut error_bytes: [u8; 4]) -> Error { + handle_unknown_error(&mut error_bytes); + u32::from_le_bytes(error_bytes).into() + } + + // Tests the `handle_unknown_error` for `Error`, version 0. + // + // Unit variants: + // If the encoded value indicates a nested `Error` which is known by V0 as a + // unit variant, the encoded value is converted into `Error::Other`. + // + // Example: the error `BadOrigin` (encoded: `[2, 0, 0, 0]`) with a non-zero value for one + // of the bytes [1..4]: `[2, 0, 1, 0]` is converted into `[0, 2, 0, 1]` (shifting the bits + // one forward). This is decoded to `Error::Other { dispatch_error: 2, index: 0, error: 1 }`. + #[test] + fn unit_error_variants() { + let errors = vec![ + CannotLookup, + BadOrigin, + ConsumerRemaining, + NoProviders, + TooManyConsumers, + Exhausted, + Corruption, + Unavailable, + RootNotAllowed, + UnknownFunctionId, + DecodingFailed, + ]; + // Compare an `Error`, which is converted from an encoded value, with the expected `Error`. + for (i, &error_code) in UNIT_ERRORS.iter().enumerate() { + // No nesting and unit variant correctly returned. + assert_eq!(into_error([error_code, 0, 0, 0]), errors[i]); + // Unexpected second byte nested. + assert_eq!( + into_error([error_code, 1, 0, 0]), + (Other { dispatch_error_index: error_code, error_index: 1, error: 0 }), + ); + // Unexpected third byte nested. + assert_eq!( + into_error([error_code, 1, 1, 0]), + (Other { dispatch_error_index: error_code, error_index: 1, error: 1 }), + ); + // Unexpected fourth byte nested. + assert_eq!( + into_error([error_code, 1, 1, 1]), + (Other { dispatch_error_index: error_code, error_index: 1, error: 1 }), + ); + } + } + + // Single nested variants: + // If the encoded value indicates a double nested `Error` which is known by V0 + // as a single nested variant, the encoded value is converted into `Error::Other`. + // + // Example: the error `Arithmetic(Overflow)` (encoded: `[8, 1, 0, 0]`) with a non-zero + // value for one of the bytes [2..4]: `[8, 1, 1, 0]` is converted into `[0, 8, 1, 1]`. This is + // decoded to `Error::Other { dispatch_error: 8, index: 1, error: 1 }`. + #[test] + fn single_nested_error_variants() { + let errors = vec![ + [Token(FundsUnavailable), Token(OnlyProvider)], + [Arithmetic(Underflow), Arithmetic(Overflow)], + [Transactional(LimitReached), Transactional(NoLayer)], + ]; + // Compare an `Error`, which is converted from an encoded value, with the expected `Error`. + for (i, &error_code) in SINGLE_NESTED_ERRORS.iter().enumerate() { + // No nested and single nested variant correctly returned. + assert_eq!(into_error([error_code, 0, 0, 0]), errors[i][0]); + assert_eq!(into_error([error_code, 1, 0, 0]), errors[i][1]); + // Unexpected third byte nested. + assert_eq!( + into_error([error_code, 1, 1, 0]), + (Other { dispatch_error_index: error_code, error_index: 1, error: 1 }), + ); + // Unexpected fourth byte nested. + assert_eq!( + into_error([error_code, 1, 1, 1]), + Other { dispatch_error_index: error_code, error_index: 1, error: 1 }, + ); + } + } + + #[test] + fn single_nested_unknown_variants() { + // Unknown `TokenError` variant. + assert_eq!( + into_error([7, 10, 0, 0]), + Other { dispatch_error_index: 7, error_index: 10, error: 0 } + ); + // Unknown `Arithmetic` variant. + assert_eq!( + into_error([8, 3, 0, 0]), + Other { dispatch_error_index: 8, error_index: 3, error: 0 } + ); + // Unknown `Transactional` variant. + assert_eq!( + into_error([9, 2, 0, 0]), + Other { dispatch_error_index: 9, error_index: 2, error: 0 } + ); + } + + // Double nested variants: + // If the encoded value indicates a triple nested `Error` which is known by V0 + // as a double nested variant, the encoded value is converted into `Error::Other`. + // + // Example: the error `Module { index: 10, error 5 }` (encoded: `[3, 10, 5, 0]`) with a non-zero + // value for the last byte: `[3, 10, 5, 3]` is converted into `[0, 3, 10, 5]`. This is + // decoded to `Error::Other { dispatch_error: 3, index: 10, error: 5 }`. + #[test] + fn double_nested_error_variants() { + // Compare an `Error`, which is converted from an encoded value, with the expected `Error`. + // No nesting and unit variant correctly returned. + assert_eq!(into_error([3, 0, 0, 0]), Module { index: 0, error: 0 }); + // Allowed single nesting and variant correctly returned. + assert_eq!(into_error([3, 1, 0, 0]), Module { index: 1, error: 0 }); + // Allowed double nesting and variant correctly returned. + assert_eq!(into_error([3, 1, 1, 0]), Module { index: 1, error: 1 }); + // Unexpected fourth byte nested. + assert_eq!( + into_error([3, 1, 1, 1]), + Other { dispatch_error_index: 3, error_index: 1, error: 1 }, + ); + } + + #[test] + fn test_random_encoded_values() { + assert_eq!( + into_error([100, 100, 100, 100]), + Other { dispatch_error_index: 100, error_index: 100, error: 100 } + ); + assert_eq!( + into_error([200, 200, 200, 200]), + Other { dispatch_error_index: 200, error_index: 200, error: 200 } + ); + } +} diff --git a/runtime/devnet/src/extensions/v0/mod.rs b/runtime/devnet/src/extensions/v0/mod.rs new file mode 100644 index 00000000..6406e08f --- /dev/null +++ b/runtime/devnet/src/extensions/v0/mod.rs @@ -0,0 +1,2 @@ +pub(crate) mod assets; +pub(crate) mod error; diff --git a/runtime/testnet/Cargo.toml b/runtime/testnet/Cargo.toml index b7aa7b76..b04c3102 100644 --- a/runtime/testnet/Cargo.toml +++ b/runtime/testnet/Cargo.toml @@ -22,7 +22,7 @@ scale-info.workspace = true smallvec.workspace = true # Local -pop-primitives = { workspace = true, features = ["assets", "nfts", "cross-chain"] } +pop-primitives = { workspace = true, features = ["nfts", "cross-chain"] } pop-runtime-common = { workspace = true, default-features = false } # Substrate diff --git a/runtime/testnet/src/extensions.rs b/runtime/testnet/src/extensions.rs index dd2c52bb..4c224544 100644 --- a/runtime/testnet/src/extensions.rs +++ b/runtime/testnet/src/extensions.rs @@ -3,7 +3,7 @@ use frame_support::traits::{Contains, OriginTrait}; use frame_support::{ dispatch::{GetDispatchInfo, RawOrigin}, pallet_prelude::*, - traits::nonfungibles_v2::Inspect as NonFungiblesInspect, + traits::nonfungibles_v2::Inspect, }; use pallet_contracts::chain_extension::{ BufInBufOutState, ChainExtension, ChargedAmount, Environment, Ext, InitState, RetVal, @@ -86,7 +86,6 @@ impl TryFrom for v0::FuncId { 0x1 => Self::ReadState, _ => { log::error!("called an unregistered `func_id`: {:}", func_id); - // TODO: Other error. return Err(DispatchError::Other("unimplemented func_id")); }, }; @@ -207,8 +206,6 @@ where RuntimeStateKeys::ParachainSystem(key) => { read_parachain_system_state::(key, &mut env) }, - // TODO: devnet / testnet feature. - _ => Err(DispatchError::Other("Unknown state keys")), }? .encode(); @@ -218,8 +215,7 @@ where ); env.write(&result, false, None).map_err(|e| { log::trace!(target: LOG_TARGET, "{:?}", e); - // TODO: Other error. - DispatchError::Other("Unable to write results to contract memory") + DispatchError::Other("unable to write results to contract memory") }) } @@ -485,7 +481,7 @@ mod tests { log::debug!("result: {:?}", result); } - // Check for revert. + // check for revert assert!(!result.result.unwrap().did_revert(), "Contract reverted!"); assert_eq!(Nfts::owner(collection_id, item_id), Some(BOB.into())); @@ -550,7 +546,7 @@ mod tests { log::debug!("result: {:?}", result); } - // Check for revert with expected error. + // check for revert with expected error let result = result.result.unwrap(); assert!(result.did_revert()); }); @@ -610,7 +606,7 @@ mod tests { log::debug!("result: {:?}", result); } - // Check for revert. + // check for revert assert!(!result.result.unwrap().did_revert(), "Contract reverted!"); }); } @@ -673,7 +669,7 @@ mod tests { log::debug!("result: {:?}", result); } - // Check for revert. + // check for revert assert!( result.result.is_err(), "Contract execution should have failed - unimplemented runtime call!" @@ -735,7 +731,7 @@ mod tests { log::debug!("filtered result: {:?}", result); } - // Check for revert. + // check for revert assert!(!result.result.unwrap().did_revert(), "Contract reverted!"); }); } From 972e4c9e1519279ad351d4d900c65e3a375a6d29 Mon Sep 17 00:00:00 2001 From: Daanvdplas Date: Fri, 5 Jul 2024 19:13:57 +0200 Subject: [PATCH 017/112] feat: add more interfaces --- pop-api/examples/fungibles/lib.rs | 38 +- pop-api/integration-tests/Cargo.toml | 2 + pop-api/integration-tests/src/lib.rs | 9 +- .../integration-tests/src/local_fungibles.rs | 440 ++++++++++++++---- pop-api/src/v0/assets/fungibles.rs | 19 +- pop-api/src/v0/assets/mod.rs | 140 ++++-- runtime/devnet/src/config/mod.rs | 2 +- runtime/devnet/src/extensions/mod.rs | 45 +- runtime/devnet/src/extensions/v0/assets.rs | 42 +- 9 files changed, 554 insertions(+), 183 deletions(-) diff --git a/pop-api/examples/fungibles/lib.rs b/pop-api/examples/fungibles/lib.rs index 03841b74..2abc422c 100755 --- a/pop-api/examples/fungibles/lib.rs +++ b/pop-api/examples/fungibles/lib.rs @@ -45,19 +45,23 @@ mod fungibles { } #[ink(message)] - pub fn balance_of(&self, id: AssetId, owner: AccountId) -> Balance { + pub fn balance_of(&self, id: AssetId, owner: AccountId) -> Result { api::balance_of(id, owner) } #[ink(message)] - pub fn allowance(&self, id: AssetId, owner: AccountId, spender: AccountId) -> Balance { + pub fn allowance( + &self, + id: AssetId, + owner: AccountId, + spender: AccountId, + ) -> Result { api::allowance(id, owner, spender) } #[ink(message)] pub fn transfer(&self, id: AssetId, to: AccountId, value: Balance) -> Result<()> { - api::transfer(id, to, value)?; - Ok(()) + api::transfer(id, to, value) } #[ink(message)] @@ -70,14 +74,12 @@ mod fungibles { // In the standard a `[u8]`, but the size needs to be known at compile time. _data: Vec, ) -> Result<()> { - api::transfer_from(id, from, to, value)?; - Ok(()) + api::transfer_from(id, from, to, value) } #[ink(message)] pub fn approve(&self, id: AssetId, spender: AccountId, value: Balance) -> Result<()> { - api::approve(id, spender, value)?; - Ok(()) + api::approve(id, spender, value) } #[ink(message)] @@ -87,8 +89,7 @@ mod fungibles { spender: AccountId, value: Balance, ) -> Result<()> { - api::increase_allowance(id, spender, value)?; - Ok(()) + api::increase_allowance(id, spender, value) } #[ink(message)] @@ -98,27 +99,26 @@ mod fungibles { spender: AccountId, value: Balance, ) -> Result<()> { - api::decrease_allowance(id, spender, value)?; - Ok(()) + api::decrease_allowance(id, spender, value) } - // 2. PSP-22 Metadata Interface: - // - token_name - // - token_symbol - // - token_decimals + /// 2. PSP-22 Metadata Interface: + /// - token_name + /// - token_symbol + /// - token_decimals #[ink(message)] - pub fn token_name(&self, id: AssetId) -> Vec { + pub fn token_name(&self, id: AssetId) -> Result> { api::token_name(id) } #[ink(message)] - pub fn token_symbol(&self, id: AssetId) -> Vec { + pub fn token_symbol(&self, id: AssetId) -> Result> { api::token_symbol(id) } #[ink(message)] - pub fn token_decimals(&self, id: AssetId) -> u8 { + pub fn token_decimals(&self, id: AssetId) -> Result { api::token_decimals(id) } diff --git a/pop-api/integration-tests/Cargo.toml b/pop-api/integration-tests/Cargo.toml index c855a884..94c0ba83 100644 --- a/pop-api/integration-tests/Cargo.toml +++ b/pop-api/integration-tests/Cargo.toml @@ -9,6 +9,7 @@ scale = { package = "parity-scale-codec", version = "3.0.0", default-features = frame-support = { version = "29.0.0", default-features = false } frame-system = { version = "29.0.0", default-features = false } pallet-balances = { version = "29.0.2", default-features = false } +pallet-assets = { version = "30.0.0", default-features = false } pallet-contracts = { version = "28.0.0", default-features = false } pop-primitives = { path = "../../primitives", default-features = false, features = ["assets"] } pop-runtime-devnet = { path = "../../runtime/devnet", default-features = false } @@ -22,6 +23,7 @@ std = [ "frame-support/std", "frame-system/std", "pallet-balances/std", + "pallet-assets/std", "pallet-contracts/std", "pop-primitives/std", "pop-runtime-devnet/std", diff --git a/pop-api/integration-tests/src/lib.rs b/pop-api/integration-tests/src/lib.rs index 624c3000..c6732d91 100644 --- a/pop-api/integration-tests/src/lib.rs +++ b/pop-api/integration-tests/src/lib.rs @@ -1,14 +1,19 @@ #![cfg(test)] use frame_support::{ - traits::fungibles::{approvals::Inspect as ApprovalInspect, Inspect}, + traits::fungibles::{ + approvals::Inspect as ApprovalInspect, metadata::Inspect as MetadataInspect, Inspect, + }, weights::Weight, }; use pallet_contracts::{Code, CollectEvents, Determinism, ExecReturnValue}; use scale::{Decode, Encode}; use sp_runtime::{traits::Hash, AccountId32, BuildStorage, DispatchError}; -use pop_runtime_devnet::{Assets, Contracts, Runtime, RuntimeOrigin, System, UNIT}; +use pop_runtime_devnet::{ + config::assets::TrustBackedAssetsInstance, Assets, Contracts, Runtime, RuntimeOrigin, System, + UNIT, +}; mod local_fungibles; diff --git a/pop-api/integration-tests/src/local_fungibles.rs b/pop-api/integration-tests/src/local_fungibles.rs index 968c43eb..d0229c84 100644 --- a/pop-api/integration-tests/src/local_fungibles.rs +++ b/pop-api/integration-tests/src/local_fungibles.rs @@ -10,10 +10,27 @@ const ASSET_ID: AssetId = 1; fn decoded(result: ExecReturnValue) -> T { match ::decode(&mut &result.data[2..]) { Ok(value) => value, - Err(_) => panic!("\nTest failed by trying to decode result: {:?} into `T`\n", result), + Err(_) => panic!("\nTest failed by trying to decode `{:?}` into `T`\n", result), } } +// Call total_supply contract message. +fn total_supply(addr: AccountId32, asset_id: AssetId) -> Balance { + let function = function_selector("total_supply"); + let params = [function, asset_id.encode()].concat(); + let result = do_bare_call(addr, params, 0).expect("should work"); + decoded::(result) +} + +// Call balance_of contract message. +fn balance_of(addr: AccountId32, asset_id: AssetId, owner: AccountId32) -> Balance { + let function = function_selector("balance_of"); + let params = [function, asset_id.encode(), owner.encode()].concat(); + let result = do_bare_call(addr, params, 0).expect("should work"); + decoded::(result) +} + +// Call allowance contract message. fn allowance( addr: AccountId32, asset_id: AssetId, @@ -26,20 +43,28 @@ fn allowance( decoded::(result) } -// Call balance_of contract message. -fn balance_of(addr: AccountId32, asset_id: AssetId, owner: AccountId32) -> Balance { - let function = function_selector("balance_of"); - let params = [function, asset_id.encode(), owner.encode()].concat(); +// Call token_name contract message. +fn token_name(addr: AccountId32, asset_id: AssetId) -> Vec { + let function = function_selector("token_name"); + let params = [function, asset_id.encode()].concat(); let result = do_bare_call(addr, params, 0).expect("should work"); - decoded::(result) + decoded::>(result) } -// Call total_supply contract message. -fn total_supply(addr: AccountId32, asset_id: AssetId) -> Balance { - let function = function_selector("total_supply"); +// Call token_symbol contract message. +fn token_symbol(addr: AccountId32, asset_id: AssetId) -> Vec { + let function = function_selector("token_symbol"); let params = [function, asset_id.encode()].concat(); let result = do_bare_call(addr, params, 0).expect("should work"); - decoded::(result) + decoded::>(result) +} + +// Call token_decimals contract message. +fn token_decimals(addr: AccountId32, asset_id: AssetId) -> u8 { + let function = function_selector("token_decimals"); + let params = [function, asset_id.encode()].concat(); + let result = do_bare_call(addr, params, 0).expect("should work"); + decoded::(result) } fn asset_exists(addr: AccountId32, asset_id: AssetId) -> bool { @@ -82,7 +107,6 @@ fn transfer( let function = function_selector("transfer"); let params = [function, asset_id.encode(), to.encode(), value.encode()].concat(); let result = do_bare_call(addr, params, 0).expect("should work"); - println!("Transfer result: {:?}", result); result } @@ -101,6 +125,18 @@ fn transfer_from( do_bare_call(addr, params, 0).expect("should work") } +fn increase_allowance( + addr: AccountId32, + asset_id: AssetId, + spender: AccountId32, + value: Balance, +) -> ExecReturnValue { + let function = function_selector("increase_allowance"); + let params = [function, asset_id.encode(), spender.encode(), value.encode()].concat(); + let result = do_bare_call(addr, params, 0).expect("should work"); + result +} + fn create_asset(owner: AccountId32, asset_id: AssetId, min_balance: Balance) -> AssetId { assert_eq!( Assets::create( @@ -154,20 +190,88 @@ fn create_asset_mint_and_approve( } // Freeze an asset. -fn freeze_asset(asset_id: AssetId, owner: AccountId32) { +fn freeze_asset(owner: AccountId32, asset_id: AssetId) { assert_eq!(Assets::freeze_asset(RuntimeOrigin::signed(owner.into()), asset_id.into()), Ok(())); } // Thaw an asset. -fn thaw_asset(asset_id: AssetId, owner: AccountId32) { +fn thaw_asset(owner: AccountId32, asset_id: AssetId) { assert_eq!(Assets::thaw_asset(RuntimeOrigin::signed(owner.into()), asset_id.into()), Ok(())); } // Start destroying an asset. -fn start_destroy_asset(asset_id: AssetId, owner: AccountId32) { +fn start_destroy_asset(owner: AccountId32, asset_id: AssetId) { assert_eq!(Assets::start_destroy(RuntimeOrigin::signed(owner.into()), asset_id.into()), Ok(())); } +// Create an asset and set metadata. +fn create_asset_and_set_metadata( + owner: AccountId32, + asset_id: AssetId, + name: Vec, + symbol: Vec, + decimals: u8, +) { + assert_eq!( + Assets::create( + RuntimeOrigin::signed(owner.clone()), + asset_id.into(), + owner.clone().into(), + 100 + ), + Ok(()) + ); + set_metadata_asset(owner, asset_id, name, symbol, decimals); +} + +// Set metadata of an asset. +fn set_metadata_asset( + owner: AccountId32, + asset_id: AssetId, + name: Vec, + symbol: Vec, + decimals: u8, +) { + assert_eq!( + Assets::set_metadata( + RuntimeOrigin::signed(owner.into()), + asset_id.into(), + name, + symbol, + decimals + ), + Ok(()) + ); +} + +fn token_name_asset(asset_id: AssetId) -> Vec { + as MetadataInspect>::name( + asset_id, + ) +} + +fn token_symbol_asset(asset_id: AssetId) -> Vec { + as MetadataInspect>::symbol( + asset_id, + ) +} + +fn token_decimals_asset(asset_id: AssetId) -> u8 { + as MetadataInspect>::decimals( + asset_id, + ) +} + +/// 1. PSP-22 Interface: +/// - total_supply +/// - balance_of +/// - allowance +/// - transfer +/// - transfer_from +/// - approve +/// - increase_allowance +/// - decrease_allowance + #[test] #[ignore] fn total_supply_works() { @@ -181,10 +285,12 @@ fn total_supply_works() { // No tokens in circulation. assert_eq!(Assets::total_supply(ASSET_ID), total_supply(addr.clone(), ASSET_ID)); + assert_eq!(0, total_supply(addr.clone(), ASSET_ID)); // Tokens in circulation. create_asset_and_mint_to(addr.clone(), ASSET_ID, BOB, 100); - assert_eq!(Assets::total_supply(ASSET_ID), total_supply(addr, ASSET_ID)); + assert_eq!(Assets::total_supply(ASSET_ID), total_supply(addr.clone(), ASSET_ID)); + assert_eq!(100, total_supply(addr, ASSET_ID)); }); } @@ -198,10 +304,12 @@ fn balance_of_works() { // No tokens in circulation. assert_eq!(Assets::balance(ASSET_ID, BOB), balance_of(addr.clone(), ASSET_ID, BOB)); + assert_eq!(0, balance_of(addr.clone(), ASSET_ID, BOB)); // Tokens in circulation. create_asset_and_mint_to(addr.clone(), ASSET_ID, BOB, 100); - assert_eq!(Assets::balance(ASSET_ID, BOB), balance_of(addr, ASSET_ID, BOB)); + assert_eq!(Assets::balance(ASSET_ID, BOB), balance_of(addr.clone(), ASSET_ID, BOB)); + assert_eq!(100, balance_of(addr, ASSET_ID, BOB)); }); } @@ -218,90 +326,240 @@ fn allowance_works() { Assets::allowance(ASSET_ID, &BOB, &ALICE), allowance(addr.clone(), ASSET_ID, BOB, ALICE) ); + assert_eq!(0, allowance(addr.clone(), ASSET_ID, BOB, ALICE)); // Tokens in circulation. create_asset_mint_and_approve(addr.clone(), ASSET_ID, BOB, 100, ALICE, 50); assert_eq!( Assets::allowance(ASSET_ID, &BOB, &ALICE), - allowance(addr, ASSET_ID, BOB, ALICE) + allowance(addr.clone(), ASSET_ID, BOB, ALICE) ); + assert_eq!(50, allowance(addr, ASSET_ID, BOB, ALICE)); }); } #[test] #[ignore] -fn asset_exists_works() { +fn transfer_works() { new_test_ext().execute_with(|| { let _ = env_logger::try_init(); let addr = instantiate("../examples/fungibles/target/ink/fungibles.wasm", INIT_VALUE, vec![]); + let amount: Balance = 100 * UNIT; - // No tokens in circulation. - assert_eq!(Assets::asset_exists(ASSET_ID), asset_exists(addr.clone(), ASSET_ID)); - - // Tokens in circulation. - create_asset(addr.clone(), ASSET_ID, 1); - assert_eq!(Assets::asset_exists(ASSET_ID), asset_exists(addr, ASSET_ID)); + // Asset does not exist. + assert_eq!( + decoded::(transfer(addr.clone(), 1, BOB, amount,)), + Module { index: 52, error: 3 }, + ); + // Create asset with Alice as owner and mint `amount` to contract address. + let asset = create_asset_and_mint_to(ALICE, 1, addr.clone(), amount); + // Asset is not live, i.e. frozen or being destroyed. + freeze_asset(ALICE, asset); + assert_eq!( + decoded::(transfer(addr.clone(), asset, BOB, amount,)), + Module { index: 52, error: 16 }, + ); + thaw_asset(ALICE, asset); + // Not enough balance. + assert_eq!( + decoded::(transfer(addr.clone(), asset, BOB, amount + 1 * UNIT)), + Module { index: 52, error: 0 }, + ); + // Not enough balance due to ED. + assert_eq!( + decoded::(transfer(addr.clone(), asset, BOB, amount)), + Module { index: 52, error: 0 }, + ); + // Successful transfer. + let bob_balance_before_mint = Assets::balance(asset, &BOB); + let result = transfer(addr.clone(), asset, BOB, amount / 2); + assert!(!result.did_revert(), "Contract reverted!"); + let bob_balance_after_mint = Assets::balance(asset, &BOB); + assert_eq!(bob_balance_after_mint, bob_balance_before_mint + amount / 2); + // Transfer asset to account that does not exist. + assert_eq!( + decoded::(transfer(addr.clone(), asset, FERDIE, amount / 4)), + Token(CannotCreate) + ); + // Asset is not live, i.e. frozen or being destroyed. + start_destroy_asset(ALICE, asset); + assert_eq!( + decoded::(transfer(addr.clone(), asset, BOB, amount / 4)), + Module { index: 52, error: 16 }, + ); }); } #[test] #[ignore] -fn create_works() { +fn increase_allowance_works() { new_test_ext().execute_with(|| { let _ = env_logger::try_init(); - let new_asset = 2; - // Instantiate a contract without balance (relay token). - let addr = instantiate("../examples/fungibles/target/ink/fungibles.wasm", 0, vec![0]); - // No balance to pay for fees. + let addr = instantiate("../examples/fungibles/target/ink/fungibles.wasm", 0, vec![]); + let amount: Balance = 100 * UNIT; + let asset = 0; + create_asset_and_mint_to(ALICE, asset, addr.clone(), amount); assert_eq!( - decoded::(create(addr.clone(), ASSET_ID, addr.clone(), 1)), - Module { index: 10, error: 2 }, + decoded::(increase_allowance(addr.clone(), asset, BOB, amount)), + ConsumerRemaining ); - // Instantiate a contract without balance (relay token). - let addr = instantiate("../examples/fungibles/target/ink/fungibles.wasm", 100, vec![2]); - // TODO: make sure it has enough for the fees but not for the deposit. - // No balance to pay fe deposit. + + let addr = + instantiate("../examples/fungibles/target/ink/fungibles.wasm", INIT_VALUE, vec![1]); + // Asset does not exist. + let asset = 1; assert_eq!( - decoded::(create(addr.clone(), ASSET_ID, addr.clone(), 1)), - Module { index: 10, error: 2 }, + decoded::(increase_allowance(addr.clone(), asset, BOB, amount)), + Module { index: 52, error: 3 }, ); - // Instantiate a contract with balance. + // Create asset with Alice as owner and mint `amount` to contract address. + create_asset_and_mint_to(ALICE, asset, addr.clone(), amount); + // Asset is not live, i.e. frozen or being destroyed. + freeze_asset(ALICE, asset); + assert_eq!( + decoded::(increase_allowance(addr.clone(), asset, BOB, amount)), + Module { index: 52, error: 16 }, + ); + thaw_asset(ALICE, asset); + // Successful approval. + assert_eq!(0, Assets::allowance(asset, &addr, &BOB)); + assert!( + !increase_allowance(addr.clone(), asset, BOB, amount).did_revert(), + "Contract reverted!" + ); + assert_eq!(Assets::allowance(asset, &addr, &BOB), amount); + // Additive. + assert!( + !increase_allowance(addr.clone(), asset, BOB, amount).did_revert(), + "Contract reverted!" + ); + assert_eq!(Assets::allowance(asset, &addr, &BOB), amount * 2); + // Asset is not live, i.e. frozen or being destroyed. + start_destroy_asset(ALICE, asset); + assert_eq!( + decoded::(increase_allowance(addr.clone(), asset, BOB, amount)), + Module { index: 52, error: 16 }, + ); + }); +} + +#[test] +#[ignore] +fn transfer_from_works() { + new_test_ext().execute_with(|| { + let _ = env_logger::try_init(); let addr = - instantiate("../examples/fungibles/target/ink/fungibles.wasm", INIT_VALUE, vec![1]); - create_asset(ALICE, ASSET_ID, 1); - // Asset ID is already taken. + instantiate("../examples/fungibles/target/ink/fungibles.wasm", INIT_VALUE, vec![]); + let amount: Balance = 100 * UNIT; + + // Asset does not exist. assert_eq!( - decoded::(create(addr.clone(), ASSET_ID, BOB, 1)), - Module { index: 52, error: 5 }, + decoded::(transfer(addr.clone(), 1, BOB, amount,)), + Module { index: 52, error: 3 }, ); - // The minimal balance for an asset must be non zero. + // Create asset with Alice as owner and mint `amount` to contract address. + let asset = create_asset_and_mint_to(ALICE, 1, addr.clone(), amount); + // Asset is not live, i.e. frozen or being destroyed. + freeze_asset(ALICE, asset); assert_eq!( - decoded::(create(addr.clone(), new_asset, BOB, 0)), - Module { index: 52, error: 7 }, + decoded::(transfer(addr.clone(), asset, BOB, amount,)), + Module { index: 52, error: 16 }, ); - let result = create(addr.clone(), new_asset, BOB, 1); + thaw_asset(ALICE, asset); + // Not enough balance. + assert_eq!( + decoded::(transfer(addr.clone(), asset, BOB, amount + 1 * UNIT)), + Module { index: 52, error: 0 }, + ); + // Not enough balance due to ED. + assert_eq!( + decoded::(transfer(addr.clone(), asset, BOB, amount)), + Module { index: 52, error: 0 }, + ); + // Successful transfer. + let bob_balance_before_mint = Assets::balance(asset, &BOB); + let result = transfer(addr.clone(), asset, BOB, amount / 2); assert!(!result.did_revert(), "Contract reverted!"); + let bob_balance_after_mint = Assets::balance(asset, &BOB); + assert_eq!(bob_balance_after_mint, bob_balance_before_mint + amount / 2); + // Transfer asset to account that does not exist. + assert_eq!( + decoded::(transfer(addr.clone(), asset, FERDIE, amount / 4)), + Token(CannotCreate) + ); + // Asset is not live, i.e. frozen or being destroyed. + start_destroy_asset(ALICE, asset); + assert_eq!( + decoded::(transfer(addr.clone(), asset, BOB, amount / 4)), + Module { index: 52, error: 16 }, + ); }); } +/// 2. PSP-22 Metadata Interface: +/// - token_name +/// - token_symbol +/// - token_decimals + #[test] #[ignore] -fn set_metadata_works() { +fn token_metadata_works() { + new_test_ext().execute_with(|| { + let _ = env_logger::try_init(); + let addr = instantiate( + "../../pop-api/examples/fungibles/target/ink/fungibles.wasm", + INIT_VALUE, + vec![], + ); + + let name: Vec = vec![11, 12, 13]; + let symbol: Vec = vec![21, 22, 23]; + let decimals: u8 = 69; + // Token does not exist. + assert_eq!(token_name_asset(ASSET_ID), token_name(addr.clone(), ASSET_ID)); + assert_eq!(Vec::::new(), token_name(addr.clone(), ASSET_ID)); + assert_eq!(token_symbol_asset(ASSET_ID), token_symbol(addr.clone(), ASSET_ID)); + assert_eq!(Vec::::new(), token_symbol(addr.clone(), ASSET_ID)); + assert_eq!(token_decimals_asset(ASSET_ID), token_decimals(addr.clone(), ASSET_ID)); + assert_eq!(0, token_decimals(addr.clone(), ASSET_ID)); + + create_asset_and_set_metadata( + addr.clone(), + ASSET_ID, + name.clone(), + symbol.clone(), + decimals, + ); + assert_eq!(token_name_asset(ASSET_ID), token_name(addr.clone(), ASSET_ID)); + assert_eq!(name, token_name(addr.clone(), ASSET_ID)); + assert_eq!(token_symbol_asset(ASSET_ID), token_symbol(addr.clone(), ASSET_ID)); + assert_eq!(symbol, token_symbol(addr.clone(), ASSET_ID)); + assert_eq!(token_decimals_asset(ASSET_ID), token_decimals(addr.clone(), ASSET_ID)); + assert_eq!(decimals, token_decimals(addr.clone(), ASSET_ID)); + }); +} + +#[test] +#[ignore] +fn asset_exists_works() { new_test_ext().execute_with(|| { let _ = env_logger::try_init(); let addr = instantiate("../examples/fungibles/target/ink/fungibles.wasm", INIT_VALUE, vec![]); + // No tokens in circulation. + assert_eq!(Assets::asset_exists(ASSET_ID), asset_exists(addr.clone(), ASSET_ID)); + + // Tokens in circulation. create_asset(addr.clone(), ASSET_ID, 1); - let result = set_metadata(addr.clone(), ASSET_ID, vec![12], vec![12], 12); - assert!(!result.did_revert(), "Contract reverted!"); + assert_eq!(Assets::asset_exists(ASSET_ID), asset_exists(addr, ASSET_ID)); }); } #[test] #[ignore] -fn transfer_from_mint_works() { +fn mint_works() { new_test_ext().execute_with(|| { let _ = env_logger::try_init(); let addr = @@ -326,12 +584,12 @@ fn transfer_from_mint_works() { ); let asset = create_asset(addr.clone(), 2, 2); // Asset is not live, i.e. frozen or being destroyed. - freeze_asset(asset, addr.clone()); + freeze_asset(addr.clone(), asset); assert_eq!( decoded::(transfer_from(addr.clone(), asset, None, Some(BOB), amount, &[0u8])), Module { index: 52, error: 16 }, ); - thaw_asset(asset, addr.clone()); + thaw_asset(addr.clone(), asset); // Successful mint. let bob_balance_before_mint = Assets::balance(asset, &BOB); let result = transfer_from(addr.clone(), asset, None, Some(BOB), amount, &[0u8]); @@ -351,7 +609,7 @@ fn transfer_from_mint_works() { Arithmetic(Overflow) ); // Asset is not live, i.e. frozen or being destroyed. - start_destroy_asset(asset, addr.clone()); + start_destroy_asset(addr.clone(), asset); assert_eq!( decoded::(transfer_from(addr.clone(), asset, None, Some(BOB), amount, &[0u8])), Module { index: 52, error: 16 }, @@ -361,53 +619,53 @@ fn transfer_from_mint_works() { #[test] #[ignore] -fn transfer_works() { +fn create_works() { new_test_ext().execute_with(|| { let _ = env_logger::try_init(); - let addr = - instantiate("../examples/fungibles/target/ink/fungibles.wasm", INIT_VALUE, vec![]); - let amount: Balance = 100 * UNIT; - - // Asset does not exist. + // Instantiate a contract without balance (relay token). + let addr = instantiate("../examples/fungibles/target/ink/fungibles.wasm", 0, vec![0]); + // No balance to pay for fees. assert_eq!( - decoded::(transfer(addr.clone(), 1, BOB, amount,)), - Module { index: 52, error: 3 }, + decoded::(create(addr.clone(), ASSET_ID, addr.clone(), 1)), + Module { index: 10, error: 2 }, ); - // Create asset with Alice as owner and mint `amount` to contract address. - let asset = create_asset_and_mint_to(ALICE, 1, addr.clone(), amount); - // Asset is not live, i.e. frozen or being destroyed. - freeze_asset(asset, ALICE); + // Instantiate a contract without balance (relay token). + let addr = instantiate("../examples/fungibles/target/ink/fungibles.wasm", 100, vec![2]); + // No balance to pay the deposit. assert_eq!( - decoded::(transfer(addr.clone(), asset, BOB, amount,)), - Module { index: 52, error: 16 }, + decoded::(create(addr.clone(), ASSET_ID, addr.clone(), 1)), + Module { index: 10, error: 2 }, ); - thaw_asset(asset, ALICE); - // Not enough balance. + // Instantiate a contract with balance. + let addr = + instantiate("../examples/fungibles/target/ink/fungibles.wasm", INIT_VALUE, vec![1]); assert_eq!( - decoded::(transfer(addr.clone(), asset, BOB, amount + 1 * UNIT)), - Module { index: 52, error: 0 }, + decoded::(create(addr.clone(), ASSET_ID, BOB, 0)), + Module { index: 52, error: 7 }, ); - // Not enough balance due to ED. + create_asset(ALICE, ASSET_ID, 1); + // Asset ID is already taken. assert_eq!( - decoded::(transfer(addr.clone(), asset, BOB, amount)), - Module { index: 52, error: 0 }, + decoded::(create(addr.clone(), ASSET_ID, BOB, 1)), + Module { index: 52, error: 5 }, ); - // Successful transfer. - let bob_balance_before_mint = Assets::balance(asset, &BOB); - let result = transfer(addr.clone(), asset, BOB, amount / 2); + // The minimal balance for an asset must be non zero. + let new_asset = 2; + let result = create(addr.clone(), new_asset, BOB, 1); + assert!(!result.did_revert(), "Contract reverted!"); + }); +} + +#[test] +#[ignore] +fn set_metadata_works() { + new_test_ext().execute_with(|| { + let _ = env_logger::try_init(); + let addr = + instantiate("../examples/fungibles/target/ink/fungibles.wasm", INIT_VALUE, vec![]); + + create_asset(addr.clone(), ASSET_ID, 1); + let result = set_metadata(addr.clone(), ASSET_ID, vec![12], vec![12], 12); assert!(!result.did_revert(), "Contract reverted!"); - let bob_balance_after_mint = Assets::balance(asset, &BOB); - assert_eq!(bob_balance_after_mint, bob_balance_before_mint + amount / 2); - // Transfer asset to account that does not exist. - assert_eq!( - decoded::(transfer(addr.clone(), asset, FERDIE, amount / 4)), - Token(CannotCreate) - ); - // Asset is not live, i.e. frozen or being destroyed. - start_destroy_asset(asset, ALICE); - assert_eq!( - decoded::(transfer(addr.clone(), asset, BOB, amount / 4)), - Module { index: 52, error: 16 }, - ); }); } diff --git a/pop-api/src/v0/assets/fungibles.rs b/pop-api/src/v0/assets/fungibles.rs index 8d0de768..5325cad3 100644 --- a/pop-api/src/v0/assets/fungibles.rs +++ b/pop-api/src/v0/assets/fungibles.rs @@ -39,7 +39,7 @@ pub fn total_supply(id: AssetId) -> Result { /// # Returns /// The balance of the specified account, or an error if the operation fails. #[inline] -pub fn balance_of(id: AssetId, owner: AccountId) -> Balance { +pub fn balance_of(id: AssetId, owner: AccountId) -> Result { assets::balance_of(id, owner) } @@ -54,7 +54,7 @@ pub fn balance_of(id: AssetId, owner: AccountId) -> Balance { /// # Returns /// The remaining allowance, or an error if the operation fails. #[inline] -pub fn allowance(id: AssetId, owner: AccountId, spender: AccountId) -> Balance { +pub fn allowance(id: AssetId, owner: AccountId, spender: AccountId) -> Result { assets::allowance(id, owner, spender) } @@ -101,6 +101,7 @@ pub fn transfer_from(id: AssetId, from: AccountId, to: AccountId, value: Balance /// Returns `Ok(())` if successful, or an error if the approval fails. #[inline] pub fn approve(id: AssetId, spender: AccountId, value: Balance) -> Result<()> { + assets::cancel_approval(id, spender)?; assets::approve_transfer(id, spender, value) } @@ -128,9 +129,11 @@ pub fn increase_allowance(id: AssetId, spender: AccountId, value: Balance) -> Re /// # Returns /// Returns `Ok(())` if successful, or an error if the operation fails. #[inline] -pub fn decrease_allowance(id: AssetId, spender: AccountId, value: Balance) -> Result<()> { - assets::cancel_approval(id, spender.clone())?; - assets::approve_transfer(id, spender, value) +pub fn decrease_allowance(_id: AssetId, _spender: AccountId, _value: Balance) -> Result<()> { + // let allowance = assets::allowance(id, owner, spender)?; + // assets::cancel_approval(id, spender.clone())?; + // assets::approve_transfer(id, spender, value) + Ok(()) } /// 2. PSP-22 Metadata Interface: @@ -146,7 +149,7 @@ pub fn decrease_allowance(id: AssetId, spender: AccountId, value: Balance) -> Re /// # Returns /// The name of the token as a byte vector, or an error if the operation fails. #[inline] -pub fn token_name(id: AssetId) -> Vec { +pub fn token_name(id: AssetId) -> Result> { assets::token_name(id) } @@ -158,7 +161,7 @@ pub fn token_name(id: AssetId) -> Vec { /// # Returns /// The symbol of the token as a byte vector, or an error if the operation fails. #[inline] -pub fn token_symbol(id: AssetId) -> Vec { +pub fn token_symbol(id: AssetId) -> Result> { assets::token_symbol(id) } @@ -170,7 +173,7 @@ pub fn token_symbol(id: AssetId) -> Vec { /// # Returns /// The number of decimals of the token as a byte vector, or an error if the operation fails. #[inline] -pub fn token_decimals(id: AssetId) -> u8 { +pub fn token_decimals(id: AssetId) -> Result { assets::token_decimals(id) } diff --git a/pop-api/src/v0/assets/mod.rs b/pop-api/src/v0/assets/mod.rs index 22657323..d14c3322 100644 --- a/pop-api/src/v0/assets/mod.rs +++ b/pop-api/src/v0/assets/mod.rs @@ -26,8 +26,11 @@ const TRANSFER_KEEP_ALIVE: u8 = 9; /// - set_metadata /// - clear_metadata /// - approve_transfer +const APPROVE_TRANSFER: u8 = 22; /// - cancel_approval +const CANCEL_APPROVAL: u8 = 23; /// - transfer_approved +const TRANSFER_APPROVED: u8 = 25; /// Issue a new class of fungible assets from a public origin. // pub(crate) fn create( @@ -91,7 +94,7 @@ pub fn transfer(id: AssetId, target: AccountId, amount: Balance) -> Result<()> { VERSION, DISPATCH, ASSETS_MODULE, - // TODO: E.D. is always respected with transferring tokens via the API. + // E.D. is always respected with transferring tokens via the API. TRANSFER_KEEP_ALIVE, ])) .input::<(AssetId, AccountId, Balance)>() @@ -131,21 +134,31 @@ pub fn transfer(id: AssetId, target: AccountId, amount: Balance) -> Result<()> { /// Approve an amount of asset for transfer by a delegated third-party account. #[inline] pub fn approve_transfer(id: AssetId, delegate: AccountId, amount: Balance) -> Result<()> { - ChainExtensionMethod::build(u32::from_le_bytes([0u8, 0, 52, 69])) - .input::<(AssetId, AccountId, Balance)>() - .output::, true>() - .handle_error_code::() - .call(&(id, delegate, amount)) + ChainExtensionMethod::build(u32::from_le_bytes([ + VERSION, + DISPATCH, + ASSETS_MODULE, + APPROVE_TRANSFER, + ])) + .input::<(AssetId, AccountId, Balance)>() + .output::, true>() + .handle_error_code::() + .call(&(id, delegate, amount)) } /// Cancel all of some asset approved for delegated transfer by a third-party account. #[inline] pub fn cancel_approval(id: AssetId, delegate: AccountId) -> Result<()> { - ChainExtensionMethod::build(0) - .input::<(AssetId, AccountId)>() - .output::, true>() - .handle_error_code::() - .call(&(id, delegate)) + ChainExtensionMethod::build(u32::from_le_bytes([ + VERSION, + DISPATCH, + ASSETS_MODULE, + CANCEL_APPROVAL, + ])) + .input::<(AssetId, AccountId)>() + .output::, true>() + .handle_error_code::() + .call(&(id, delegate)) } /// Transfer some asset balance from a previously delegated account to some third-party @@ -157,23 +170,33 @@ pub fn transfer_approved( to: AccountId, amount: Balance, ) -> Result<()> { - ChainExtensionMethod::build(0) - .input::<(AssetId, AccountId, AccountId, Balance)>() - .output::, true>() - .handle_error_code::() - .call(&(id, from, to, amount)) + ChainExtensionMethod::build(u32::from_le_bytes([ + VERSION, + DISPATCH, + ASSETS_MODULE, + TRANSFER_APPROVED, + ])) + .input::<(AssetId, AccountId, AccountId, Balance)>() + .output::, true>() + .handle_error_code::() + .call(&(id, from, to, amount)) } -/// 2. Read state functions +/// 2. Read state functions: const READ_STATE: u8 = 1; /// - total_supply const TOTAL_SUPPLY: u8 = 0; /// - balance_of +const BALANCE_OF: u8 = 1; /// - allowance -/// - asset_exists +const ALLOWANCE: u8 = 2; /// - token_name +const TOKEN_NAME: u8 = 3; /// - token_symbol +const TOKEN_SYMBOL: u8 = 4; /// - token_decimals +const TOKEN_DECIMALS: u8 = 5; +/// - asset_exists #[inline] pub fn total_supply(id: AssetId) -> Result { @@ -191,48 +214,73 @@ pub fn total_supply(id: AssetId) -> Result { } #[inline] -pub fn balance_of(id: AssetId, owner: AccountId) -> Balance { - ChainExtensionMethod::build(1) - .input::<(AssetId, AccountId)>() - .output::() - .ignore_error_code() - .call(&(id, owner)) +pub fn balance_of(id: AssetId, owner: AccountId) -> Result { + ChainExtensionMethod::build(u32::from_le_bytes([ + VERSION, + READ_STATE, + ASSETS_MODULE, + BALANCE_OF, + ])) + .input::<(AssetId, AccountId)>() + .output::>, true>() + .handle_error_code::() + .call(&(id, owner)) + .and_then(|v| Balance::decode(&mut &v[..]).map_err(|_e| StatusCode(255u32))) } #[inline] -pub fn allowance(id: AssetId, owner: AccountId, spender: AccountId) -> Balance { - ChainExtensionMethod::build(1) +pub fn allowance(id: AssetId, owner: AccountId, spender: AccountId) -> Result { + ChainExtensionMethod::build(u32::from_le_bytes([VERSION, READ_STATE, ASSETS_MODULE, ALLOWANCE])) .input::<(AssetId, AccountId, AccountId)>() - .output::() - .ignore_error_code() + .output::>, true>() + .handle_error_code::() .call(&(id, owner, spender)) + .and_then(|v| Balance::decode(&mut &v[..]).map_err(|_e| StatusCode(255u32))) } #[inline] -pub fn token_name(id: AssetId) -> Vec { - ChainExtensionMethod::build(1) - .input::() - .output::, false>() - .ignore_error_code() - .call(&(id)) +pub fn token_name(id: AssetId) -> Result> { + ChainExtensionMethod::build(u32::from_le_bytes([ + VERSION, + READ_STATE, + ASSETS_MODULE, + TOKEN_NAME, + ])) + .input::() + .output::>, true>() + .handle_error_code::() + .call(&(id)) + .and_then(|v| >::decode(&mut &v[..]).map_err(|_e| StatusCode(255u32))) } // #[inline] -pub fn token_symbol(id: AssetId) -> Vec { - ChainExtensionMethod::build(1) - .input::() - .output::, false>() - .ignore_error_code() - .call(&(id)) +pub fn token_symbol(id: AssetId) -> Result> { + ChainExtensionMethod::build(u32::from_le_bytes([ + VERSION, + READ_STATE, + ASSETS_MODULE, + TOKEN_SYMBOL, + ])) + .input::() + .output::>, true>() + .handle_error_code::() + .call(&(id)) + .and_then(|v| >::decode(&mut &v[..]).map_err(|_e| StatusCode(255u32))) } #[inline] -pub fn token_decimals(id: AssetId) -> u8 { - ChainExtensionMethod::build(1) - .input::() - .output::() - .ignore_error_code() - .call(&(id)) +pub fn token_decimals(id: AssetId) -> Result { + ChainExtensionMethod::build(u32::from_le_bytes([ + VERSION, + READ_STATE, + ASSETS_MODULE, + TOKEN_DECIMALS, + ])) + .input::() + .output::>, true>() + .handle_error_code::() + .call(&(id)) + .and_then(|v| ::decode(&mut &v[..]).map_err(|_e| StatusCode(255u32))) } // pub(crate) fn asset_exists(id: AssetId) -> Result { diff --git a/runtime/devnet/src/config/mod.rs b/runtime/devnet/src/config/mod.rs index c370bb1d..e0aaa3a1 100644 --- a/runtime/devnet/src/config/mod.rs +++ b/runtime/devnet/src/config/mod.rs @@ -1,4 +1,4 @@ -pub(crate) mod assets; +pub mod assets; mod contracts; mod proxy; // Public due to integration tests crate. diff --git a/runtime/devnet/src/extensions/mod.rs b/runtime/devnet/src/extensions/mod.rs index ac52d5bd..8f0a6eda 100644 --- a/runtime/devnet/src/extensions/mod.rs +++ b/runtime/devnet/src/extensions/mod.rs @@ -5,7 +5,7 @@ use frame_support::{ dispatch::{GetDispatchInfo, RawOrigin}, pallet_prelude::*, traits::{ - fungibles::approvals::Inspect as ApprovalInspect, + fungibles::{approvals::Inspect as ApprovalInspect, metadata::Inspect as MetadataInspect}, nonfungibles_v2::Inspect as NonFungiblesInspect, }, }; @@ -129,8 +129,7 @@ where E: Ext, { const LOG_PREFIX: &str = " dispatch |"; - let call = construct_call(version, pallet_index, call_index, params) - .map_err(|_| DispatchError::Other("DecodingFailed"))?; + let call = construct_call(version, pallet_index, call_index, params)?; // Contract is the origin by default. let origin: RuntimeOrigin = RawOrigin::Signed(env.ext().address().clone()).into(); dispatch_call::(env, call, origin, LOG_PREFIX) @@ -434,6 +433,15 @@ where T: frame_system::Config, { match key { + TotalSupply(id) => { + env.charge_weight(T::DbWeight::get().reads(1_u64))?; + Ok(pallet_assets::Pallet::::total_supply(id).encode()) + }, + BalanceOf(id, owner) => { + env.charge_weight(T::DbWeight::get().reads(1_u64))?; + Ok(pallet_assets::Pallet::::balance(id, &owner.0.into()) + .encode()) + }, Allowance(id, owner, spender) => { env.charge_weight(T::DbWeight::get().reads(1_u64))?; Ok(pallet_assets::Pallet::::allowance( @@ -443,20 +451,31 @@ where ) .encode()) }, - // AssetsKeys::AssetExists(id) => { - // env.charge_weight(T::DbWeight::get().reads(1_u64))?; - // Ok(pallet_assets::Pallet::::asset_exists(id).encode()) - // }, - BalanceOf(id, owner) => { + TokenName(id) => { env.charge_weight(T::DbWeight::get().reads(1_u64))?; - Ok(pallet_assets::Pallet::::balance(id, &owner.0.into()) - .encode()) + Ok( as MetadataInspect< + AccountId, + >>::name(id) + .encode()) }, - TotalSupply(id) => { + TokenSymbol(id) => { env.charge_weight(T::DbWeight::get().reads(1_u64))?; - Ok(pallet_assets::Pallet::::total_supply(id).encode()) + Ok( as MetadataInspect< + AccountId, + >>::symbol(id) + .encode()) }, - _ => todo!(), + TokenDecimals(id) => { + env.charge_weight(T::DbWeight::get().reads(1_u64))?; + Ok( as MetadataInspect< + AccountId, + >>::decimals(id) + .encode()) + }, + // AssetsKeys::AssetExists(id) => { + // env.charge_weight(T::DbWeight::get().reads(1_u64))?; + // Ok(pallet_assets::Pallet::::asset_exists(id).encode()) + // }, } } diff --git a/runtime/devnet/src/extensions/v0/assets.rs b/runtime/devnet/src/extensions/v0/assets.rs index 912b116f..407b0d55 100644 --- a/runtime/devnet/src/extensions/v0/assets.rs +++ b/runtime/devnet/src/extensions/v0/assets.rs @@ -1,8 +1,9 @@ use crate::extensions::{ - AccountId, AssetId, - AssetsKeys::{self, TotalSupply}, + AccountId as AccountId32, AssetId, + AssetsKeys::{self, *}, Balance, Compact, Decode, DispatchError, MultiAddress, Runtime, TrustBackedAssetsInstance, }; +use pop_primitives::AccountId; pub(crate) fn construct_assets_key( call_index: u8, @@ -14,6 +15,31 @@ pub(crate) fn construct_assets_key( .map_err(|_| DispatchError::Other("DecodingFailed"))?; Ok(TotalSupply(id)) }, + 1 => { + let (id, owner) = <(AssetId, AccountId)>::decode(&mut ¶ms[..]) + .map_err(|_| DispatchError::Other("DecodingFailed"))?; + Ok(BalanceOf(id, owner)) + }, + 2 => { + let (id, owner, spender) = <(AssetId, AccountId, AccountId)>::decode(&mut ¶ms[..]) + .map_err(|_| DispatchError::Other("DecodingFailed"))?; + Ok(Allowance(id, owner, spender)) + }, + 3 => { + let id = ::decode(&mut ¶ms[..]) + .map_err(|_| DispatchError::Other("DecodingFailed"))?; + Ok(TokenName(id)) + }, + 4 => { + let id = ::decode(&mut ¶ms[..]) + .map_err(|_| DispatchError::Other("DecodingFailed"))?; + Ok(TokenSymbol(id)) + }, + 5 => { + let id = ::decode(&mut ¶ms[..]) + .map_err(|_| DispatchError::Other("DecodingFailed"))?; + Ok(TokenDecimals(id)) + }, // other calls _ => Err(DispatchError::Other("UnknownFunctionId")), } @@ -25,7 +51,7 @@ pub(crate) fn construct_assets_call( ) -> Result, DispatchError> { match call_index { 9 => { - let (id, target, amount) = <(AssetId, AccountId, Balance)>::decode(&mut ¶ms[..]) + let (id, target, amount) = <(AssetId, AccountId32, Balance)>::decode(&mut ¶ms[..]) .map_err(|_| DispatchError::Other("DecodingFailed"))?; Ok(pallet_assets::Call::::transfer_keep_alive { id: Compact(id), @@ -33,6 +59,16 @@ pub(crate) fn construct_assets_call( amount, }) }, + 22 => { + let (id, delegate, amount) = + <(AssetId, AccountId32, Balance)>::decode(&mut ¶ms[..]) + .map_err(|_| DispatchError::Other("DecodingFailed"))?; + Ok(pallet_assets::Call::::approve_transfer { + id: Compact(id), + delegate: MultiAddress::Id(delegate), + amount, + }) + }, // other calls _ => Err(DispatchError::Other("UnknownFunctionId")), } From 47e2ea6770d0b6fe8fe5b611570cdfa772ed4c04 Mon Sep 17 00:00:00 2001 From: Daanvdplas Date: Fri, 5 Jul 2024 23:49:03 +0200 Subject: [PATCH 018/112] refactor: final bits --- pop-api/src/v0/assets/fungibles.rs | 10 +++++----- pop-api/src/v0/assets/mod.rs | 17 ++--------------- runtime/devnet/src/extensions/mod.rs | 1 + runtime/devnet/src/extensions/v0/assets.rs | 1 + runtime/testnet/src/extensions.rs | 1 + 5 files changed, 10 insertions(+), 20 deletions(-) diff --git a/pop-api/src/v0/assets/fungibles.rs b/pop-api/src/v0/assets/fungibles.rs index 5325cad3..4abd46a6 100644 --- a/pop-api/src/v0/assets/fungibles.rs +++ b/pop-api/src/v0/assets/fungibles.rs @@ -70,7 +70,7 @@ pub fn allowance(id: AssetId, owner: AccountId, spender: AccountId) -> Result Result<()> { - assets::transfer(id, to, value) + assets::transfer_keep_alive(id, to, value) } /// Transfers `value` tokens on behalf of `from` to account `to` with additional `data` @@ -279,7 +279,6 @@ pub fn token_decimals(id: AssetId) -> Result { // assets::asset_exists(id) // } -// TODO: further implement the rest of the interfaces and conclude on the FungiblesError. #[derive(Debug, PartialEq, Eq)] #[ink::scale_derive(Encode, Decode, TypeInfo)] pub enum FungiblesError { @@ -300,13 +299,14 @@ pub enum FungiblesError { NoPermission, /// The given asset ID is unknown. Unknown, - // - Originally `InsufficientBalance` for the deposit but this would result in the same error - // as the error when there is insufficient balance for transferring an asset. /// No balance for creation of assets or fees. + // + // Originally `pallet_balances::Error::InsufficientBalance` but collides with the + // `InsufficientBalance` error that is used for `pallet_assets::Error::BalanceLow` to adhere to + // standard. NoBalance, } -// TODO: include conversions from TokenError and add conversions based on added interfaces. impl From for FungiblesError { fn from(value: StatusCode) -> Self { let encoded = value.0.to_le_bytes(); diff --git a/pop-api/src/v0/assets/mod.rs b/pop-api/src/v0/assets/mod.rs index d14c3322..ea8991a7 100644 --- a/pop-api/src/v0/assets/mod.rs +++ b/pop-api/src/v0/assets/mod.rs @@ -87,9 +87,9 @@ const TRANSFER_APPROVED: u8 = 25; // })) // } -/// Move some assets from the sender account to another. +/// Move some assets from the sender account to another, keeping the sender account alive. #[inline] -pub fn transfer(id: AssetId, target: AccountId, amount: Balance) -> Result<()> { +pub fn transfer_keep_alive(id: AssetId, target: AccountId, amount: Balance) -> Result<()> { ChainExtensionMethod::build(u32::from_le_bytes([ VERSION, DISPATCH, @@ -103,19 +103,6 @@ pub fn transfer(id: AssetId, target: AccountId, amount: Balance) -> Result<()> { .call(&(id, target, amount)) } -// /// Move some assets from the sender account to another, keeping the sender account alive. -// pub(crate) fn transfer_keep_alive( -// id: AssetId, -// target: impl Into>, -// amount: Balance, -// ) -> Result<()> { -// dispatch(RuntimeCall::Assets(AssetsCall::TransferKeepAlive { -// id: id.into(), -// target: target.into(), -// amount: Compact(amount), -// })) -// } - // /// Set the metadata for an asset. // pub(crate) fn set_metadata( // id: AssetId, diff --git a/runtime/devnet/src/extensions/mod.rs b/runtime/devnet/src/extensions/mod.rs index 8f0a6eda..aa58bcea 100644 --- a/runtime/devnet/src/extensions/mod.rs +++ b/runtime/devnet/src/extensions/mod.rs @@ -304,6 +304,7 @@ where // - `error`: The `DispatchError` encountered during contract execution. // - `version`: The version of the chain extension, used to determine the known errors. pub(crate) fn convert_to_status_code(error: DispatchError, version: u8) -> u32 { + use sp_std::vec; // "UnknownFunctionId" and "DecodingFailed" are mapped to specific errors in the API and will // never change. let mut encoded_error = match error { diff --git a/runtime/devnet/src/extensions/v0/assets.rs b/runtime/devnet/src/extensions/v0/assets.rs index 407b0d55..c6b15b4e 100644 --- a/runtime/devnet/src/extensions/v0/assets.rs +++ b/runtime/devnet/src/extensions/v0/assets.rs @@ -4,6 +4,7 @@ use crate::extensions::{ Balance, Compact, Decode, DispatchError, MultiAddress, Runtime, TrustBackedAssetsInstance, }; use pop_primitives::AccountId; +use sp_std::vec::Vec; pub(crate) fn construct_assets_key( call_index: u8, diff --git a/runtime/testnet/src/extensions.rs b/runtime/testnet/src/extensions.rs index 4c224544..a5eeb3c3 100644 --- a/runtime/testnet/src/extensions.rs +++ b/runtime/testnet/src/extensions.rs @@ -206,6 +206,7 @@ where RuntimeStateKeys::ParachainSystem(key) => { read_parachain_system_state::(key, &mut env) }, + _ => Ok(vec![0]), }? .encode(); From 9dcfccbe414ef4de57d12e59db6841fcbed9eeee Mon Sep 17 00:00:00 2001 From: Daanvdplas Date: Sat, 6 Jul 2024 10:05:17 +0200 Subject: [PATCH 019/112] fix: compiling --- Cargo.lock | 46 +++++++++++++++++++--------- Cargo.toml | 14 ++++----- runtime/devnet/src/extensions/mod.rs | 1 - runtime/testnet/src/extensions.rs | 2 +- 4 files changed, 40 insertions(+), 23 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index cf7abf73..e0c87955 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -426,9 +426,9 @@ checksum = "9b34d609dfbaf33d6889b2b7106d3ca345eacad44200913df5ba02bfd31d2ba9" [[package]] name = "asset-hub-rococo-runtime" -version = "0.12.0" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e80dcb69497d50ceef11a046720e1c5a0feeb5575239c5ccb4b0be14a49bcfa" +checksum = "af52c4d3011936f615f3469b3c20f8b13b861f4c06d097bc1922200ce44781d9" dependencies = [ "assets-common", "bp-asset-hub-rococo", @@ -445,6 +445,7 @@ dependencies = [ "cumulus-primitives-utility", "frame-benchmarking", "frame-executive", + "frame-metadata-hash-extension", "frame-support", "frame-system", "frame-system-benchmarking", @@ -3747,6 +3748,22 @@ dependencies = [ "serde", ] +[[package]] +name = "frame-metadata-hash-extension" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5bb1eec9eb46d3e016c95b2fa875118c04609f2150013c56a894cae00581e265" +dependencies = [ + "array-bytes 6.2.2", + "docify", + "frame-support", + "frame-system", + "log", + "parity-scale-codec", + "scale-info", + "sp-runtime", +] + [[package]] name = "frame-remote-externalities" version = "0.36.0" @@ -6979,9 +6996,9 @@ dependencies = [ [[package]] name = "pallet-collator-selection" -version = "10.0.2" +version = "10.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49d1157d9a4b7966040158a7b4f1fb29f0cefa8deb6eb9b3452df7ce4161a31c" +checksum = "a36858c4275b7d19671b321e95f545e07c9643f97dffed1b333774cb391a4456" dependencies = [ "frame-benchmarking", "frame-support", @@ -7827,9 +7844,9 @@ dependencies = [ [[package]] name = "pallet-transaction-payment" -version = "29.0.1" +version = "29.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b0c408252aefe10cff96af1e54f06f45cb0dd184b4e450e9a2ecf837dfe506e" +checksum = "5a5ba71f06f09e955b80dc313c333be3f8d9e8505b051558e0b7af4806b13310" dependencies = [ "frame-support", "frame-system", @@ -8023,9 +8040,9 @@ dependencies = [ [[package]] name = "parachains-common" -version = "8.0.0" +version = "8.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d34aa00981a24a2b772afaa49e258f9bcd6bb372db060a05614becc1c74d4456" +checksum = "711a4c073e7c83aac7e414ba16c7c641d6d9e22e6d32f9775ff35b2464ffd7ff" dependencies = [ "cumulus-primitives-core", "cumulus-primitives-utility", @@ -9255,9 +9272,9 @@ dependencies = [ [[package]] name = "polkadot-runtime-common" -version = "8.0.2" +version = "8.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d815f0ff0a69dce7235d42c6e7d5e2b8b7429cba1252b4802ddc7879e2e74d4a" +checksum = "12a70422ca43d30457e2d9502a5e4af35e20fa2ff3f7cd46e0d2997c784f2665" dependencies = [ "bitvec", "frame-benchmarking", @@ -10518,13 +10535,14 @@ dependencies = [ [[package]] name = "rococo-runtime" -version = "8.0.0" +version = "8.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d089e93be2b8b76dd0d4b794a6a995ca3a1d6cb0ea3dd1cd42462f048bcfc926" +checksum = "cfa4cc054efdd3bfbec965da01b1ae16475031308c109c173347717091f6e3a5" dependencies = [ "binary-merkle-tree", "frame-benchmarking", "frame-executive", + "frame-metadata-hash-extension", "frame-support", "frame-system", "frame-system-benchmarking", @@ -13959,9 +13977,9 @@ dependencies = [ [[package]] name = "staging-xcm-builder" -version = "8.0.2" +version = "8.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "988d765ad5ab3b5cc90bb1dd143153ebdbe2b7600e10d5ef3a7f3e8df1bdac5d" +checksum = "78b7447c38be3ca9fb21c7434de2243aa6ac74acde8944cda7bb6e2a4f765801" dependencies = [ "frame-support", "frame-system", diff --git a/Cargo.toml b/Cargo.toml index 3719e83d..6b3cde02 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -97,7 +97,7 @@ pallet-scheduler = { version = "30.0.0", default-features = false } pallet-session = { version = "29.0.0", default-features = false } pallet-sudo = { version = "29.0.0", default-features = false } pallet-timestamp = { version = "28.0.0", default-features = false } -pallet-transaction-payment = { version = "29.0.1", default-features = false } +pallet-transaction-payment = { version = "29.0.2", default-features = false } pallet-transaction-payment-rpc = "31.0.0" pallet-transaction-payment-rpc-runtime-api = { version = "29.0.0", default-features = false } pallet-utility = { version = "29.0.0", default-features = false } @@ -130,15 +130,15 @@ polkadot-cli = "8.0.0" polkadot-parachain-primitives = { version = "7.0.0", default-features = false } polkadot-runtime-parachains = { version = "8.0.3", default-features = false } polkadot-primitives = { version = "8.0.1", default-features = false } -polkadot-runtime-common = { version = "8.0.2", default-features = false } +polkadot-runtime-common = { version = "8.0.3", default-features = false } rococo-runtime-constants = { version = "8.0.0", default-features = false } -rococo-runtime = { version = "8.0.0", default-features = false } +rococo-runtime = { version = "8.0.1", default-features = false } xcm = { version = "8.0.1", package = "staging-xcm", default-features = false } -xcm-builder = { version = "8.0.2", package = "staging-xcm-builder", default-features = false } +xcm-builder = { version = "8.0.3", package = "staging-xcm-builder", default-features = false } xcm-executor = { version = "8.0.2", package = "staging-xcm-executor", default-features = false } # Cumulus -asset-hub-rococo-runtime = { version = "0.12.0", default-features = false } +asset-hub-rococo-runtime = { version = "0.12.3", default-features = false } asset-test-utils = { version = "8.0.1", default-features = false } cumulus-pallet-aura-ext = { version = "0.8.0", default-features = false } cumulus-pallet-parachain-system = { version = "0.8.1", default-features = false, features = ["parameterized-consensus-hook"] } @@ -149,8 +149,8 @@ cumulus-primitives-aura = { version = "0.8.0", default-features = false } cumulus-primitives-core = { version = "0.8.0", default-features = false } cumulus-primitives-utility = { version = "0.8.1", default-features = false } emulated-integration-tests-common = { version = "4.0.0", default-features = false } -pallet-collator-selection = { version = "10.0.2", default-features = false } -parachains-common = { version = "8.0.0", default-features = false } +pallet-collator-selection = { version = "10.0.3", default-features = false } +parachains-common = { version = "8.0.1", default-features = false } parachain-info = { version = "0.8.0", package = "staging-parachain-info", default-features = false } cumulus-primitives-parachain-inherent = "0.8.0" cumulus-relay-chain-interface = "0.8.0" diff --git a/runtime/devnet/src/extensions/mod.rs b/runtime/devnet/src/extensions/mod.rs index aa58bcea..8f0a6eda 100644 --- a/runtime/devnet/src/extensions/mod.rs +++ b/runtime/devnet/src/extensions/mod.rs @@ -304,7 +304,6 @@ where // - `error`: The `DispatchError` encountered during contract execution. // - `version`: The version of the chain extension, used to determine the known errors. pub(crate) fn convert_to_status_code(error: DispatchError, version: u8) -> u32 { - use sp_std::vec; // "UnknownFunctionId" and "DecodingFailed" are mapped to specific errors in the API and will // never change. let mut encoded_error = match error { diff --git a/runtime/testnet/src/extensions.rs b/runtime/testnet/src/extensions.rs index a5eeb3c3..61d3cb43 100644 --- a/runtime/testnet/src/extensions.rs +++ b/runtime/testnet/src/extensions.rs @@ -206,7 +206,7 @@ where RuntimeStateKeys::ParachainSystem(key) => { read_parachain_system_state::(key, &mut env) }, - _ => Ok(vec![0]), + _ => Ok(vec![0u8]), }? .encode(); From b067edac54c1cb375dfa72472c03fab75aaa99d2 Mon Sep 17 00:00:00 2001 From: Daanvdplas Date: Tue, 16 Jul 2024 18:27:27 +0200 Subject: [PATCH 020/112] fix: cannot find macro vec error --- Cargo.lock | 1489 +++++++++++++------------- runtime/devnet/Cargo.toml | 2 +- runtime/devnet/src/extensions/mod.rs | 4 +- runtime/testnet/src/extensions.rs | 2 +- 4 files changed, 755 insertions(+), 742 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e0c87955..1983b157 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -23,11 +23,11 @@ dependencies = [ [[package]] name = "addr2line" -version = "0.21.0" +version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +checksum = "6e4503c46a5c0c7844e948c9a4d6acd9f50cccb4de1c48eb9e291ea17470c678" dependencies = [ - "gimli 0.28.1", + "gimli 0.29.0", ] [[package]] @@ -68,7 +68,7 @@ dependencies = [ "cipher 0.4.4", "ctr", "ghash", - "subtle 2.5.0", + "subtle 2.6.1", ] [[package]] @@ -77,7 +77,7 @@ version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "891477e0c6a8957309ee5c45a6368af3ae14bb510732d2684ffa19af310920f9" dependencies = [ - "getrandom 0.2.12", + "getrandom 0.2.15", "once_cell", "version_check", ] @@ -89,7 +89,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" dependencies = [ "cfg-if", - "getrandom 0.2.12", + "getrandom 0.2.15", "once_cell", "version_check", "zerocopy", @@ -106,9 +106,9 @@ dependencies = [ [[package]] name = "allocator-api2" -version = "0.2.16" +version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" +checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f" [[package]] name = "always-assert" @@ -142,47 +142,48 @@ dependencies = [ [[package]] name = "anstream" -version = "0.6.13" +version = "0.6.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d96bd03f33fe50a863e394ee9718a706f988b9079b20c3784fb726e7678b62fb" +checksum = "418c75fa768af9c03be99d17643f93f79bbba589895012a80e3452a19ddda15b" dependencies = [ "anstyle", "anstyle-parse", "anstyle-query", "anstyle-wincon", "colorchoice", + "is_terminal_polyfill", "utf8parse", ] [[package]] name = "anstyle" -version = "1.0.6" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8901269c6307e8d93993578286ac0edf7f195079ffff5ebdeea6a59ffb7e36bc" +checksum = "038dfcf04a5feb68e9c60b21c9625a54c2c0616e79b72b0fd87075a056ae1d1b" [[package]] name = "anstyle-parse" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c75ac65da39e5fe5ab759307499ddad880d724eed2f6ce5b5e8a26f4f387928c" +checksum = "c03a11a9034d92058ceb6ee011ce58af4a9bf61491aa7e1e59ecd24bd40d22d4" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" -version = "1.0.2" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648" +checksum = "ad186efb764318d35165f1758e7dcef3b10628e26d41a44bc5550652e6804391" dependencies = [ "windows-sys 0.52.0", ] [[package]] name = "anstyle-wincon" -version = "3.0.2" +version = "3.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7" +checksum = "61a38449feb7068f52bb06c12759005cf459ee52bb4adc1d5a7c4322d716fb19" dependencies = [ "anstyle", "windows-sys 0.52.0", @@ -190,9 +191,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.81" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0952808a6c2afd1aa8947271f3a60f1a6763c7b912d210184c5149b5cf147247" +checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" [[package]] name = "approx" @@ -214,7 +215,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.71", ] [[package]] @@ -354,9 +355,9 @@ checksum = "f52f63c5c1316a16a4b35eaac8b76a98248961a533f061684cb2a7cb0eafb6c6" [[package]] name = "array-bytes" -version = "6.2.2" +version = "6.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f840fb7195bcfc5e17ea40c26e5ce6d5b9ce5d584466e17703209657e459ae0" +checksum = "5d5dde061bd34119e902bbb2d9b90c5692635cf59fb91d582c2b68043f1b8293" [[package]] name = "arrayref" @@ -404,7 +405,7 @@ dependencies = [ "proc-macro2", "quote", "syn 1.0.109", - "synstructure", + "synstructure 0.12.6", ] [[package]] @@ -573,27 +574,25 @@ dependencies = [ [[package]] name = "async-channel" -version = "2.2.0" +version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f28243a43d821d11341ab73c80bed182dc015c514b951616cf79bd4af39af0c3" +checksum = "89b47800b0be77592da0afd425cc03468052844aff33b84e33cc696f64e77b6a" dependencies = [ "concurrent-queue", - "event-listener 5.2.0", - "event-listener-strategy 0.5.1", + "event-listener-strategy", "futures-core", "pin-project-lite 0.2.14", ] [[package]] name = "async-executor" -version = "1.9.1" +version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10b3e585719c2358d2660232671ca8ca4ddb4be4ce8a1842d6c2dc8685303316" +checksum = "d7ebdfa2ebdab6b1760375fa7d6f382b9f486eac35fc994625a00e89280bdbb7" dependencies = [ - "async-lock 3.3.0", "async-task", "concurrent-queue", - "fastrand 2.0.2", + "fastrand 2.1.0", "futures-lite 2.3.0", "slab", ] @@ -612,11 +611,11 @@ dependencies = [ [[package]] name = "async-fs" -version = "2.1.1" +version = "2.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc19683171f287921f2405677dd2ed2549c3b3bda697a563ebc3a121ace2aba1" +checksum = "ebcd09b382f40fcd159c2d695175b2ae620ffa5f3bd6f664131efff4e8b9e04a" dependencies = [ - "async-lock 3.3.0", + "async-lock 3.4.0", "blocking", "futures-lite 2.3.0", ] @@ -643,18 +642,18 @@ dependencies = [ [[package]] name = "async-io" -version = "2.3.2" +version = "2.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcccb0f599cfa2f8ace422d3555572f47424da5648a4382a9dd0310ff8210884" +checksum = "0d6baa8f0178795da0e71bc42c9e5d13261aac7ee549853162e66a241ba17964" dependencies = [ - "async-lock 3.3.0", + "async-lock 3.4.0", "cfg-if", "concurrent-queue", "futures-io", "futures-lite 2.3.0", "parking", - "polling 3.6.0", - "rustix 0.38.32", + "polling 3.7.2", + "rustix 0.38.34", "slab", "tracing", "windows-sys 0.52.0", @@ -671,12 +670,12 @@ dependencies = [ [[package]] name = "async-lock" -version = "3.3.0" +version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d034b430882f8381900d3fe6f0aaa3ad94f2cb4ac519b429692a1bc2dda4ae7b" +checksum = "ff6e472cdea888a4bd64f342f09b3f50e1886d32afe8df3d663c01140b811b18" dependencies = [ - "event-listener 4.0.3", - "event-listener-strategy 0.4.0", + "event-listener 5.3.1", + "event-listener-strategy", "pin-project-lite 0.2.14", ] @@ -697,7 +696,7 @@ version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b948000fad4873c1c9339d60f2623323a0cfd3816e5181033c6a5cb68b2accf7" dependencies = [ - "async-io 2.3.2", + "async-io 2.3.3", "blocking", "futures-lite 2.3.0", ] @@ -715,61 +714,63 @@ dependencies = [ "cfg-if", "event-listener 3.1.0", "futures-lite 1.13.0", - "rustix 0.38.32", + "rustix 0.38.34", "windows-sys 0.48.0", ] [[package]] name = "async-process" -version = "2.1.0" +version = "2.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "451e3cf68011bd56771c79db04a9e333095ab6349f7e47592b788e9b98720cc8" +checksum = "f7eda79bbd84e29c2b308d1dc099d7de8dcc7035e48f4bf5dc4a531a44ff5e2a" dependencies = [ - "async-channel 2.2.0", - "async-io 2.3.2", - "async-lock 3.3.0", + "async-channel 2.3.1", + "async-io 2.3.3", + "async-lock 3.4.0", "async-signal", + "async-task", "blocking", "cfg-if", - "event-listener 5.2.0", + "event-listener 5.3.1", "futures-lite 2.3.0", - "rustix 0.38.32", + "rustix 0.38.34", + "tracing", "windows-sys 0.52.0", ] [[package]] name = "async-signal" -version = "0.2.5" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e47d90f65a225c4527103a8d747001fc56e375203592b25ad103e1ca13124c5" +checksum = "794f185324c2f00e771cd9f1ae8b5ac68be2ca7abb129a87afd6e86d228bc54d" dependencies = [ - "async-io 2.3.2", - "async-lock 2.8.0", + "async-io 2.3.3", + "async-lock 3.4.0", "atomic-waker", "cfg-if", "futures-core", "futures-io", - "rustix 0.38.32", + "rustix 0.38.34", "signal-hook-registry", "slab", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] name = "async-task" -version = "4.7.0" +version = "4.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbb36e985947064623dbd357f727af08ffd077f93d696782f3c56365fa2e2799" +checksum = "8b75356056920673b02621b35afd0f7dda9306d03c79a30f5c56c44cf256e3de" [[package]] name = "async-trait" -version = "0.1.79" +version = "0.1.81" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a507401cad91ec6a857ed5513a2073c82a9b9048762b885bb98655b306964681" +checksum = "6e0c28dcc82d7c8ead5cb13beb15405b57b8546e93215673ff8ca0349a028107" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.71", ] [[package]] @@ -799,22 +800,22 @@ checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" [[package]] name = "autocfg" -version = "1.2.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1fdabc7756949593fe60f30ec81974b613357de856987752631dea1e3394c80" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "backtrace" -version = "0.3.71" +version = "0.3.73" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26b05800d2e817c8b3b4b54abd461726265fa9789ae34330622f2db9ee696f9d" +checksum = "5cc23269a4f8976d0a4d2e7109211a419fe30e8d88d677cd60b6bc79c5732e0a" dependencies = [ - "addr2line 0.21.0", + "addr2line 0.22.0", "cc", "cfg-if", "libc", "miniz_oxide", - "object 0.32.2", + "object 0.36.1", "rustc-demangle", ] @@ -848,6 +849,12 @@ version = "0.21.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" +[[package]] +name = "base64" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" + [[package]] name = "base64ct" version = "1.6.0" @@ -894,13 +901,13 @@ dependencies = [ "lazy_static", "lazycell", "peeking_take_while", - "prettyplease 0.2.17", + "prettyplease 0.2.20", "proc-macro2", "quote", "regex", "rustc-hash", "shlex", - "syn 2.0.58", + "syn 2.0.71", ] [[package]] @@ -930,9 +937,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.5.0" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" [[package]] name = "bitvec" @@ -1002,9 +1009,9 @@ dependencies = [ [[package]] name = "blake3" -version = "1.5.1" +version = "1.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30cca6d3674597c30ddf2c587bf8d9d65c9a84d2326d941cc79c9842dfe0ef52" +checksum = "e9ec96fe9a81b5e365f9db71fe00edc4fe4ca2cc7dcb7861f0603012a7caa210" dependencies = [ "arrayref", "arrayvec 0.7.4", @@ -1033,18 +1040,15 @@ dependencies = [ [[package]] name = "blocking" -version = "1.5.1" +version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a37913e8dc4ddcc604f0c6d3bf2887c995153af3611de9e23c352b44c1b9118" +checksum = "703f41c54fc768e63e091340b424302bb1c29ef4aa0c7f10fe849dfb114d29ea" dependencies = [ - "async-channel 2.2.0", - "async-lock 3.3.0", + "async-channel 2.3.1", "async-task", - "fastrand 2.0.2", "futures-io", "futures-lite 2.3.0", "piper", - "tracing", ] [[package]] @@ -1152,9 +1156,9 @@ dependencies = [ [[package]] name = "bp-header-chain" -version = "0.8.0" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96157f586811969b3911d26cc79e02b28cfbecf859d96d7c12b6af10b9ea9350" +checksum = "1c4d2c457d5e18a5dbfe47a2ecd01f95036930a4a7ac0f3e47c2843bb067331b" dependencies = [ "bp-runtime", "finality-grandpa", @@ -1364,9 +1368,9 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.15.4" +version = "3.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ff69b9dd49fd426c69a0db9fc04dd934cdb6645ff000864d98f7e2af8830eaa" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" [[package]] name = "byte-slice-cast" @@ -1382,9 +1386,9 @@ checksum = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7" [[package]] name = "bytemuck" -version = "1.15.0" +version = "1.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d6d68c57235a3a081186990eca2867354726650f42f7516ca50c28d6281fd15" +checksum = "b236fc92302c97ed75b38da1f4917b5cdda4984745740f153a5d3059e48d725e" [[package]] name = "byteorder" @@ -1394,9 +1398,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.6.0" +version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9" +checksum = "a12916984aab3fa6e39d655a33e09c0071eb36d6ab3aea5c2d78551f1df6d952" [[package]] name = "bzip2-sys" @@ -1421,9 +1425,9 @@ dependencies = [ [[package]] name = "camino" -version = "1.1.6" +version = "1.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c59e92b5a388f549b863a7bea62612c09f24c8393560709a54558a9abdfb3b9c" +checksum = "e0ec6b951b160caa93cc0c7b209e5a3bff7aae9062213451ac99493cd844c239" dependencies = [ "serde", ] @@ -1445,7 +1449,7 @@ checksum = "eee4243f1f26fc7a42710e7439c149e2b10b05472f88090acce52632f231a73a" dependencies = [ "camino", "cargo-platform", - "semver 1.0.22", + "semver 1.0.23", "serde", "serde_json", "thiserror", @@ -1453,9 +1457,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.0.90" +version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8cd6604a82acf3039f1144f54b8eb34e91ffba622051189e71b781822d5ee1f5" +checksum = "324c74f2155653c90b04f25b2a47a8a631360cb908f92a772695f430c7e31052" dependencies = [ "jobserver", "libc", @@ -1472,9 +1476,9 @@ dependencies = [ [[package]] name = "cfg-expr" -version = "0.15.7" +version = "0.15.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa50868b64a9a6fda9d593ce778849ea8715cd2a3d2cc17ffdb4a2f2f2f1961d" +checksum = "d067ad48b8650848b989a59a86c6c36a995d02d2bf778d45c3c5d57bc2718f02" dependencies = [ "smallvec", ] @@ -1527,16 +1531,16 @@ dependencies = [ [[package]] name = "chrono" -version = "0.4.37" +version = "0.4.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a0d04d43504c61aa6c7531f1871dd0d418d91130162063b789da00fd7057a5e" +checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" dependencies = [ "android-tzdata", "iana-time-zone", "js-sys", "num-traits", "wasm-bindgen", - "windows-targets 0.52.4", + "windows-targets 0.52.6", ] [[package]] @@ -1583,9 +1587,9 @@ dependencies = [ [[package]] name = "clang-sys" -version = "1.7.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67523a3b4be3ce1989d607a828d036249522dd9c1c8de7f4dd2dae43a37369d1" +checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4" dependencies = [ "glob", "libc", @@ -1594,9 +1598,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.4" +version = "4.5.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90bc066a67923782aa8515dbaea16946c5bcc5addbd668bb80af688e53e548a0" +checksum = "64acc1846d54c1fe936a78dc189c34e28d3f5afc348403f28ecf53660b9b8462" dependencies = [ "clap_builder", "clap_derive", @@ -1604,9 +1608,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.2" +version = "4.5.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae129e2e766ae0ec03484e609954119f123cc1fe650337e155d03b022f24f7b4" +checksum = "6fb8393d67ba2e7bfaf28a23458e4e2b543cc73a99595511eb207fdb8aede942" dependencies = [ "anstream", "anstyle", @@ -1617,21 +1621,21 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.4" +version = "4.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "528131438037fd55894f62d6e9f068b8f45ac57ffa77517819645d10aed04f64" +checksum = "2bac35c6dafb060fd4d275d9a4ffae97917c13a6327903a8be2153cd964f7085" dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.71", ] [[package]] name = "clap_lex" -version = "0.7.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce" +checksum = "4b82cf0babdbd58558212896d1a4272303a57bdb245c2bf1147185fb45640e70" [[package]] name = "coarsetime" @@ -1656,39 +1660,39 @@ dependencies = [ [[package]] name = "color-print" -version = "0.3.5" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a858372ff14bab9b1b30ea504f2a4bc534582aee3e42ba2d41d2a7baba63d5d" +checksum = "1ee543c60ff3888934877a5671f45494dd27ed4ba25c6670b9a7576b7ed7a8c0" dependencies = [ "color-print-proc-macro", ] [[package]] name = "color-print-proc-macro" -version = "0.3.5" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57e37866456a721d0a404439a1adae37a31be4e0055590d053dfe6981e05003f" +checksum = "77ff1a80c5f3cb1ca7c06ffdd71b6a6dd6d8f896c42141fbd43f50ed28dcdb93" dependencies = [ "nom", "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.71", ] [[package]] name = "colorchoice" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" +checksum = "0b6a852b24ab71dffc585bcb46eaf7959d175cb865a7152e35b348d1b2960422" [[package]] name = "comfy-table" -version = "7.1.0" +version = "7.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c64043d6c7b7a4c58e39e7efccfdea7b93d885a795d0c054a69dbbf4dd52686" +checksum = "b34115915337defe99b2aff5c2ce6771e5fbc4079f4b506301f5cf394c8452f7" dependencies = [ - "strum 0.25.0", - "strum_macros 0.25.3", + "strum 0.26.3", + "strum_macros 0.26.4", "unicode-width", ] @@ -1700,9 +1704,9 @@ checksum = "2382f75942f4b3be3690fe4f86365e9c853c1587d6ee58212cebf6e2a9ccd101" [[package]] name = "concurrent-queue" -version = "2.4.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d16048cd947b08fa32c24458a22f5dc5e835264f689f4f5653210c69fd107363" +checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973" dependencies = [ "crossbeam-utils", ] @@ -1741,7 +1745,7 @@ version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f9d839f2a20b0aee515dc581a6172f2321f96cab76c1a38a4c584a194955390e" dependencies = [ - "getrandom 0.2.12", + "getrandom 0.2.15", "once_cell", "tiny-keccak", ] @@ -1923,9 +1927,9 @@ dependencies = [ [[package]] name = "crc32fast" -version = "1.4.0" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3855a8a784b474f333699ef2bbca9db2c4a1f6d9088a90a2d25b1eb53111eaa" +checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" dependencies = [ "cfg-if", ] @@ -1960,9 +1964,9 @@ dependencies = [ [[package]] name = "crossbeam-utils" -version = "0.8.19" +version = "0.8.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345" +checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" [[package]] name = "crunchy" @@ -1978,7 +1982,7 @@ checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" dependencies = [ "generic-array 0.14.7", "rand_core 0.6.4", - "subtle 2.5.0", + "subtle 2.6.1", "zeroize", ] @@ -2010,7 +2014,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b584a330336237c1eecd3e94266efb216c56ed91225d634cb2991c5f3fd1aeab" dependencies = [ "generic-array 0.14.7", - "subtle 2.5.0", + "subtle 2.6.1", ] [[package]] @@ -2020,7 +2024,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "25fab6889090c8133f3deb8f73ba3c65a7f456f66436fc012a1b1e272b1e103e" dependencies = [ "generic-array 0.14.7", - "subtle 2.5.0", + "subtle 2.6.1", ] [[package]] @@ -2061,7 +2065,7 @@ dependencies = [ "cumulus-primitives-core", "futures", "parity-scale-codec", - "parking_lot 0.12.1", + "parking_lot 0.12.3", "polkadot-node-primitives", "polkadot-node-subsystem", "polkadot-overseer", @@ -2174,7 +2178,7 @@ dependencies = [ "futures", "futures-timer", "parity-scale-codec", - "parking_lot 0.12.1", + "parking_lot 0.12.3", "polkadot-node-primitives", "polkadot-parachain-primitives", "polkadot-primitives", @@ -2338,7 +2342,7 @@ dependencies = [ "proc-macro-crate 3.1.0", "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.71", ] [[package]] @@ -2530,13 +2534,13 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4c7718fe298d567adc44fae3dd7024418d6eff08264041e4b0544d1892861cd6" dependencies = [ - "array-bytes 6.2.2", + "array-bytes 6.2.3", "async-trait", "cumulus-primitives-core", "cumulus-relay-chain-interface", "cumulus-relay-chain-rpc-interface", "futures", - "parking_lot 0.12.1", + "parking_lot 0.12.3", "polkadot-availability-recovery", "polkadot-collator-protocol", "polkadot-core-primitives", @@ -2630,24 +2634,23 @@ dependencies = [ "byteorder", "digest 0.9.0", "rand_core 0.5.1", - "subtle 2.5.0", + "subtle 2.6.1", "zeroize", ] [[package]] name = "curve25519-dalek" -version = "4.1.2" +version = "4.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a677b8922c94e01bdbb12126b0bc852f00447528dee1782229af9c720c3f348" +checksum = "97fb8b7c4503de7d6ae7b42ab72a5a59857b4c937ec27a3d4539dba95b5ab2be" dependencies = [ "cfg-if", "cpufeatures", "curve25519-dalek-derive", "digest 0.10.7", "fiat-crypto", - "platforms", "rustc_version", - "subtle 2.5.0", + "subtle 2.6.1", "zeroize", ] @@ -2659,7 +2662,7 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.71", ] [[package]] @@ -2677,9 +2680,9 @@ dependencies = [ [[package]] name = "cxx" -version = "1.0.120" +version = "1.0.124" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff4dc7287237dd438b926a81a1a5605dad33d286870e5eee2db17bf2bcd9e92a" +checksum = "273dcfd3acd4e1e276af13ed2a43eea7001318823e7a726a6b3ed39b4acc0b82" dependencies = [ "cc", "cxxbridge-flags", @@ -2689,9 +2692,9 @@ dependencies = [ [[package]] name = "cxx-build" -version = "1.0.120" +version = "1.0.124" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f47c6c8ad7c1a10d3ef0fe3ff6733f4db0d78f08ef0b13121543163ef327058b" +checksum = "d8b2766fbd92be34e9ed143898fce6c572dc009de39506ed6903e5a05b68914e" dependencies = [ "cc", "codespan-reporting", @@ -2699,24 +2702,24 @@ dependencies = [ "proc-macro2", "quote", "scratch", - "syn 2.0.58", + "syn 2.0.71", ] [[package]] name = "cxxbridge-flags" -version = "1.0.120" +version = "1.0.124" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "701a1ac7a697e249cdd8dc026d7a7dafbfd0dbcd8bd24ec55889f2bc13dd6287" +checksum = "839fcd5e43464614ffaa989eaf1c139ef1f0c51672a1ed08023307fa1b909ccd" [[package]] name = "cxxbridge-macro" -version = "1.0.120" +version = "1.0.124" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b404f596046b0bb2d903a9c786b875a126261b52b7c3a64bbb66382c41c771df" +checksum = "4b2c1c1776b986979be68bb2285da855f8d8a35851a769fca8740df7c3d07877" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.71", ] [[package]] @@ -2731,12 +2734,12 @@ dependencies = [ [[package]] name = "darling" -version = "0.20.8" +version = "0.20.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54e36fcd13ed84ffdfda6f5be89b31287cbb80c439841fe69e04841435464391" +checksum = "6f63b86c8a8826a49b8c21f08a2d07338eec8d900540f8630dc76284be802989" dependencies = [ - "darling_core 0.20.8", - "darling_macro 0.20.8", + "darling_core 0.20.10", + "darling_macro 0.20.10", ] [[package]] @@ -2755,16 +2758,16 @@ dependencies = [ [[package]] name = "darling_core" -version = "0.20.8" +version = "0.20.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c2cf1c23a687a1feeb728783b993c4e1ad83d99f351801977dd809b48d0a70f" +checksum = "95133861a8032aaea082871032f5815eb9e98cef03fa916ab4500513994df9e5" dependencies = [ "fnv", "ident_case", "proc-macro2", "quote", - "strsim 0.10.0", - "syn 2.0.58", + "strsim 0.11.1", + "syn 2.0.71", ] [[package]] @@ -2780,26 +2783,26 @@ dependencies = [ [[package]] name = "darling_macro" -version = "0.20.8" +version = "0.20.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a668eda54683121533a393014d8692171709ff57a7d61f187b6e782719f8933f" +checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" dependencies = [ - "darling_core 0.20.8", + "darling_core 0.20.10", "quote", - "syn 2.0.58", + "syn 2.0.71", ] [[package]] name = "data-encoding" -version = "2.5.0" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e962a19be5cfc3f3bf6dd8f61eb50107f356ad6270fbb3ed41476571db78be5" +checksum = "e8566979429cf69b49a5c740c60791108e86440e8be149bbea4fe54d2c32d6e2" [[package]] name = "data-encoding-macro" -version = "0.1.14" +version = "0.1.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20c01c06f5f429efdf2bae21eb67c28b3df3cf85b7dd2d8ef09c0838dac5d33e" +checksum = "f1559b6cba622276d6d63706db152618eeb15b89b3e4041446b05876e352e639" dependencies = [ "data-encoding", "data-encoding-macro-internal", @@ -2807,9 +2810,9 @@ dependencies = [ [[package]] name = "data-encoding-macro-internal" -version = "0.1.12" +version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0047d07f2c89b17dd631c80450d69841a6b5d7fb17278cbc43d7e4cfcf2576f3" +checksum = "332d754c0af53bc87c108fed664d121ecf59207ec4196041f04d6ab9002ad33f" dependencies = [ "data-encoding", "syn 1.0.109", @@ -2878,20 +2881,20 @@ checksum = "d65d7ce8132b7c0e54497a4d9a55a1c2a0912a0d786cf894472ba818fba45762" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.71", ] [[package]] name = "derive_more" -version = "0.99.17" +version = "0.99.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" +checksum = "5f33878137e4dafd7fa914ad4e259e18a4e8e532b9617a2d0150262bf53abfce" dependencies = [ "convert_case", "proc-macro2", "quote", "rustc_version", - "syn 1.0.109", + "syn 2.0.71", ] [[package]] @@ -2927,7 +2930,7 @@ dependencies = [ "block-buffer 0.10.4", "const-oid", "crypto-common", - "subtle 2.5.0", + "subtle 2.6.1", ] [[package]] @@ -2974,13 +2977,13 @@ dependencies = [ [[package]] name = "displaydoc" -version = "0.2.4" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "487585f4d0c6655fe74905e2504d8ad6908e4db67f744eb140876906c2f3175d" +checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.71", ] [[package]] @@ -3004,9 +3007,9 @@ dependencies = [ "proc-macro2", "quote", "regex", - "syn 2.0.58", + "syn 2.0.71", "termcolor", - "toml 0.8.12", + "toml 0.8.14", "walkdir", ] @@ -3018,9 +3021,9 @@ checksum = "1435fa1053d8b2fbbe9be7e97eca7f33d37b28409959813daefc1446a14247f1" [[package]] name = "downcast-rs" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ea835d29036a4087793836fa931b08837ad5e957da9e23886b29586fb9b6650" +checksum = "75b325c5dbd37f80359721ad39aca5a29fb04c89279657cffdda8736d0c0b9d2" [[package]] name = "dtoa" @@ -3085,12 +3088,12 @@ version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4a3daa8e81a3963a60642bcc1f90a670680bd4a77535faa384e9d1c79d620871" dependencies = [ - "curve25519-dalek 4.1.2", + "curve25519-dalek 4.1.3", "ed25519", "rand_core 0.6.4", "serde", "sha2 0.10.8", - "subtle 2.5.0", + "subtle 2.6.1", "zeroize", ] @@ -3114,9 +3117,9 @@ version = "4.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7d9ce6874da5d4415896cd45ffbc4d1cfc0c4f9c079427bd870742c30f2f65a9" dependencies = [ - "curve25519-dalek 4.1.2", + "curve25519-dalek 4.1.3", "ed25519", - "hashbrown 0.14.3", + "hashbrown 0.14.5", "hex", "rand_core 0.6.4", "sha2 0.10.8", @@ -3125,9 +3128,9 @@ dependencies = [ [[package]] name = "either" -version = "1.10.0" +version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11157ac094ffbdde99aa67b23417ebdd801842852b500e395a45a9c0aac03e4a" +checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" [[package]] name = "elliptic-curve" @@ -3144,7 +3147,7 @@ dependencies = [ "pkcs8", "rand_core 0.6.4", "sec1", - "subtle 2.5.0", + "subtle 2.6.1", "zeroize", ] @@ -3201,22 +3204,22 @@ dependencies = [ [[package]] name = "enumflags2" -version = "0.7.9" +version = "0.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3278c9d5fb675e0a51dabcf4c0d355f692b064171535ba72361be1528a9d8e8d" +checksum = "d232db7f5956f3f14313dc2f87985c58bd2c695ce124c8cdd984e08e15ac133d" dependencies = [ "enumflags2_derive", ] [[package]] name = "enumflags2_derive" -version = "0.7.9" +version = "0.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c785274071b1b420972453b306eeca06acf4633829db4223b58a2a8c5953bc4" +checksum = "de0d48a183585823424a4ce1aa132d174a6a81bd540895822eb4c8373a8e49e8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.71", ] [[package]] @@ -3227,7 +3230,7 @@ checksum = "6fd000fd6988e73bbe993ea3db9b1aa64906ab88766d654973924340c8cddb42" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.71", ] [[package]] @@ -3280,9 +3283,9 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "errno" -version = "0.3.8" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" +checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" dependencies = [ "libc", "windows-sys 0.52.0", @@ -3353,15 +3356,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "67b215c49b2b248c855fb73579eb1f4f26c38ffdc12973e20e07b91d78d5646e" dependencies = [ "concurrent-queue", - "parking", "pin-project-lite 0.2.14", ] [[package]] name = "event-listener" -version = "5.2.0" +version = "5.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b5fb89194fa3cad959b833185b3063ba881dbfc7030680b314250779fb4cc91" +checksum = "6032be9bd27023a771701cc49f9f053c751055f71efb2e0ae5c15809093675ba" dependencies = [ "concurrent-queue", "parking", @@ -3370,21 +3372,11 @@ dependencies = [ [[package]] name = "event-listener-strategy" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "958e4d70b6d5e81971bebec42271ec641e7ff4e170a6fa605f2b8a8b65cb97d3" -dependencies = [ - "event-listener 4.0.3", - "pin-project-lite 0.2.14", -] - -[[package]] -name = "event-listener-strategy" -version = "0.5.1" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "332f51cb23d20b0de8458b86580878211da09bcd4503cb579c225b3d124cabb3" +checksum = "0f214dc438f977e6d4e3500aaa277f5ad94ca83fbbd9b1a15713ce2344ccc5a1" dependencies = [ - "event-listener 5.2.0", + "event-listener 5.3.1", "pin-project-lite 0.2.14", ] @@ -3411,16 +3403,17 @@ dependencies = [ [[package]] name = "expander" -version = "2.1.0" +version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00e83c02035136f1592a47964ea60c05a50e4ed8b5892cfac197063850898d4d" +checksum = "e2c470c71d91ecbd179935b24170459e926382eaaa86b590b78814e180d8a8e2" dependencies = [ "blake2 0.10.6", + "file-guard", "fs-err", - "prettier-please", + "prettyplease 0.2.20", "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.71", ] [[package]] @@ -3440,9 +3433,9 @@ dependencies = [ [[package]] name = "fastrand" -version = "2.0.2" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "658bd65b1cf4c852a3cc96f18a8ce7b5640f6b703f905c7d74532294c2a63984" +checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a" [[package]] name = "fatality" @@ -3462,7 +3455,7 @@ checksum = "f5aa1e3ae159e592ad222dc90c5acbad632b527779ba88486abe92782ab268bd" dependencies = [ "expander 0.0.4", "indexmap 1.9.3", - "proc-macro-crate 1.3.1", + "proc-macro-crate 1.1.3", "proc-macro2", "quote", "syn 1.0.109", @@ -3486,14 +3479,24 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" dependencies = [ "rand_core 0.6.4", - "subtle 2.5.0", + "subtle 2.6.1", ] [[package]] name = "fiat-crypto" -version = "0.2.7" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c007b1ae3abe1cb6f85a16305acd418b7ca6343b953633fee2b76d8f108b830f" +checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d" + +[[package]] +name = "file-guard" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21ef72acf95ec3d7dbf61275be556299490a245f017cf084bd23b4f68cf9407c" +dependencies = [ + "libc", + "winapi", +] [[package]] name = "file-per-thread-logger" @@ -3529,7 +3532,7 @@ dependencies = [ "log", "num-traits", "parity-scale-codec", - "parking_lot 0.12.1", + "parking_lot 0.12.3", "scale-info", ] @@ -3553,9 +3556,9 @@ checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" [[package]] name = "flate2" -version = "1.0.28" +version = "1.0.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46303f565772937ffe1d394a4fac6f411c6013172fadde9dcdb1e147a086940e" +checksum = "5f54427cfd1c7829e2a139fcefea601bf088ebca651d2bf53ebc600eac295dae" dependencies = [ "crc32fast", "libz-sys", @@ -3634,7 +3637,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "efe02c96362e3c7308cdea7545859f767194a1f3f00928f0e1357f4b8a0b3b2c" dependencies = [ "Inflector", - "array-bytes 6.2.2", + "array-bytes 6.2.3", "chrono", "clap", "comfy-table", @@ -3685,7 +3688,7 @@ dependencies = [ "proc-macro-crate 3.1.0", "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.71", ] [[package]] @@ -3754,7 +3757,7 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5bb1eec9eb46d3e016c95b2fa875118c04609f2150013c56a894cae00581e265" dependencies = [ - "array-bytes 6.2.2", + "array-bytes 6.2.3", "docify", "frame-support", "frame-system", @@ -3794,7 +3797,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b8e52c84b611d2049d9253f83a62ab0f093e4be5c42a7ef42ea5bb16d6611e32" dependencies = [ "aquamarine", - "array-bytes 6.2.2", + "array-bytes 6.2.3", "bitflags 1.3.2", "docify", "environmental", @@ -3838,7 +3841,7 @@ dependencies = [ "Inflector", "cfg-expr", "derive-syn-parse 0.1.5", - "expander 2.1.0", + "expander 2.2.1", "frame-support-procedural-tools", "itertools 0.10.5", "macro_magic", @@ -3846,7 +3849,7 @@ dependencies = [ "proc-macro2", "quote", "sp-crypto-hashing", - "syn 2.0.58", + "syn 2.0.71", ] [[package]] @@ -3859,7 +3862,7 @@ dependencies = [ "proc-macro-crate 3.1.0", "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.71", ] [[package]] @@ -3870,7 +3873,7 @@ checksum = "68672b9ec6fe72d259d3879dc212c5e42e977588cdac830c76f54d9f492aeb58" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.71", ] [[package]] @@ -3958,7 +3961,7 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "29f9df8a11882c4e3335eb2d18a0137c505d9ca927470b0cac9c6f0ae07d28f7" dependencies = [ - "rustix 0.38.32", + "rustix 0.38.34", "windows-sys 0.48.0", ] @@ -4048,7 +4051,7 @@ version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "52527eb5074e35e9339c6b4e8d12600c7128b68fb25dcb9fa9dec18f7c25f3a5" dependencies = [ - "fastrand 2.0.2", + "fastrand 2.1.0", "futures-core", "futures-io", "parking", @@ -4063,7 +4066,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.71", ] [[package]] @@ -4165,9 +4168,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.12" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" dependencies = [ "cfg-if", "libc", @@ -4207,9 +4210,9 @@ dependencies = [ [[package]] name = "gimli" -version = "0.28.1" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" +checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd" [[package]] name = "glob" @@ -4225,7 +4228,7 @@ checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" dependencies = [ "ff", "rand_core 0.6.4", - "subtle 2.5.0", + "subtle 2.6.1", ] [[package]] @@ -4296,9 +4299,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.14.3" +version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" dependencies = [ "ahash 0.8.11", "allocator-api2", @@ -4311,7 +4314,7 @@ version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e8094feaf31ff591f651a2664fb9cfd92bba7a60ce3197265e9482ebe753c8f7" dependencies = [ - "hashbrown 0.14.3", + "hashbrown 0.14.5", ] [[package]] @@ -4332,6 +4335,12 @@ version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" +[[package]] +name = "hermit-abi" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc" + [[package]] name = "hex" version = "0.4.3" @@ -4443,9 +4452,9 @@ checksum = "add0ab9360ddbd88cfeb3bd9574a1d85cfdfa14db10b3e21d3700dbc4328758f" [[package]] name = "httparse" -version = "1.8.0" +version = "1.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" +checksum = "0fcc0b4a115bf80b728eb8ea024ad5bd707b615bfed49e0665b6e0f86fd082d9" [[package]] name = "httpdate" @@ -4461,9 +4470,9 @@ checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" [[package]] name = "hyper" -version = "0.14.28" +version = "0.14.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf96e135eb83a2a8ddf766e426a841d8ddd7449d5f00d34ea02b41d2f19eef80" +checksum = "a152ddd61dfaec7273fe8419ab357f33aee0d914c5f4efbf0d96fa749eea5ec9" dependencies = [ "bytes", "futures-channel", @@ -4476,7 +4485,7 @@ dependencies = [ "httpdate", "itoa", "pin-project-lite 0.2.14", - "socket2 0.5.6", + "socket2 0.5.7", "tokio", "tower-service", "tracing", @@ -4493,7 +4502,7 @@ dependencies = [ "http", "hyper", "log", - "rustls 0.21.10", + "rustls 0.21.12", "rustls-native-certs 0.6.3", "tokio", "tokio-rustls 0.24.1", @@ -4565,7 +4574,7 @@ version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d6b0422c86d7ce0e97169cc42e04ae643caf278874a7a3c87b8150a220dc7e1e" dependencies = [ - "async-io 2.3.2", + "async-io 2.3.3", "core-foundation", "fnv", "futures", @@ -4629,18 +4638,18 @@ dependencies = [ [[package]] name = "include_dir" -version = "0.7.3" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18762faeff7122e89e0857b02f7ce6fcc0d101d5e9ad2ad7846cc01d61b7f19e" +checksum = "923d117408f1e49d914f1a379a309cffe4f18c05cf4e3d12e613a15fc81bd0dd" dependencies = [ "include_dir_macros", ] [[package]] name = "include_dir_macros" -version = "0.7.3" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b139284b5cf57ecfa712bcc66950bb635b31aff41c188e8a4cfc758eca374a3f" +checksum = "7cab85a7ed0bd5f0e76d93846e0147172bed2e2d3f859bcc33a8d9699cad1a75" dependencies = [ "proc-macro2", "quote", @@ -4664,7 +4673,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" dependencies = [ "equivalent", - "hashbrown 0.14.3", + "hashbrown 0.14.5", ] [[package]] @@ -4697,9 +4706,9 @@ dependencies = [ [[package]] name = "instant" -version = "0.1.12" +version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" +checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222" dependencies = [ "cfg-if", ] @@ -4756,7 +4765,7 @@ version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" dependencies = [ - "hermit-abi", + "hermit-abi 0.3.9", "libc", "windows-sys 0.48.0", ] @@ -4773,7 +4782,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b58db92f96b720de98181bbbe63c831e87005ab460c1bf306eb2622b4707997f" dependencies = [ - "socket2 0.5.6", + "socket2 0.5.7", "widestring", "windows-sys 0.48.0", "winreg", @@ -4791,7 +4800,7 @@ version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f23ff5ef2b80d608d61efee834934d862cd92461afc0560dedf493e4c033738b" dependencies = [ - "hermit-abi", + "hermit-abi 0.3.9", "libc", "windows-sys 0.52.0", ] @@ -4805,6 +4814,12 @@ dependencies = [ "winapi", ] +[[package]] +name = "is_terminal_polyfill" +version = "1.70.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8478577c03552c21db0e2724ffb8986a5ce7af88107e6be5d2ee6e158c12800" + [[package]] name = "itertools" version = "0.10.5" @@ -4840,9 +4855,9 @@ checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" [[package]] name = "jobserver" -version = "0.1.28" +version = "0.1.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab46a6e9526ddef3ae7f787c06f0f2600639ba80ea3eade3d8e670a2230f51d6" +checksum = "d2b099aaa34a9751c5bf0878add70444e1ed2dd73f347be99003d4577277de6e" dependencies = [ "libc", ] @@ -4914,7 +4929,7 @@ dependencies = [ "http", "jsonrpsee-core 0.21.0", "pin-project", - "rustls-native-certs 0.7.0", + "rustls-native-certs 0.7.1", "rustls-pki-types", "soketto", "thiserror", @@ -4939,7 +4954,7 @@ dependencies = [ "futures-util", "hyper", "jsonrpsee-types 0.20.3", - "parking_lot 0.12.1", + "parking_lot 0.12.3", "rand", "rustc-hash", "serde", @@ -4957,7 +4972,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "776d009e2f591b78c038e0d053a796f94575d66ca4e77dd84bfc5e81419e436c" dependencies = [ "anyhow", - "async-lock 3.3.0", + "async-lock 3.4.0", "async-trait", "beef", "futures-timer", @@ -5021,7 +5036,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "29110019693a4fa2dbda04876499d098fa16d70eba06b1e6e2b3f1b251419515" dependencies = [ "heck 0.4.1", - "proc-macro-crate 1.3.1", + "proc-macro-crate 1.1.3", "proc-macro2", "quote", "syn 1.0.109", @@ -5134,7 +5149,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bf7a85fe66f9ff9cd74e169fdd2c94c6e1e74c412c99a73b4df3200b5d3760b2" dependencies = [ "kvdb", - "parking_lot 0.12.1", + "parking_lot 0.12.3", ] [[package]] @@ -5145,7 +5160,7 @@ checksum = "b644c70b92285f66bfc2032922a79000ea30af7bc2ab31902992a5dcb9b434f6" dependencies = [ "kvdb", "num_cpus", - "parking_lot 0.12.1", + "parking_lot 0.12.3", "regex", "rocksdb", "smallvec", @@ -5164,9 +5179,9 @@ dependencies = [ [[package]] name = "lazy_static" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" [[package]] name = "lazycell" @@ -5176,18 +5191,18 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" [[package]] name = "libc" -version = "0.2.153" +version = "0.2.155" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" +checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" [[package]] name = "libloading" -version = "0.8.3" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c2a198fb6b0eada2a8df47933734e6d35d350665a33a3593d7164fa52c75c19" +checksum = "e310b3a6b5907f99202fcdb4960ff45b93735d7c7d96b760fcff8db2dc0e103d" dependencies = [ "cfg-if", - "windows-targets 0.52.4", + "windows-targets 0.52.6", ] [[package]] @@ -5205,7 +5220,7 @@ dependencies = [ "bytes", "futures", "futures-timer", - "getrandom 0.2.12", + "getrandom 0.2.15", "instant", "libp2p-allow-block-list", "libp2p-connection-limits", @@ -5270,7 +5285,7 @@ dependencies = [ "multihash 0.17.0", "multistream-select", "once_cell", - "parking_lot 0.12.1", + "parking_lot 0.12.3", "pin-project", "quick-protobuf", "rand", @@ -5290,7 +5305,7 @@ dependencies = [ "futures", "libp2p-core", "log", - "parking_lot 0.12.1", + "parking_lot 0.12.3", "smallvec", "trust-dns-resolver", ] @@ -5452,7 +5467,7 @@ dependencies = [ "libp2p-identity", "libp2p-tls", "log", - "parking_lot 0.12.1", + "parking_lot 0.12.3", "quinn-proto", "rand", "rustls 0.20.9", @@ -5568,7 +5583,7 @@ dependencies = [ "futures-rustls", "libp2p-core", "log", - "parking_lot 0.12.1", + "parking_lot 0.12.3", "quicksink", "rw-stream-sink", "soketto", @@ -5595,7 +5610,7 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "libc", ] @@ -5641,7 +5656,7 @@ checksum = "5be9b9bb642d8522a44d533eab56c16c738301965504753b03ad1de3425d5451" dependencies = [ "crunchy", "digest 0.9.0", - "subtle 2.5.0", + "subtle 2.6.1", ] [[package]] @@ -5664,9 +5679,9 @@ dependencies = [ [[package]] name = "libz-sys" -version = "1.1.16" +version = "1.1.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e143b5e666b2695d28f6bca6497720813f699c9602dd7f5cac91008b8ada7f9" +checksum = "c15da26e5af7e25c90b37a2d75cdbf940cf4a55316de9d84c679c9b8bfabf82e" dependencies = [ "cc", "pkg-config", @@ -5720,9 +5735,9 @@ checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" [[package]] name = "linux-raw-sys" -version = "0.4.13" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" +checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" [[package]] name = "lioness" @@ -5738,9 +5753,9 @@ dependencies = [ [[package]] name = "lock_api" -version = "0.4.11" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" +checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" dependencies = [ "autocfg", "scopeguard", @@ -5748,9 +5763,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.21" +version = "0.4.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" +checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" [[package]] name = "lru" @@ -5782,7 +5797,7 @@ version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3262e75e648fce39813cb56ac41f3c3e3f65217ebf3844d818d1f9398cfb0dc" dependencies = [ - "hashbrown 0.14.3", + "hashbrown 0.14.5", ] [[package]] @@ -5796,9 +5811,9 @@ dependencies = [ [[package]] name = "lz4" -version = "1.24.0" +version = "1.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e9e2dd86df36ce760a60f6ff6ad526f7ba1f14ba0356f8254fb6905e6494df1" +checksum = "d6eab492fe7f8651add23237ea56dbf11b3c4ff762ab83d40a47f11433421f91" dependencies = [ "libc", "lz4-sys", @@ -5806,9 +5821,9 @@ dependencies = [ [[package]] name = "lz4-sys" -version = "1.9.4" +version = "1.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57d27b317e207b10f69f5e75494119e391a96f48861ae870d1da6edac98ca900" +checksum = "e9764018d143cc854c9f17f0b907de70f14393b1f502da6375dce70f00514eb3" dependencies = [ "cc", "libc", @@ -5825,50 +5840,50 @@ dependencies = [ [[package]] name = "macro_magic" -version = "0.5.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e03844fc635e92f3a0067e25fa4bf3e3dbf3f2927bf3aa01bb7bc8f1c428949d" +checksum = "cc33f9f0351468d26fbc53d9ce00a096c8522ecb42f19b50f34f2c422f76d21d" dependencies = [ "macro_magic_core", "macro_magic_macros", "quote", - "syn 2.0.58", + "syn 2.0.71", ] [[package]] name = "macro_magic_core" -version = "0.5.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "468155613a44cfd825f1fb0ffa532b018253920d404e6fca1e8d43155198a46d" +checksum = "1687dc887e42f352865a393acae7cf79d98fab6351cde1f58e9e057da89bf150" dependencies = [ "const-random", - "derive-syn-parse 0.1.5", + "derive-syn-parse 0.2.0", "macro_magic_core_macros", "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.71", ] [[package]] name = "macro_magic_core_macros" -version = "0.5.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ea73aa640dc01d62a590d48c0c3521ed739d53b27f919b25c3551e233481654" +checksum = "b02abfe41815b5bd98dbd4260173db2c116dda171dc0fe7838cb206333b83308" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.71", ] [[package]] name = "macro_magic_macros" -version = "0.5.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef9d79ae96aaba821963320eb2b6e34d17df1e5a83d8a1985c29cc5be59577b3" +checksum = "73ea28ee64b88876bf45277ed9a5817c1817df061a74f2b988971a12570e5869" dependencies = [ "macro_magic_core", "quote", - "syn 2.0.58", + "syn 2.0.71", ] [[package]] @@ -5919,9 +5934,9 @@ dependencies = [ [[package]] name = "memchr" -version = "2.7.2" +version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" [[package]] name = "memfd" @@ -5929,7 +5944,7 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b2cffa4ad52c6f791f4f8b15f0c05f9824b2ced1160e88cc393d64fff9a8ac64" dependencies = [ - "rustix 0.38.32", + "rustix 0.38.34", ] [[package]] @@ -5999,9 +6014,9 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] name = "miniz_oxide" -version = "0.7.2" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d811f3e15f28568be3407c8e7fdb6514c1cda3cb30683f15b6a1a1dc4ea14a7" +checksum = "b8a240ddb74feaf34a79a7add65a741f3167852fba007066dcac1ca548d89c08" dependencies = [ "adler", ] @@ -6028,16 +6043,16 @@ dependencies = [ "bitflags 1.3.2", "blake2 0.10.6", "c2-chacha", - "curve25519-dalek 4.1.2", + "curve25519-dalek 4.1.3", "either", "hashlink", "lioness", "log", - "parking_lot 0.12.1", + "parking_lot 0.12.3", "rand", "rand_chacha 0.3.1", "rand_distr", - "subtle 2.5.0", + "subtle 2.6.1", "thiserror", "zeroize", ] @@ -6146,7 +6161,7 @@ dependencies = [ "blake3", "core2", "digest 0.10.7", - "multihash-derive 0.8.0", + "multihash-derive 0.8.1", "sha2 0.10.8", "sha3", "unsigned-varint", @@ -6160,7 +6175,7 @@ checksum = "cfd8a792c1694c6da4f68db0a9d707c72bd260994da179e6030a5dcee00bb815" dependencies = [ "core2", "digest 0.10.7", - "multihash-derive 0.8.0", + "multihash-derive 0.8.1", "sha2 0.10.8", "unsigned-varint", ] @@ -6197,16 +6212,16 @@ dependencies = [ [[package]] name = "multihash-derive" -version = "0.8.0" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc076939022111618a5026d3be019fd8b366e76314538ff9a1b59ffbcbf98bcd" +checksum = "1d6d4752e6230d8ef7adf7bd5d8c4b1f6561c1014c5ba9a37445ccefe18aa1db" dependencies = [ - "proc-macro-crate 1.3.1", + "proc-macro-crate 1.1.3", "proc-macro-error", "proc-macro2", "quote", "syn 1.0.109", - "synstructure", + "synstructure 0.12.6", ] [[package]] @@ -6222,16 +6237,16 @@ dependencies = [ [[package]] name = "multihash-derive-impl" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d38685e08adb338659871ecfc6ee47ba9b22dcc8abcf6975d379cc49145c3040" +checksum = "3958713ce794e12f7c6326fac9aa274c68d74c4881dd37b3e2662b8a2046bb19" dependencies = [ - "proc-macro-crate 1.3.1", + "proc-macro-crate 2.0.0", "proc-macro-error", "proc-macro2", "quote", - "syn 1.0.109", - "synstructure", + "syn 2.0.71", + "synstructure 0.13.1", ] [[package]] @@ -6256,9 +6271,9 @@ dependencies = [ [[package]] name = "nalgebra" -version = "0.32.5" +version = "0.32.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ea4908d4f23254adda3daa60ffef0f1ac7b8c3e9a864cf3cc154b251908a2ef" +checksum = "7b5c17de023a86f59ed79891b2e5d5a94c705dbe904a5b5c9c952ea6221b03e4" dependencies = [ "approx", "matrixmultiply", @@ -6272,13 +6287,13 @@ dependencies = [ [[package]] name = "nalgebra-macros" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91761aed67d03ad966ef783ae962ef9bbaca728d2dd7ceb7939ec110fffad998" +checksum = "254a5372af8fc138e36684761d3c0cdb758a4410e938babcff1c860ce14ddbfc" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.71", ] [[package]] @@ -6379,7 +6394,7 @@ version = "0.27.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2eb04e9c688eff1c89d72b407f168cf79bb9e867a9d3323ed6c01519eb9cc053" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "cfg-if", "libc", ] @@ -6420,20 +6435,19 @@ checksum = "61807f77802ff30975e01f4f071c8ba10c022052f98b3294119f3e615d13e5be" [[package]] name = "num-bigint" -version = "0.4.4" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "608e7659b5c3d7cba262d894801b9ec9d00de989e8a82bd4bef91d08da45cdc0" +checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" dependencies = [ - "autocfg", "num-integer", "num-traits", ] [[package]] name = "num-complex" -version = "0.4.5" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23c6602fda94a57c990fe0df199a035d83576b496aa29f4e634a8ac6004e68a6" +checksum = "73f88a1307638156682bada9d7604135552957b7818057dcef22705b4d509495" dependencies = [ "num-traits", ] @@ -6465,11 +6479,10 @@ dependencies = [ [[package]] name = "num-rational" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0638a1c9d0a3c0914158145bc76cff373a75a627e6ecbfb71cbe6f453a5a19b0" +checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824" dependencies = [ - "autocfg", "num-bigint", "num-integer", "num-traits", @@ -6477,9 +6490,9 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.18" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", "libm", @@ -6491,7 +6504,7 @@ version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" dependencies = [ - "hermit-abi", + "hermit-abi 0.3.9", "libc", ] @@ -6515,9 +6528,9 @@ dependencies = [ [[package]] name = "object" -version = "0.32.2" +version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" +checksum = "081b846d1d56ddfc18fdf1a922e4f6e07a11768ea1b92dec44e42b72712ccfce" dependencies = [ "memchr", ] @@ -6563,9 +6576,9 @@ checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" [[package]] name = "orchestra" -version = "0.3.5" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2356622ffdfe72362a45a1e5e87bb113b8327e596e39b91f11f0ef4395c8da79" +checksum = "92829eef0328a3d1cd22a02c0e51deb92a5362df3e7d21a4e9bdc38934694e66" dependencies = [ "async-trait", "dyn-clonable", @@ -6580,15 +6593,15 @@ dependencies = [ [[package]] name = "orchestra-proc-macro" -version = "0.3.5" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eedb646674596266dc9bb2b5c7eea7c36b32ecc7777eba0d510196972d72c4fd" +checksum = "1344346d5af32c95bbddea91b18a88cc83eac394192d20ef2fc4c40a74332355" dependencies = [ - "expander 2.1.0", + "expander 2.2.1", "indexmap 2.2.6", "itertools 0.11.0", "petgraph", - "proc-macro-crate 1.3.1", + "proc-macro-crate 3.1.0", "proc-macro2", "quote", "syn 1.0.109", @@ -6832,7 +6845,7 @@ version = "29.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7d334f24d3c0c016d16aa87d069485847d622e8ebebace18ec5cf56609ca3a67" dependencies = [ - "array-bytes 6.2.2", + "array-bytes 6.2.3", "binary-merkle-tree", "frame-support", "frame-system", @@ -7074,7 +7087,7 @@ checksum = "3163c6bc21b55a0ccb74c546ba784d9c9e69beb9240c059d28a3052f4cbce509" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.71", ] [[package]] @@ -7430,9 +7443,9 @@ dependencies = [ [[package]] name = "pallet-nomination-pools" -version = "26.0.0" +version = "26.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f14519c1c613d2f8c95c27015864c11a37969a23deeba9f6dbaff4276e1b81c" +checksum = "b62091305ec7426e71c3da2b0944c2df5a804109ee4d2e8f4fe34865e049f8ac" dependencies = [ "frame-support", "frame-system", @@ -7742,7 +7755,7 @@ dependencies = [ "proc-macro-crate 3.1.0", "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.71", ] [[package]] @@ -7757,9 +7770,9 @@ dependencies = [ [[package]] name = "pallet-staking-runtime-api" -version = "15.0.0" +version = "15.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "237d7b5a10cb6cba727c3e957fb241776302aa3cce589e6759ba53f50129c1a5" +checksum = "e47c73850103db30b61ef170107afe1ef0dab6905c495bd6dfb57b3c1dd81bc7" dependencies = [ "parity-scale-codec", "sp-api", @@ -8121,7 +8134,7 @@ dependencies = [ "log", "lz4", "memmap2 0.5.10", - "parking_lot 0.12.1", + "parking_lot 0.12.3", "rand", "siphasher 0.3.11", "snap", @@ -8130,9 +8143,9 @@ dependencies = [ [[package]] name = "parity-scale-codec" -version = "3.6.9" +version = "3.6.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "881331e34fa842a2fb61cc2db9643a8fedc615e47cfcc52597d1af0db9a7e8fe" +checksum = "306800abfa29c7f16596b5970a588435e3d5b3149683d00c12b699cc19f895ee" dependencies = [ "arrayvec 0.7.4", "bitvec", @@ -8145,11 +8158,11 @@ dependencies = [ [[package]] name = "parity-scale-codec-derive" -version = "3.6.9" +version = "3.6.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be30eaf4b0a9fba5336683b38de57bb86d179a35862ba6bfcf57625d006bde5b" +checksum = "d830939c76d294956402033aee57a6da7b438f2294eb94864c37b0569053a42c" dependencies = [ - "proc-macro-crate 2.0.0", + "proc-macro-crate 3.1.0", "proc-macro2", "quote", "syn 1.0.109", @@ -8173,7 +8186,7 @@ dependencies = [ "impl-trait-for-tuples", "lru 0.8.1", "parity-util-mem-derive", - "parking_lot 0.12.1", + "parking_lot 0.12.3", "primitive-types", "smallvec", "winapi", @@ -8187,7 +8200,7 @@ checksum = "f557c32c6d268a07c921471619c0295f5efad3a0e76d4f97a05c091a51d110b2" dependencies = [ "proc-macro2", "syn 1.0.109", - "synstructure", + "synstructure 0.12.6", ] [[package]] @@ -8215,12 +8228,12 @@ dependencies = [ [[package]] name = "parking_lot" -version = "0.12.1" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" +checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" dependencies = [ "lock_api", - "parking_lot_core 0.9.9", + "parking_lot_core 0.9.10", ] [[package]] @@ -8239,15 +8252,15 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.9" +version = "0.9.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" +checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" dependencies = [ "cfg-if", "libc", - "redox_syscall 0.4.1", + "redox_syscall 0.5.3", "smallvec", - "windows-targets 0.48.5", + "windows-targets 0.52.6", ] [[package]] @@ -8258,9 +8271,9 @@ checksum = "7924d1d0ad836f665c9065e26d016c673ece3993f30d340068b16f282afc1156" [[package]] name = "paste" -version = "1.0.14" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" [[package]] name = "pbkdf2" @@ -8303,9 +8316,9 @@ checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "pest" -version = "2.7.9" +version = "2.7.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "311fb059dee1a7b802f036316d790138c613a4e8b180c822e3925a662e9f0c95" +checksum = "cd53dff83f26735fdc1ca837098ccf133605d794cdae66acfc2bfac3ec809d95" dependencies = [ "memchr", "thiserror", @@ -8314,9 +8327,9 @@ dependencies = [ [[package]] name = "pest_derive" -version = "2.7.9" +version = "2.7.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f73541b156d32197eecda1a4014d7f868fd2bcb3c550d5386087cfba442bf69c" +checksum = "2a548d2beca6773b1c244554d36fcf8548a8a58e74156968211567250e48e49a" dependencies = [ "pest", "pest_generator", @@ -8324,22 +8337,22 @@ dependencies = [ [[package]] name = "pest_generator" -version = "2.7.9" +version = "2.7.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c35eeed0a3fab112f75165fdc026b3913f4183133f19b49be773ac9ea966e8bd" +checksum = "3c93a82e8d145725dcbaf44e5ea887c8a869efdcc28706df2d08c69e17077183" dependencies = [ "pest", "pest_meta", "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.71", ] [[package]] name = "pest_meta" -version = "2.7.9" +version = "2.7.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2adbf29bb9776f28caece835398781ab24435585fe0d4dc1374a61db5accedca" +checksum = "a941429fea7e08bedec25e4f6785b6ffaacc6b755da98df5ef3e7dcf4a124c4f" dependencies = [ "once_cell", "pest", @@ -8348,9 +8361,9 @@ dependencies = [ [[package]] name = "petgraph" -version = "0.6.4" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1d3afd2628e69da2be385eb6f2fd57c8ac7977ceeff6dc166ff1657b0e386a9" +checksum = "b4c5cc86750666a3ed20bdaf5ca2a0344f9c67674cae0515bec2da16fbaa47db" dependencies = [ "fixedbitset", "indexmap 2.2.6", @@ -8373,7 +8386,7 @@ checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.71", ] [[package]] @@ -8396,12 +8409,12 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "piper" -version = "0.2.1" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "668d31b1c4eba19242f2088b2bf3316b82ca31082a8335764db4e083db7485d4" +checksum = "ae1d5c74c9876f070d3e8fd503d748c7d974c3e48da8f41350fa5222ef9b4391" dependencies = [ "atomic-waker", - "fastrand 2.0.2", + "fastrand 2.1.0", "futures-io", ] @@ -8421,12 +8434,6 @@ version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" -[[package]] -name = "platforms" -version = "3.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db23d408679286588f4d4644f965003d056e3dd5abcaaa938116871d7ce2fee7" - [[package]] name = "polkadot-approval-distribution" version = "8.0.0" @@ -8654,7 +8661,7 @@ dependencies = [ "fatality", "futures", "parity-scale-codec", - "parking_lot 0.12.1", + "parking_lot 0.12.3", "polkadot-node-metrics", "polkadot-node-network-protocol", "polkadot-node-subsystem", @@ -8915,7 +8922,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f3bbb1b5f4b966f21a0336e94c0a0222958d2f3cba451da1157af271d07f9748" dependencies = [ "always-assert", - "array-bytes 6.2.2", + "array-bytes 6.2.3", "blake3", "cfg-if", "futures", @@ -9013,7 +9020,7 @@ dependencies = [ "log", "mick-jaeger", "parity-scale-codec", - "parking_lot 0.12.1", + "parking_lot 0.12.3", "polkadot-node-primitives", "polkadot-primitives", "sc-network", @@ -9146,7 +9153,7 @@ dependencies = [ "kvdb", "parity-db", "parity-scale-codec", - "parking_lot 0.12.1", + "parking_lot 0.12.3", "pin-project", "polkadot-node-jaeger", "polkadot-node-metrics", @@ -9177,7 +9184,7 @@ dependencies = [ "futures", "futures-timer", "orchestra", - "parking_lot 0.12.1", + "parking_lot 0.12.3", "polkadot-node-metrics", "polkadot-node-network-protocol", "polkadot-node-primitives", @@ -9412,7 +9419,7 @@ dependencies = [ "pallet-transaction-payment-rpc-runtime-api", "parity-db", "parity-scale-codec", - "parking_lot 0.12.1", + "parking_lot 0.12.3", "polkadot-approval-distribution", "polkadot-availability-bitfield-distribution", "polkadot-availability-distribution", @@ -9553,7 +9560,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6380dbe1fb03ecc74ad55d841cfc75480222d153ba69ddcb00977866cbdabdb8" dependencies = [ "polkavm-derive-impl", - "syn 2.0.58", + "syn 2.0.71", ] [[package]] @@ -9565,7 +9572,7 @@ dependencies = [ "polkavm-common", "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.71", ] [[package]] @@ -9586,15 +9593,15 @@ dependencies = [ [[package]] name = "polling" -version = "3.6.0" +version = "3.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0c976a60b2d7e99d6f229e414670a9b85d13ac305cc6d1e9c134de58c5aaaf6" +checksum = "a3ed00ed3fbf728b5816498ecd316d1716eecaced9c0c8d2c5a6740ca214985b" dependencies = [ "cfg-if", "concurrent-queue", - "hermit-abi", + "hermit-abi 0.4.0", "pin-project-lite 0.2.14", - "rustix 0.38.32", + "rustix 0.38.34", "tracing", "windows-sys 0.52.0", ] @@ -9903,21 +9910,11 @@ dependencies = [ "termtree", ] -[[package]] -name = "prettier-please" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22020dfcf177fcc7bf5deaf7440af371400c67c0de14c399938d8ed4fb4645d3" -dependencies = [ - "proc-macro2", - "syn 2.0.58", -] - [[package]] name = "prettyplease" -version = "0.1.11" +version = "0.1.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f28f53e8b192565862cf99343194579a022eb9c7dd3a8d03134734803c7b3125" +checksum = "6c8646e95016a7a6c4adea95bafa8a16baab64b583356217f2c85db4a39d9a86" dependencies = [ "proc-macro2", "syn 1.0.109", @@ -9925,12 +9922,12 @@ dependencies = [ [[package]] name = "prettyplease" -version = "0.2.17" +version = "0.2.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d3928fb5db768cb86f891ff014f0144589297e3c6a1aba6ed7cecfdace270c7" +checksum = "5f12335488a2f3b0a83b14edad48dca9879ce89b2edd10e80237e4e852dd645e" dependencies = [ "proc-macro2", - "syn 2.0.58", + "syn 2.0.71", ] [[package]] @@ -9966,12 +9963,12 @@ dependencies = [ [[package]] name = "proc-macro-crate" -version = "1.3.1" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" +checksum = "e17d47ce914bf4de440332250b0edd23ce48c005f59fab39d3335866b114f11a" dependencies = [ - "once_cell", - "toml_edit 0.19.15", + "thiserror", + "toml 0.5.11", ] [[package]] @@ -10024,29 +10021,29 @@ checksum = "834da187cfe638ae8abb0203f0b33e5ccdb02a28e7199f2f47b3e2754f50edca" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.71", ] [[package]] name = "proc-macro2" -version = "1.0.79" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e835ff2298f5721608eb1a980ecaee1aef2c132bf95ecc026a11b7bf3c01c02e" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] [[package]] name = "prometheus" -version = "0.13.3" +version = "0.13.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "449811d15fbdf5ceb5c1144416066429cf82316e2ec8ce0c1f6f8a02e7bbcf8c" +checksum = "3d33c28a30771f7f96db69893f78b857f7450d7e0237e9c8fc6427a81bae7ed1" dependencies = [ "cfg-if", "fnv", "lazy_static", "memchr", - "parking_lot 0.12.1", + "parking_lot 0.12.3", "thiserror", ] @@ -10058,7 +10055,7 @@ checksum = "5d6fa99d535dd930d1249e6c79cb3c2915f9172a540fe2b02a4c8f9ca954721e" dependencies = [ "dtoa", "itoa", - "parking_lot 0.12.1", + "parking_lot 0.12.3", "prometheus-client-derive-encode", ] @@ -10070,7 +10067,7 @@ checksum = "440f724eba9f6996b75d63681b0a92b06947f1457076d503a4d2e2c8f56442b8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.71", ] [[package]] @@ -10085,12 +10082,12 @@ dependencies = [ [[package]] name = "prost" -version = "0.12.3" +version = "0.12.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "146c289cda302b98a28d40c8b3b90498d6e526dd24ac2ecea73e4e491685b94a" +checksum = "deb1435c188b76130da55f17a466d252ff7b1418b2ad3e037d127b94e3411f29" dependencies = [ "bytes", - "prost-derive 0.12.3", + "prost-derive 0.12.6", ] [[package]] @@ -10106,7 +10103,7 @@ dependencies = [ "log", "multimap", "petgraph", - "prettyplease 0.1.11", + "prettyplease 0.1.25", "prost 0.11.9", "prost-types", "regex", @@ -10130,15 +10127,15 @@ dependencies = [ [[package]] name = "prost-derive" -version = "0.12.3" +version = "0.12.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "efb6c9a1dd1def8e2124d17e83a20af56f1570d6c2d2bd9e266ccb768df3840e" +checksum = "81bddcdb20abf9501610992b6759a4c888aef7d1a7247ef75e2404275ac24af1" dependencies = [ "anyhow", - "itertools 0.11.0", + "itertools 0.12.1", "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.71", ] [[package]] @@ -10218,9 +10215,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.35" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] @@ -10277,7 +10274,7 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ - "getrandom 0.2.12", + "getrandom 0.2.15", ] [[package]] @@ -10355,13 +10352,22 @@ dependencies = [ "bitflags 1.3.2", ] +[[package]] +name = "redox_syscall" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a908a6e00f1fdd0dfd9c0eb08ce85126f6d8bbda50017e74bc4a4b7d4a926a4" +dependencies = [ + "bitflags 2.6.0", +] + [[package]] name = "redox_users" version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bd283d9651eeda4b2a83a43c1c91b266c40fd76ecd39a50a8c630ae69dc72891" dependencies = [ - "getrandom 0.2.12", + "getrandom 0.2.15", "libredox", "thiserror", ] @@ -10380,22 +10386,22 @@ dependencies = [ [[package]] name = "ref-cast" -version = "1.0.22" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4846d4c50d1721b1a3bef8af76924eef20d5e723647333798c1b519b3a9473f" +checksum = "ccf0a6f84d5f1d581da8b41b47ec8600871962f2a528115b542b362d4b744931" dependencies = [ "ref-cast-impl", ] [[package]] name = "ref-cast-impl" -version = "1.0.22" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fddb4f8d99b0a2ebafc65a87a69a7b9875e4b1ae1f00db265d300ef7f28bccc" +checksum = "bcc303e793d3734489387d205e9b186fac9c6cfacedd98cbb2e8a5943595f3e6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.71", ] [[package]] @@ -10412,14 +10418,14 @@ dependencies = [ [[package]] name = "regex" -version = "1.10.4" +version = "1.10.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c" +checksum = "b91213439dad192326a0d7c6ee3955910425f441d7038e0d6933b0aec5c4517f" dependencies = [ "aho-corasick", "memchr", - "regex-automata 0.4.6", - "regex-syntax 0.8.3", + "regex-automata 0.4.7", + "regex-syntax 0.8.4", ] [[package]] @@ -10433,13 +10439,13 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.6" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea" +checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" dependencies = [ "aho-corasick", "memchr", - "regex-syntax 0.8.3", + "regex-syntax 0.8.4", ] [[package]] @@ -10450,9 +10456,9 @@ checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" [[package]] name = "regex-syntax" -version = "0.8.3" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56" +checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" [[package]] name = "resolv-conf" @@ -10471,7 +10477,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" dependencies = [ "hmac 0.12.1", - "subtle 2.5.0", + "subtle 2.6.1", ] [[package]] @@ -10497,7 +10503,7 @@ checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" dependencies = [ "cc", "cfg-if", - "getrandom 0.2.12", + "getrandom 0.2.15", "libc", "spin 0.9.8", "untrusted 0.9.0", @@ -10692,9 +10698,9 @@ dependencies = [ [[package]] name = "rustc-demangle" -version = "0.1.23" +version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" +checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" [[package]] name = "rustc-hash" @@ -10714,7 +10720,7 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" dependencies = [ - "semver 1.0.22", + "semver 1.0.23", ] [[package]] @@ -10756,14 +10762,14 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.32" +version = "0.38.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65e04861e65f21776e67888bfbea442b3642beaa0138fdb1dd7a84a52dffdb89" +checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "errno", "libc", - "linux-raw-sys 0.4.13", + "linux-raw-sys 0.4.14", "windows-sys 0.52.0", ] @@ -10781,9 +10787,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.21.10" +version = "0.21.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9d5a6813c0759e4609cd494e8e725babae6a2ca7b62a5536a13daaec6fcb7ba" +checksum = "3f56a14d1f48b391359b22f731fd4bd7e43c97f3c50eee276f3aa09c94784d3e" dependencies = [ "log", "ring 0.17.8", @@ -10793,15 +10799,15 @@ dependencies = [ [[package]] name = "rustls" -version = "0.22.3" +version = "0.22.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99008d7ad0bbbea527ec27bddbc0e432c5b87d8175178cee68d2eec9c4a1813c" +checksum = "bf4ef73721ac7bcd79b2b315da7779d8fc09718c6b3d2d1b2d94850eb8c18432" dependencies = [ "log", "ring 0.17.8", "rustls-pki-types", - "rustls-webpki 0.102.2", - "subtle 2.5.0", + "rustls-webpki 0.102.5", + "subtle 2.6.1", "zeroize", ] @@ -10819,12 +10825,12 @@ dependencies = [ [[package]] name = "rustls-native-certs" -version = "0.7.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f1fb85efa936c42c6d5fc28d2629bb51e4b2f4b8a5211e297d599cc5a093792" +checksum = "a88d6d420651b496bdd98684116959239430022a115c1240e6c3993be0b15fba" dependencies = [ "openssl-probe", - "rustls-pemfile 2.1.1", + "rustls-pemfile 2.1.2", "rustls-pki-types", "schannel", "security-framework", @@ -10841,19 +10847,19 @@ dependencies = [ [[package]] name = "rustls-pemfile" -version = "2.1.1" +version = "2.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f48172685e6ff52a556baa527774f61fcaa884f59daf3375c62a3f1cd2549dab" +checksum = "29993a25686778eb88d4189742cd713c9bce943bc54251a33509dc63cbacf73d" dependencies = [ - "base64 0.21.7", + "base64 0.22.1", "rustls-pki-types", ] [[package]] name = "rustls-pki-types" -version = "1.4.1" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecd36cc4259e3e4514335c4a138c6b43171a8d61d8f5c9348f9fc7529416f247" +checksum = "976295e77ce332211c0d24d92c0e83e50f5c5f046d11082cea19f3df13a3562d" [[package]] name = "rustls-webpki" @@ -10867,9 +10873,9 @@ dependencies = [ [[package]] name = "rustls-webpki" -version = "0.102.2" +version = "0.102.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "faaa0a62740bedb9b2ef5afa303da42764c012f743917351dc9a237ea1663610" +checksum = "f9a6fccd794a42c2c105b513a2f62bc3fd8f3ba57a4593677ceb0bd035164d78" dependencies = [ "ring 0.17.8", "rustls-pki-types", @@ -10878,9 +10884,9 @@ dependencies = [ [[package]] name = "rustversion" -version = "1.0.14" +version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" +checksum = "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6" [[package]] name = "ruzstd" @@ -10917,15 +10923,15 @@ dependencies = [ [[package]] name = "ryu" -version = "1.0.17" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1" +checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" [[package]] name = "safe_arch" -version = "0.7.1" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f398075ce1e6a179b46f51bd88d0598b92b00d3551f1a2d4ac49e771b56ac354" +checksum = "c3460605018fdc9612bce72735cba0d27efbcd9904780d44c7e3a9948f96148a" dependencies = [ "bytemuck", ] @@ -10966,7 +10972,7 @@ dependencies = [ "multihash 0.18.1", "multihash-codetable", "parity-scale-codec", - "prost 0.12.3", + "prost 0.12.6", "prost-build", "rand", "sc-client-api", @@ -11026,7 +11032,7 @@ version = "28.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0f73880050f8b04fed7f6301279ef3899df13a3891bd06156d56f9a1c50fefba" dependencies = [ - "array-bytes 6.2.2", + "array-bytes 6.2.3", "docify", "log", "memmap2 0.9.4", @@ -11056,7 +11062,7 @@ dependencies = [ "proc-macro-crate 3.1.0", "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.71", ] [[package]] @@ -11065,7 +11071,7 @@ version = "0.37.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e8a284c10ea92b1fe789b9f0e5815d393f3a1e3bf6a4adaa884f24e36143b83b" dependencies = [ - "array-bytes 6.2.2", + "array-bytes 6.2.3", "bip39", "chrono", "clap", @@ -11111,7 +11117,7 @@ dependencies = [ "futures", "log", "parity-scale-codec", - "parking_lot 0.12.1", + "parking_lot 0.12.3", "sc-executor", "sc-transaction-pool-api", "sc-utils", @@ -11143,7 +11149,7 @@ dependencies = [ "log", "parity-db", "parity-scale-codec", - "parking_lot 0.12.1", + "parking_lot 0.12.3", "sc-client-api", "sc-state-db", "schnellru", @@ -11168,7 +11174,7 @@ dependencies = [ "libp2p-identity", "log", "mockall", - "parking_lot 0.12.1", + "parking_lot 0.12.3", "sc-client-api", "sc-utils", "serde", @@ -11226,7 +11232,7 @@ dependencies = [ "num-rational", "num-traits", "parity-scale-codec", - "parking_lot 0.12.1", + "parking_lot 0.12.3", "sc-client-api", "sc-consensus", "sc-consensus-epochs", @@ -11278,14 +11284,14 @@ version = "14.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e9ce3ee15eff7fa642791966d427f185184df3c7f4e58893705f3e7781da8ef5" dependencies = [ - "array-bytes 6.2.2", + "array-bytes 6.2.3", "async-channel 1.9.0", "async-trait", "fnv", "futures", "log", "parity-scale-codec", - "parking_lot 0.12.1", + "parking_lot 0.12.3", "sc-client-api", "sc-consensus", "sc-network", @@ -11319,7 +11325,7 @@ dependencies = [ "jsonrpsee 0.20.3", "log", "parity-scale-codec", - "parking_lot 0.12.1", + "parking_lot 0.12.3", "sc-consensus-beefy", "sc-rpc", "serde", @@ -11350,7 +11356,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ae91e5b5a120be4d13a59eaf94fd85d7c7af528482b8e21d861fa1167df3083" dependencies = [ "ahash 0.8.11", - "array-bytes 6.2.2", + "array-bytes 6.2.3", "async-trait", "dyn-clone", "finality-grandpa", @@ -11359,7 +11365,7 @@ dependencies = [ "futures-timer", "log", "parity-scale-codec", - "parking_lot 0.12.1", + "parking_lot 0.12.3", "rand", "sc-block-builder", "sc-chain-spec", @@ -11439,7 +11445,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "aa2ac6c356538d67987bbb867e11a12a84ba87250c70fd50005b6d74f570a4f7" dependencies = [ "parity-scale-codec", - "parking_lot 0.12.1", + "parking_lot 0.12.3", "sc-executor-common", "sc-executor-wasmtime", "schnellru", @@ -11478,7 +11484,7 @@ dependencies = [ "cfg-if", "libc", "log", - "parking_lot 0.12.1", + "parking_lot 0.12.3", "rustix 0.36.17", "sc-allocator", "sc-executor-common", @@ -11511,8 +11517,8 @@ version = "26.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4cc4f6a558dd23e3bae2e9f195da822465258b9aaf211c34360d7f6efb944e54" dependencies = [ - "array-bytes 6.2.2", - "parking_lot 0.12.1", + "array-bytes 6.2.3", + "parking_lot 0.12.3", "serde_json", "sp-application-crypto", "sp-core", @@ -11537,7 +11543,7 @@ dependencies = [ "mixnet", "multiaddr", "parity-scale-codec", - "parking_lot 0.12.1", + "parking_lot 0.12.3", "sc-client-api", "sc-network", "sc-transaction-pool-api", @@ -11556,7 +11562,7 @@ version = "0.35.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f231c7d5e749ec428b4cfa669d759ae76cd3da4f50d7352a2d711acdc7532891" dependencies = [ - "array-bytes 6.2.2", + "array-bytes 6.2.3", "async-channel 1.9.0", "async-trait", "asynchronous-codec", @@ -11571,7 +11577,7 @@ dependencies = [ "log", "mockall", "parity-scale-codec", - "parking_lot 0.12.1", + "parking_lot 0.12.3", "partial_sort", "pin-project", "rand", @@ -11605,7 +11611,7 @@ dependencies = [ "futures", "libp2p-identity", "log", - "prost 0.12.3", + "prost 0.12.6", "prost-build", "sc-client-api", "sc-network", @@ -11659,13 +11665,13 @@ version = "0.34.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "38d84ef0b212c775f58e0304ec09166089f6b09afddf559b7c2b5702933b3be4" dependencies = [ - "array-bytes 6.2.2", + "array-bytes 6.2.3", "async-channel 1.9.0", "futures", "libp2p-identity", "log", "parity-scale-codec", - "prost 0.12.3", + "prost 0.12.6", "prost-build", "sc-client-api", "sc-network", @@ -11681,7 +11687,7 @@ version = "0.34.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9aa9377059deece4e7d419d9ec456f657268c0c603e1cf98df4a920f6da83461" dependencies = [ - "array-bytes 6.2.2", + "array-bytes 6.2.3", "async-channel 1.9.0", "async-trait", "fork-tree", @@ -11691,7 +11697,7 @@ dependencies = [ "log", "mockall", "parity-scale-codec", - "prost 0.12.3", + "prost 0.12.6", "prost-build", "sc-client-api", "sc-consensus", @@ -11718,7 +11724,7 @@ version = "0.34.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "16c9cad4baf348725bd82eadcd1747fc112ec49c76b863755ce79c588fa73fe4" dependencies = [ - "array-bytes 6.2.2", + "array-bytes 6.2.3", "futures", "libp2p", "log", @@ -11738,7 +11744,7 @@ version = "30.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1aee89f2abd406356bfd688bd7a51155dc963259e4b752bb85d1f8a061a194fd" dependencies = [ - "array-bytes 6.2.2", + "array-bytes 6.2.3", "bytes", "fnv", "futures", @@ -11750,7 +11756,7 @@ dependencies = [ "num_cpus", "once_cell", "parity-scale-codec", - "parking_lot 0.12.1", + "parking_lot 0.12.3", "rand", "sc-client-api", "sc-network", @@ -11787,7 +11793,7 @@ dependencies = [ "jsonrpsee 0.20.3", "log", "parity-scale-codec", - "parking_lot 0.12.1", + "parking_lot 0.12.3", "sc-block-builder", "sc-chain-spec", "sc-client-api", @@ -11853,14 +11859,14 @@ version = "0.35.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a7f10275c62296a785f6e2ac716521e3b6e0fae470416fdf86491cbbfcc2e23d" dependencies = [ - "array-bytes 6.2.2", + "array-bytes 6.2.3", "futures", "futures-util", "hex", "jsonrpsee 0.20.3", "log", "parity-scale-codec", - "parking_lot 0.12.1", + "parking_lot 0.12.3", "sc-chain-spec", "sc-client-api", "sc-rpc", @@ -11892,7 +11898,7 @@ dependencies = [ "jsonrpsee 0.20.3", "log", "parity-scale-codec", - "parking_lot 0.12.1", + "parking_lot 0.12.3", "pin-project", "rand", "sc-chain-spec", @@ -11950,7 +11956,7 @@ checksum = "aa842052c41ad379eaecdfddc0d5c953d57e311ae688233f68f461b91d38da0a" dependencies = [ "log", "parity-scale-codec", - "parking_lot 0.12.1", + "parking_lot 0.12.3", "sp-core", ] @@ -12020,7 +12026,7 @@ dependencies = [ "futures", "libp2p", "log", - "parking_lot 0.12.1", + "parking_lot 0.12.3", "pin-project", "rand", "sc-utils", @@ -12043,7 +12049,7 @@ dependencies = [ "libc", "log", "parity-scale-codec", - "parking_lot 0.12.1", + "parking_lot 0.12.3", "regex", "rustc-hash", "sc-client-api", @@ -12070,7 +12076,7 @@ dependencies = [ "proc-macro-crate 3.1.0", "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.71", ] [[package]] @@ -12085,7 +12091,7 @@ dependencies = [ "linked-hash-map", "log", "parity-scale-codec", - "parking_lot 0.12.1", + "parking_lot 0.12.3", "sc-client-api", "sc-transaction-pool-api", "sc-utils", @@ -12129,7 +12135,7 @@ dependencies = [ "futures-timer", "lazy_static", "log", - "parking_lot 0.12.1", + "parking_lot 0.12.3", "prometheus", "sp-arithmetic", ] @@ -12167,7 +12173,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3475108a1b62c7efd1b5c65974f30109a598b2f45f23c9ae030acb9686966db" dependencies = [ "darling 0.14.4", - "proc-macro-crate 1.3.1", + "proc-macro-crate 1.1.3", "proc-macro2", "quote", "syn 1.0.109", @@ -12195,7 +12201,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "995491f110efdc6bea96d6a746140e32bfceb4ea47510750a5467295a4707a25" dependencies = [ "darling 0.14.4", - "proc-macro-crate 1.3.1", + "proc-macro-crate 1.1.3", "proc-macro2", "quote", "syn 1.0.109", @@ -12203,9 +12209,9 @@ dependencies = [ [[package]] name = "scale-info" -version = "2.11.1" +version = "2.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "788745a868b0e751750388f4e6546eb921ef714a4317fa6954f7cde114eb2eb7" +checksum = "eca070c12893629e2cc820a9761bedf6ce1dcddc9852984d1dc734b8bd9bd024" dependencies = [ "bitvec", "cfg-if", @@ -12217,11 +12223,11 @@ dependencies = [ [[package]] name = "scale-info-derive" -version = "2.11.1" +version = "2.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7dc2f4e8bc344b9fc3d5f74f72c2e55bfc38d28dc2ebc69c194a3df424e4d9ac" +checksum = "2d35494501194174bda522a32605929eefc9ecf7e0a326c26db1fdd85881eb62" dependencies = [ - "proc-macro-crate 1.3.1", + "proc-macro-crate 3.1.0", "proc-macro2", "quote", "syn 1.0.109", @@ -12236,7 +12242,7 @@ dependencies = [ "proc-macro2", "quote", "scale-info", - "syn 2.0.58", + "syn 2.0.71", "thiserror", ] @@ -12271,9 +12277,9 @@ dependencies = [ [[package]] name = "schnellru" -version = "0.2.1" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "772575a524feeb803e5b0fcbc6dd9f367e579488197c94c6e4023aad2305774d" +checksum = "c9a8ef13a93c54d20580de1e5c413e624e53121d42fc7e2c11d10ef7f8b02367" dependencies = [ "ahash 0.8.11", "cfg-if", @@ -12305,13 +12311,13 @@ dependencies = [ "aead", "arrayref", "arrayvec 0.7.4", - "curve25519-dalek 4.1.2", + "curve25519-dalek 4.1.3", "getrandom_or_panic", "merlin", "rand_core 0.6.4", "serde_bytes", "sha2 0.10.8", - "subtle 2.5.0", + "subtle 2.6.1", "zeroize", ] @@ -12347,7 +12353,7 @@ dependencies = [ "der", "generic-array 0.14.7", "pkcs8", - "subtle 2.5.0", + "subtle 2.6.1", "zeroize", ] @@ -12389,11 +12395,11 @@ dependencies = [ [[package]] name = "security-framework" -version = "2.10.0" +version = "2.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "770452e37cad93e0a50d5abc3990d2bc351c36d0328f86cefec2f2fb206eaef6" +checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.6.0", "core-foundation", "core-foundation-sys", "libc", @@ -12402,9 +12408,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.10.0" +version = "2.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41f3cc463c0ef97e11c3461a9d3787412d30e8e7eb907c79180c4a57bf7c04ef" +checksum = "75da29fe9b9b08fe9d6b22b5b4bcbc75d8db3aa31e639aa56bb62e9d46bfceaf" dependencies = [ "core-foundation-sys", "libc", @@ -12421,9 +12427,9 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.22" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92d43fe69e652f3df9bdc2b85b2854a0825b86e4fb76bc44d945137d053639ca" +checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" dependencies = [ "serde", ] @@ -12436,9 +12442,9 @@ checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" [[package]] name = "serde" -version = "1.0.197" +version = "1.0.204" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2" +checksum = "bc76f558e0cbb2a839d37354c575f1dc3fdc6546b5be373ba43d95f231bf7c12" dependencies = [ "serde_derive", ] @@ -12454,29 +12460,29 @@ dependencies = [ [[package]] name = "serde_bytes" -version = "0.11.14" +version = "0.11.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b8497c313fd43ab992087548117643f6fcd935cbf36f176ffda0aacf9591734" +checksum = "387cc504cb06bb40a96c8e04e951fe01854cf6bc921053c954e4a606d9675c6a" dependencies = [ "serde", ] [[package]] name = "serde_derive" -version = "1.0.197" +version = "1.0.204" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" +checksum = "e0cd7e117be63d3c3678776753929474f3b04a43a080c744d6b0ae2a8c28e222" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.71", ] [[package]] name = "serde_json" -version = "1.0.115" +version = "1.0.120" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12dc5c46daa8e9fdf4f5e71b6cf9a53f2487da0e86e55808e2d35539666497dd" +checksum = "4e0d21c9a8cae1235ad58a00c11cb40d4b1e5c784f1ef2c537876ed6ffd8b7c5" dependencies = [ "itoa", "ryu", @@ -12485,9 +12491,9 @@ dependencies = [ [[package]] name = "serde_spanned" -version = "0.6.5" +version = "0.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb3622f419d1296904700073ea6cc23ad690adbd66f13ea683df73298736f0c1" +checksum = "79e674e01f999af37c49f70a6ede167a8a60b2503e56c5599532a65baa5969a0" dependencies = [ "serde", ] @@ -12567,9 +12573,9 @@ checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" [[package]] name = "signal-hook-registry" -version = "1.4.1" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" +checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1" dependencies = [ "libc", ] @@ -12681,13 +12687,13 @@ version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e635339259e51ef85ac7aa29a1cd991b957047507288697a690e80ab97d07cad" dependencies = [ - "async-channel 2.2.0", + "async-channel 2.3.1", "async-executor", - "async-fs 2.1.1", - "async-io 2.3.2", - "async-lock 3.3.0", + "async-fs 2.1.2", + "async-io 2.3.3", + "async-lock 3.4.0", "async-net 2.0.0", - "async-process 2.1.0", + "async-process 2.2.3", "blocking", "futures-lite 2.3.0", ] @@ -12714,7 +12720,7 @@ dependencies = [ "fnv", "futures-lite 1.13.0", "futures-util", - "hashbrown 0.14.3", + "hashbrown 0.14.5", "hex", "hmac 0.12.1", "itertools 0.11.0", @@ -12753,7 +12759,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6d1eaa97d77be4d026a1e7ffad1bb3b78448763b357ea6f8188d3e6f736a9b9" dependencies = [ "arrayvec 0.7.4", - "async-lock 3.3.0", + "async-lock 3.4.0", "atomic-take", "base64 0.21.7", "bip39", @@ -12768,7 +12774,7 @@ dependencies = [ "fnv", "futures-lite 2.3.0", "futures-util", - "hashbrown 0.14.3", + "hashbrown 0.14.5", "hex", "hmac 0.12.1", "itertools 0.12.1", @@ -12818,13 +12824,13 @@ dependencies = [ "futures-channel", "futures-lite 1.13.0", "futures-util", - "hashbrown 0.14.3", + "hashbrown 0.14.5", "hex", "itertools 0.11.0", "log", "lru 0.11.1", "no-std-net", - "parking_lot 0.12.1", + "parking_lot 0.12.3", "pin-project", "rand", "rand_chacha 0.3.1", @@ -12843,8 +12849,8 @@ version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5496f2d116b7019a526b1039ec2247dd172b8670633b1a64a614c9ea12c9d8c7" dependencies = [ - "async-channel 2.2.0", - "async-lock 3.3.0", + "async-channel 2.3.1", + "async-lock 3.4.0", "base64 0.21.7", "blake2-rfc", "derive_more", @@ -12854,13 +12860,13 @@ dependencies = [ "futures-channel", "futures-lite 2.3.0", "futures-util", - "hashbrown 0.14.3", + "hashbrown 0.14.5", "hex", "itertools 0.12.1", "log", "lru 0.12.3", "no-std-net", - "parking_lot 0.12.1", + "parking_lot 0.12.3", "pin-project", "rand", "rand_chacha 0.3.1", @@ -12888,12 +12894,12 @@ dependencies = [ "aes-gcm", "blake2 0.10.6", "chacha20poly1305", - "curve25519-dalek 4.1.2", + "curve25519-dalek 4.1.3", "rand_core 0.6.4", "ring 0.17.8", "rustc_version", "sha2 0.10.8", - "subtle 2.5.0", + "subtle 2.6.1", ] [[package]] @@ -12908,9 +12914,9 @@ dependencies = [ [[package]] name = "snowbridge-beacon-primitives" -version = "0.1.0" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60a73ef707257064bc4ecce8323cdb7c30e8ecd1ce74aa89a6e82e81fa8b9970" +checksum = "5404af73550b39022e08e5500b30fba627e109a56407b7e80b08da2305b11bfe" dependencies = [ "byte-slice-cast", "frame-support", @@ -12933,9 +12939,9 @@ dependencies = [ [[package]] name = "snowbridge-core" -version = "0.1.1" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a3e2e3b94bfcfc8f363e21a6c5a1d3c67eb4592ada672c868a3236ad1dd563b" +checksum = "aed4ebefed4c40b9c00e9adf5f02ab2760a7a2dad8bf05110c0013a7a59f4097" dependencies = [ "ethabi-decode", "frame-support", @@ -13029,9 +13035,9 @@ dependencies = [ [[package]] name = "socket2" -version = "0.5.6" +version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05ffd9c0a93b7543e062e759284fcf5f5e3b098501104bfbdde4d404db792871" +checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" dependencies = [ "libc", "windows-sys 0.52.0", @@ -13084,11 +13090,11 @@ checksum = "0301e2f77afb450fbf2b093f8b324c7ad88cc82e5e69bd5dc8658a1f068b2a96" dependencies = [ "Inflector", "blake2 0.10.6", - "expander 2.1.0", + "expander 2.2.1", "proc-macro-crate 3.1.0", "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.71", ] [[package]] @@ -13155,7 +13161,7 @@ dependencies = [ "futures", "log", "parity-scale-codec", - "parking_lot 0.12.1", + "parking_lot 0.12.3", "schnellru", "sp-api", "sp-consensus", @@ -13278,7 +13284,7 @@ version = "29.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7c33c7a1568175250628567d50c4e1c54a6ac5bc1190413b9be29a9e810cbe73" dependencies = [ - "array-bytes 6.2.2", + "array-bytes 6.2.3", "bip39", "bitflags 1.3.2", "blake2 0.10.6", @@ -13295,7 +13301,7 @@ dependencies = [ "log", "merlin", "parity-scale-codec", - "parking_lot 0.12.1", + "parking_lot 0.12.3", "paste", "primitive-types", "rand", @@ -13354,7 +13360,7 @@ checksum = "b85d0f1f1e44bd8617eb2a48203ee854981229e3e79e6f468c7175d5fd37489b" dependencies = [ "quote", "sp-crypto-hashing", - "syn 2.0.58", + "syn 2.0.71", ] [[package]] @@ -13364,7 +13370,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "722cbecdbf5b94578137dbd07feb51e95f7de221be0c1ff4dcfe0bb4cd986929" dependencies = [ "kvdb", - "parking_lot 0.12.1", + "parking_lot 0.12.3", ] [[package]] @@ -13375,7 +13381,7 @@ checksum = "48d09fa0a5f7299fb81ee25ae3853d26200f7a348148aed6de76be905c007dbe" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.71", ] [[package]] @@ -13461,7 +13467,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "444f2d53968b1ce5e908882710ff1f3873fcf3e95f59d57432daf685bbacb959" dependencies = [ "parity-scale-codec", - "parking_lot 0.12.1", + "parking_lot 0.12.3", "sp-core", "sp-externalities", "thiserror", @@ -13620,11 +13626,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cfaf6e85b2ec12a4b99cd6d8d57d083e30c94b7f1b0d8f93547121495aae6f0c" dependencies = [ "Inflector", - "expander 2.1.0", + "expander 2.2.1", "proc-macro-crate 3.1.0", "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.71", ] [[package]] @@ -13667,7 +13673,7 @@ dependencies = [ "hash-db", "log", "parity-scale-codec", - "parking_lot 0.12.1", + "parking_lot 0.12.3", "rand", "smallvec", "sp-core", @@ -13687,7 +13693,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "309a9ae4e8134bbed8ffc510cf4d461a4a651f9250b556de782cedd876abe1ff" dependencies = [ "aes-gcm", - "curve25519-dalek 4.1.2", + "curve25519-dalek 4.1.3", "ed25519-dalek", "hkdf", "parity-scale-codec", @@ -13791,7 +13797,7 @@ dependencies = [ "memory-db", "nohash-hasher", "parity-scale-codec", - "parking_lot 0.12.1", + "parking_lot 0.12.3", "rand", "scale-info", "schnellru", @@ -13831,7 +13837,7 @@ dependencies = [ "parity-scale-codec", "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.71", ] [[package]] @@ -13962,7 +13968,7 @@ version = "8.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "48fa328b87de3466bc38cc9a07244c42c647b7755b81115e1dfeb47cc13fc6e6" dependencies = [ - "array-bytes 6.2.2", + "array-bytes 6.2.3", "bounded-collections 0.2.0", "derivative", "environmental", @@ -14063,7 +14069,7 @@ dependencies = [ "bitflags 1.3.2", "byteorder", "keccak", - "subtle 2.5.0", + "subtle 2.6.1", "zeroize", ] @@ -14090,9 +14096,9 @@ dependencies = [ [[package]] name = "strum" -version = "0.25.0" +version = "0.26.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "290d54ea6f91c969195bdbcd7442c8c2a2ba87da8bf60a7ee86a235d4bc1e125" +checksum = "8fec0f0aef304996cf250b31b5a10dee7980c85da9d759361292b8bca5a18f06" [[package]] name = "strum_macros" @@ -14109,15 +14115,15 @@ dependencies = [ [[package]] name = "strum_macros" -version = "0.25.3" +version = "0.26.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23dc1fa9ac9c169a78ba62f0b841814b7abae11bdd047b9c58f893439e309ea0" +checksum = "4c6bee85a5a24955dc440386795aa378cd9cf82acd5f764469152d2270e581be" dependencies = [ - "heck 0.4.1", + "heck 0.5.0", "proc-macro2", "quote", "rustversion", - "syn 2.0.58", + "syn 2.0.71", ] [[package]] @@ -14218,7 +14224,7 @@ dependencies = [ "sp-maybe-compressed-blob", "strum 0.24.1", "tempfile", - "toml 0.8.12", + "toml 0.8.14", "walkdir", "wasm-opt", ] @@ -14231,9 +14237,9 @@ checksum = "2d67a5a62ba6e01cb2192ff309324cb4875d0c451d55fe2319433abe7a05a8ee" [[package]] name = "subtle" -version = "2.5.0" +version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "subtle-ng" @@ -14293,7 +14299,7 @@ dependencies = [ "scale-info", "scale-typegen", "subxt-metadata", - "syn 2.0.58", + "syn 2.0.71", "thiserror", "tokio", ] @@ -14321,13 +14327,13 @@ version = "0.34.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "365251668613323064803427af8c7c7bc366cd8b28e33639640757669dafebd5" dependencies = [ - "darling 0.20.8", + "darling 0.20.10", "parity-scale-codec", "proc-macro-error", "quote", "scale-typegen", "subxt-codegen", - "syn 2.0.58", + "syn 2.0.71", ] [[package]] @@ -14378,9 +14384,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.58" +version = "2.0.71" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44cfb93f38070beee36b3fef7d4f5a16f27751d94b187b666a5cc5e9b0d30687" +checksum = "b146dcf730474b4bcd16c311627b31ede9ab149045db4d6088b3becaea046462" dependencies = [ "proc-macro2", "quote", @@ -14399,6 +14405,17 @@ dependencies = [ "unicode-xid", ] +[[package]] +name = "synstructure" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.71", +] + [[package]] name = "system-configuration" version = "0.5.1" @@ -14428,9 +14445,9 @@ checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" [[package]] name = "target-lexicon" -version = "0.12.14" +version = "0.12.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1fc403891a21bcfb7c37834ba66a547a8f402146eba7265b5a6d88059c9ff2f" +checksum = "4873307b7c257eddcb50c9bedf158eb669578359fb28428bef438fec8e6ba7c2" [[package]] name = "tempfile" @@ -14439,8 +14456,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" dependencies = [ "cfg-if", - "fastrand 2.0.2", - "rustix 0.38.32", + "fastrand 2.1.0", + "rustix 0.38.34", "windows-sys 0.52.0", ] @@ -14459,7 +14476,7 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "21bebf2b7c9e0a515f6e0f8c51dc0f8e4696391e6f1ff30379559f8365fb0df7" dependencies = [ - "rustix 0.38.32", + "rustix 0.38.34", "windows-sys 0.48.0", ] @@ -14486,9 +14503,9 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.58" +version = "1.0.62" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03468839009160513471e86a034bb2c5c0e4baae3b43f79ffc55c4a5427b3297" +checksum = "f2675633b1499176c2dff06b0856a27976a8f9d436737b4cf4f312d4d91d8bbb" dependencies = [ "thiserror-impl", ] @@ -14510,18 +14527,18 @@ checksum = "e4c60d69f36615a077cc7663b9cb8e42275722d23e58a7fa3d2c7f2915d09d04" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.71", ] [[package]] name = "thiserror-impl" -version = "1.0.58" +version = "1.0.62" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c61f3ba182994efc43764a46c018c347bc492c79f024e705f46567b418f6d4f7" +checksum = "d20468752b09f49e909e55a5d338caa8bedf615594e9d80bc4c565d30faf798c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.71", ] [[package]] @@ -14585,9 +14602,9 @@ dependencies = [ [[package]] name = "time" -version = "0.3.34" +version = "0.3.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8248b6521bb14bc45b4067159b9b6ad792e2d6d754d6c41fb50e29fefe38749" +checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" dependencies = [ "deranged", "itoa", @@ -14606,9 +14623,9 @@ checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" [[package]] name = "time-macros" -version = "0.2.17" +version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ba3a3ef41e6672a2f0f001392bb5dcd3ff0a9992d618ca761a11c3121547774" +checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf" dependencies = [ "num-conv", "time-core", @@ -14625,9 +14642,9 @@ dependencies = [ [[package]] name = "tinyvec" -version = "1.6.0" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +checksum = "445e881f4f6d382d5f27c034e25eb92edd7c784ceab92a0937db7f2e9471b938" dependencies = [ "tinyvec_macros", ] @@ -14640,32 +14657,32 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.37.0" +version = "1.38.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1adbebffeca75fcfd058afa480fb6c0b81e165a0323f9c9d39c9697e37c46787" +checksum = "ba4f4a02a7a80d6f274636f0aa95c7e383b912d41fe721a31f29e29698585a4a" dependencies = [ "backtrace", "bytes", "libc", "mio", "num_cpus", - "parking_lot 0.12.1", + "parking_lot 0.12.3", "pin-project-lite 0.2.14", "signal-hook-registry", - "socket2 0.5.6", + "socket2 0.5.7", "tokio-macros", "windows-sys 0.48.0", ] [[package]] name = "tokio-macros" -version = "2.2.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" +checksum = "5f5ae998a069d4b5aba8ee9dad856af7d520c3699e6159b185c2acd48155d39a" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.71", ] [[package]] @@ -14685,7 +14702,7 @@ version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" dependencies = [ - "rustls 0.21.10", + "rustls 0.21.12", "tokio", ] @@ -14695,7 +14712,7 @@ version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "775e0c0f0adb3a2f22a00c4745d728b479985fc15ee7ca6a2608388c5569860f" dependencies = [ - "rustls 0.22.3", + "rustls 0.22.4", "rustls-pki-types", "tokio", ] @@ -14714,9 +14731,9 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.10" +version = "0.7.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15" +checksum = "9cf6b47b3771c49ac75ad09a6162f53ad4b8088b76ac60e8ec1455b31a189fe1" dependencies = [ "bytes", "futures-core", @@ -14724,7 +14741,6 @@ dependencies = [ "futures-sink", "pin-project-lite 0.2.14", "tokio", - "tracing", ] [[package]] @@ -14738,36 +14754,25 @@ dependencies = [ [[package]] name = "toml" -version = "0.8.12" +version = "0.8.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9dd1545e8208b4a5af1aa9bbd0b4cf7e9ea08fabc5d0a5c67fcaafa17433aa3" +checksum = "6f49eb2ab21d2f26bd6db7bf383edc527a7ebaee412d17af4d40fdccd442f335" dependencies = [ "serde", "serde_spanned", "toml_datetime", - "toml_edit 0.22.9", + "toml_edit 0.22.15", ] [[package]] name = "toml_datetime" -version = "0.6.5" +version = "0.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1" +checksum = "4badfd56924ae69bcc9039335b2e017639ce3f9b001c393c1b2d1ef846ce2cbf" dependencies = [ "serde", ] -[[package]] -name = "toml_edit" -version = "0.19.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" -dependencies = [ - "indexmap 2.2.6", - "toml_datetime", - "winnow 0.5.40", -] - [[package]] name = "toml_edit" version = "0.20.7" @@ -14792,15 +14797,15 @@ dependencies = [ [[package]] name = "toml_edit" -version = "0.22.9" +version = "0.22.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e40bb779c5187258fd7aad0eb68cb8706a0a81fa712fbea808ab43c4b8374c4" +checksum = "d59a3a72298453f564e2b111fa896f8d07fabb36f51f06d7e875fc5e0b5a3ef1" dependencies = [ "indexmap 2.2.6", "serde", "serde_spanned", "toml_datetime", - "winnow 0.6.5", + "winnow 0.6.13", ] [[package]] @@ -14824,7 +14829,7 @@ version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "61c5bb1d698276a2443e5ecfabc1008bf15a36c12e6a7176e7bf089ea9131140" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "bytes", "futures-core", "futures-util", @@ -14868,7 +14873,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.71", ] [[package]] @@ -14909,11 +14914,11 @@ version = "5.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0f074568687ffdfd0adb6005aa8d1d96840197f2c159f80471285f08694cf0ce" dependencies = [ - "expander 2.1.0", + "expander 2.2.1", "proc-macro-crate 3.1.0", "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.71", ] [[package]] @@ -15046,7 +15051,7 @@ dependencies = [ "ipconfig", "lazy_static", "lru-cache", - "parking_lot 0.12.1", + "parking_lot 0.12.3", "resolv-conf", "smallvec", "thiserror", @@ -15163,9 +15168,9 @@ dependencies = [ [[package]] name = "unicode-width" -version = "0.1.11" +version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85" +checksum = "0336d538f7abc86d282a4189614dfaa90810dfc2c6f6427eaf88e16311dd225d" [[package]] name = "unicode-xid" @@ -15180,7 +15185,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07ea" dependencies = [ "crypto-common", - "subtle 2.5.0", + "subtle 2.6.1", ] [[package]] @@ -15209,9 +15214,9 @@ checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" [[package]] name = "url" -version = "2.5.0" +version = "2.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633" +checksum = "22784dbdf76fdde8af1aeda5622b546b422b6fc585325248a2bf9f5e41e94d6c" dependencies = [ "form_urlencoded", "idna 0.5.0", @@ -15220,9 +15225,9 @@ dependencies = [ [[package]] name = "utf8parse" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "valuable" @@ -15250,9 +15255,9 @@ checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" [[package]] name = "w3f-bls" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7335e4c132c28cc43caef6adb339789e599e39adbe78da0c4d547fad48cbc331" +checksum = "9c5da5fa2c6afa2c9158eaa7cd9aee249765eb32b5fb0c63ad8b9e79336a47ec" dependencies = [ "ark-bls12-377", "ark-bls12-381", @@ -15274,9 +15279,9 @@ dependencies = [ [[package]] name = "waker-fn" -version = "1.1.1" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3c4517f54858c779bbcbf228f4fca63d121bf85fbecb2dc578cdf4a39395690" +checksum = "317211a0dc0ceedd78fb2ca9a44aed3d7b9b26f81870d485c07122b4350673b7" [[package]] name = "walkdir" @@ -15339,7 +15344,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.71", "wasm-bindgen-shared", ] @@ -15373,7 +15378,7 @@ checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.71", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -15491,9 +15496,9 @@ dependencies = [ [[package]] name = "wasmparser-nostd" -version = "0.100.1" +version = "0.100.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9157cab83003221bfd385833ab587a039f5d6fa7304854042ba358a3b09e0724" +checksum = "d5a015fe95f3504a94bb1462c717aae75253e39b9dd6c3fb1062c934535c64aa" dependencies = [ "indexmap-nostd", ] @@ -15724,15 +15729,16 @@ dependencies = [ [[package]] name = "westend-runtime" -version = "8.0.0" +version = "8.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db2a5cebb4c678a0d1291bb21f9d44ddebceae044b0fb5200fa3bed108a31595" +checksum = "b4aa5580861b05668a6af845aa271c4f699a2fc26646d524e5b0d9375fb0647e" dependencies = [ "binary-merkle-tree", "bitvec", "frame-benchmarking", "frame-election-provider-support", "frame-executive", + "frame-metadata-hash-extension", "frame-support", "frame-system", "frame-system-benchmarking", @@ -15855,14 +15861,14 @@ dependencies = [ "either", "home", "once_cell", - "rustix 0.38.32", + "rustix 0.38.34", ] [[package]] name = "wide" -version = "0.7.15" +version = "0.7.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89beec544f246e679fc25490e3f8e08003bc4bf612068f325120dad4cea02c1c" +checksum = "2caba658a80831539b30698ae9862a72db6697dfdd7151e46920f5f2755c3ce2" dependencies = [ "bytemuck", "safe_arch", @@ -15870,9 +15876,9 @@ dependencies = [ [[package]] name = "widestring" -version = "1.0.2" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "653f141f39ec16bba3c5abe400a0c60da7468261cc2cbf36805022876bc721a8" +checksum = "7219d36b6eac893fa81e84ebe06485e7dcbb616177469b142df14f1f4deb1311" [[package]] name = "winapi" @@ -15892,11 +15898,11 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" -version = "0.1.6" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" +checksum = "4d4cc384e1e73b93bafa6fb4f1df8c41695c8a91cf9c4c64358067d15a7b6c6b" dependencies = [ - "winapi", + "windows-sys 0.52.0", ] [[package]] @@ -15930,7 +15936,7 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" dependencies = [ - "windows-targets 0.52.4", + "windows-targets 0.52.6", ] [[package]] @@ -15957,7 +15963,7 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets 0.52.4", + "windows-targets 0.52.6", ] [[package]] @@ -15992,17 +15998,18 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.52.4" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7dd37b7e5ab9018759f893a1952c9420d060016fc19a472b4bb20d1bdd694d1b" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ - "windows_aarch64_gnullvm 0.52.4", - "windows_aarch64_msvc 0.52.4", - "windows_i686_gnu 0.52.4", - "windows_i686_msvc 0.52.4", - "windows_x86_64_gnu 0.52.4", - "windows_x86_64_gnullvm 0.52.4", - "windows_x86_64_msvc 0.52.4", + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", + "windows_i686_gnullvm", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", ] [[package]] @@ -16019,9 +16026,9 @@ checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] name = "windows_aarch64_gnullvm" -version = "0.52.4" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bcf46cf4c365c6f2d1cc93ce535f2c8b244591df96ceee75d8e83deb70a9cac9" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" [[package]] name = "windows_aarch64_msvc" @@ -16037,9 +16044,9 @@ checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] name = "windows_aarch64_msvc" -version = "0.52.4" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da9f259dd3bcf6990b55bffd094c4f7235817ba4ceebde8e6d11cd0c5633b675" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" [[package]] name = "windows_i686_gnu" @@ -16055,9 +16062,15 @@ checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] name = "windows_i686_gnu" -version = "0.52.4" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b474d8268f99e0995f25b9f095bc7434632601028cf86590aea5c8a5cb7801d3" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" [[package]] name = "windows_i686_msvc" @@ -16073,9 +16086,9 @@ checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] name = "windows_i686_msvc" -version = "0.52.4" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1515e9a29e5bed743cb4415a9ecf5dfca648ce85ee42e15873c3cd8610ff8e02" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" [[package]] name = "windows_x86_64_gnu" @@ -16091,9 +16104,9 @@ checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] name = "windows_x86_64_gnu" -version = "0.52.4" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5eee091590e89cc02ad514ffe3ead9eb6b660aedca2183455434b93546371a03" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" [[package]] name = "windows_x86_64_gnullvm" @@ -16109,9 +16122,9 @@ checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] name = "windows_x86_64_gnullvm" -version = "0.52.4" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77ca79f2451b49fa9e2af39f0747fe999fcda4f5e241b2898624dca97a1f2177" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" [[package]] name = "windows_x86_64_msvc" @@ -16127,9 +16140,9 @@ checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] name = "windows_x86_64_msvc" -version = "0.52.4" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32b752e52a2da0ddfbdbcc6fceadfeede4c939ed16d13e648833a61dfb611ed8" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "winnow" @@ -16142,9 +16155,9 @@ dependencies = [ [[package]] name = "winnow" -version = "0.6.5" +version = "0.6.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dffa400e67ed5a4dd237983829e66475f0a4a26938c4b04c21baede6262215b8" +checksum = "59b5e5f6c299a3c7890b876a2a587f3115162487e704907d9b6cd29473052ba1" dependencies = [ "memchr", ] @@ -16185,7 +16198,7 @@ version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c7e468321c81fb07fa7f4c636c3972b9100f0346e5b6a9f2bd0603a52f7ed277" dependencies = [ - "curve25519-dalek 4.1.2", + "curve25519-dalek 4.1.3", "rand_core 0.6.4", "serde", "zeroize", @@ -16253,7 +16266,7 @@ dependencies = [ "Inflector", "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.71", ] [[package]] @@ -16265,7 +16278,7 @@ dependencies = [ "futures", "log", "nohash-hasher", - "parking_lot 0.12.1", + "parking_lot 0.12.3", "rand", "static_assertions", ] @@ -16287,29 +16300,29 @@ dependencies = [ [[package]] name = "zerocopy" -version = "0.7.32" +version = "0.7.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be" +checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.7.32" +version = "0.7.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" +checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.71", ] [[package]] name = "zeroize" -version = "1.7.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" +checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" dependencies = [ "zeroize_derive", ] @@ -16322,7 +16335,7 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.71", ] [[package]] @@ -16365,9 +16378,9 @@ dependencies = [ [[package]] name = "zstd-sys" -version = "2.0.10+zstd.1.5.6" +version = "2.0.12+zstd.1.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c253a4914af5bafc8fa8c86ee400827e83cf6ec01195ec1f1ed8441bf00d65aa" +checksum = "0a4e40c320c3cb459d9a9ff6de98cff88f4751ee9275d140e2be94a2b74e4c13" dependencies = [ "cc", "pkg-config", diff --git a/runtime/devnet/Cargo.toml b/runtime/devnet/Cargo.toml index 7db68576..70e6e9c9 100644 --- a/runtime/devnet/Cargo.toml +++ b/runtime/devnet/Cargo.toml @@ -22,7 +22,7 @@ scale-info.workspace = true smallvec.workspace = true # Local -pop-primitives = { workspace = true, default-features = false, features = ["assets", "cross-chain", "nfts"] } +pop-primitives = { workspace = true, features = ["assets", "cross-chain", "nfts"] } pop-runtime-common = { workspace = true, default-features = false } # Substrate diff --git a/runtime/devnet/src/extensions/mod.rs b/runtime/devnet/src/extensions/mod.rs index 8f0a6eda..c6bab850 100644 --- a/runtime/devnet/src/extensions/mod.rs +++ b/runtime/devnet/src/extensions/mod.rs @@ -307,8 +307,8 @@ pub(crate) fn convert_to_status_code(error: DispatchError, version: u8) -> u32 { // "UnknownFunctionId" and "DecodingFailed" are mapped to specific errors in the API and will // never change. let mut encoded_error = match error { - DispatchError::Other("UnknownFunctionId") => vec![254, 0, 0, 0], - DispatchError::Other("DecodingFailed") => vec![255, 0, 0, 0], + DispatchError::Other("UnknownFunctionId") => Vec::from([254u8, 0, 0, 0]), + DispatchError::Other("DecodingFailed") => Vec::from([255u8, 0, 0, 0]), _ => error.encode(), }; // Resize the encoded value to 4 bytes in order to decode the value in a u32 (4 bytes). diff --git a/runtime/testnet/src/extensions.rs b/runtime/testnet/src/extensions.rs index 61d3cb43..866cb12c 100644 --- a/runtime/testnet/src/extensions.rs +++ b/runtime/testnet/src/extensions.rs @@ -206,7 +206,7 @@ where RuntimeStateKeys::ParachainSystem(key) => { read_parachain_system_state::(key, &mut env) }, - _ => Ok(vec![0u8]), + _ => Ok(Vec::from([0u8])), }? .encode(); From 8730f90d07dbd1ce564a14a19bb1288a70ddaa4b Mon Sep 17 00:00:00 2001 From: Daanvdplas Date: Wed, 17 Jul 2024 17:47:38 +0200 Subject: [PATCH 021/112] refactor: decoding failed and commenting out unimplemented tests --- .../integration-tests/src/local_fungibles.rs | 448 +++++++++--------- pop-api/src/lib.rs | 4 +- pop-api/src/v0/assets/mod.rs | 14 +- primitives/src/lib.rs | 2 +- runtime/devnet/src/extensions/mod.rs | 2 +- 5 files changed, 236 insertions(+), 234 deletions(-) diff --git a/pop-api/integration-tests/src/local_fungibles.rs b/pop-api/integration-tests/src/local_fungibles.rs index d0229c84..bef3aa6a 100644 --- a/pop-api/integration-tests/src/local_fungibles.rs +++ b/pop-api/integration-tests/src/local_fungibles.rs @@ -67,37 +67,6 @@ fn token_decimals(addr: AccountId32, asset_id: AssetId) -> u8 { decoded::(result) } -fn asset_exists(addr: AccountId32, asset_id: AssetId) -> bool { - let function = function_selector("asset_exists"); - let params = [function, asset_id.encode()].concat(); - let result = do_bare_call(addr, params, 0).expect("should work"); - decoded::(result) -} - -fn create( - addr: AccountId32, - asset_id: AssetId, - admin: AccountId32, - min_balance: Balance, -) -> ExecReturnValue { - let function = function_selector("create"); - let params = [function, asset_id.encode(), admin.encode(), min_balance.encode()].concat(); - do_bare_call(addr, params, 0).expect("should work") -} - -fn set_metadata( - addr: AccountId32, - asset_id: AssetId, - name: Vec, - symbol: Vec, - decimals: u8, -) -> ExecReturnValue { - let function = function_selector("set_metadata"); - let params = - [function, asset_id.encode(), name.encode(), symbol.encode(), decimals.encode()].concat(); - do_bare_call(addr, params, 0).expect("should work") -} - fn transfer( addr: AccountId32, asset_id: AssetId, @@ -137,18 +106,49 @@ fn increase_allowance( result } -fn create_asset(owner: AccountId32, asset_id: AssetId, min_balance: Balance) -> AssetId { - assert_eq!( - Assets::create( - RuntimeOrigin::signed(owner.clone()), - asset_id.into(), - owner.into(), - min_balance - ), - Ok(()) - ); - asset_id -} +// fn asset_exists(addr: AccountId32, asset_id: AssetId) -> bool { +// let function = function_selector("asset_exists"); +// let params = [function, asset_id.encode()].concat(); +// let result = do_bare_call(addr, params, 0).expect("should work"); +// decoded::(result) +// } +// +// fn create( +// addr: AccountId32, +// asset_id: AssetId, +// admin: AccountId32, +// min_balance: Balance, +// ) -> ExecReturnValue { +// let function = function_selector("create"); +// let params = [function, asset_id.encode(), admin.encode(), min_balance.encode()].concat(); +// do_bare_call(addr, params, 0).expect("should work") +// } +// +// fn set_metadata( +// addr: AccountId32, +// asset_id: AssetId, +// name: Vec, +// symbol: Vec, +// decimals: u8, +// ) -> ExecReturnValue { +// let function = function_selector("set_metadata"); +// let params = +// [function, asset_id.encode(), name.encode(), symbol.encode(), decimals.encode()].concat(); +// do_bare_call(addr, params, 0).expect("should work") +// } +// +// fn create_asset(owner: AccountId32, asset_id: AssetId, min_balance: Balance) -> AssetId { +// assert_eq!( +// Assets::create( +// RuntimeOrigin::signed(owner.clone()), +// asset_id.into(), +// owner.into(), +// min_balance +// ), +// Ok(()) +// ); +// asset_id +// } fn mint_asset(owner: AccountId32, asset_id: AssetId, to: AccountId32, value: Balance) -> AssetId { assert_eq!( @@ -393,52 +393,52 @@ fn transfer_works() { #[test] #[ignore] -fn increase_allowance_works() { +fn transfer_from_works() { new_test_ext().execute_with(|| { let _ = env_logger::try_init(); - let addr = instantiate("../examples/fungibles/target/ink/fungibles.wasm", 0, vec![]); + let addr = + instantiate("../examples/fungibles/target/ink/fungibles.wasm", INIT_VALUE, vec![]); let amount: Balance = 100 * UNIT; - let asset = 0; - create_asset_and_mint_to(ALICE, asset, addr.clone(), amount); - assert_eq!( - decoded::(increase_allowance(addr.clone(), asset, BOB, amount)), - ConsumerRemaining - ); - let addr = - instantiate("../examples/fungibles/target/ink/fungibles.wasm", INIT_VALUE, vec![1]); // Asset does not exist. - let asset = 1; assert_eq!( - decoded::(increase_allowance(addr.clone(), asset, BOB, amount)), + decoded::(transfer(addr.clone(), 1, BOB, amount,)), Module { index: 52, error: 3 }, ); // Create asset with Alice as owner and mint `amount` to contract address. - create_asset_and_mint_to(ALICE, asset, addr.clone(), amount); + let asset = create_asset_and_mint_to(ALICE, 1, addr.clone(), amount); // Asset is not live, i.e. frozen or being destroyed. freeze_asset(ALICE, asset); assert_eq!( - decoded::(increase_allowance(addr.clone(), asset, BOB, amount)), + decoded::(transfer(addr.clone(), asset, BOB, amount,)), Module { index: 52, error: 16 }, ); thaw_asset(ALICE, asset); - // Successful approval. - assert_eq!(0, Assets::allowance(asset, &addr, &BOB)); - assert!( - !increase_allowance(addr.clone(), asset, BOB, amount).did_revert(), - "Contract reverted!" + // Not enough balance. + assert_eq!( + decoded::(transfer(addr.clone(), asset, BOB, amount + 1 * UNIT)), + Module { index: 52, error: 0 }, ); - assert_eq!(Assets::allowance(asset, &addr, &BOB), amount); - // Additive. - assert!( - !increase_allowance(addr.clone(), asset, BOB, amount).did_revert(), - "Contract reverted!" + // Not enough balance due to ED. + assert_eq!( + decoded::(transfer(addr.clone(), asset, BOB, amount)), + Module { index: 52, error: 0 }, + ); + // Successful transfer. + let bob_balance_before_mint = Assets::balance(asset, &BOB); + let result = transfer(addr.clone(), asset, BOB, amount / 2); + assert!(!result.did_revert(), "Contract reverted!"); + let bob_balance_after_mint = Assets::balance(asset, &BOB); + assert_eq!(bob_balance_after_mint, bob_balance_before_mint + amount / 2); + // Transfer asset to account that does not exist. + assert_eq!( + decoded::(transfer(addr.clone(), asset, FERDIE, amount / 4)), + Token(CannotCreate) ); - assert_eq!(Assets::allowance(asset, &addr, &BOB), amount * 2); // Asset is not live, i.e. frozen or being destroyed. start_destroy_asset(ALICE, asset); assert_eq!( - decoded::(increase_allowance(addr.clone(), asset, BOB, amount)), + decoded::(transfer(addr.clone(), asset, BOB, amount / 4)), Module { index: 52, error: 16 }, ); }); @@ -446,52 +446,52 @@ fn increase_allowance_works() { #[test] #[ignore] -fn transfer_from_works() { +fn increase_allowance_works() { new_test_ext().execute_with(|| { let _ = env_logger::try_init(); - let addr = - instantiate("../examples/fungibles/target/ink/fungibles.wasm", INIT_VALUE, vec![]); + let addr = instantiate("../examples/fungibles/target/ink/fungibles.wasm", 0, vec![]); let amount: Balance = 100 * UNIT; + let asset = 0; + create_asset_and_mint_to(ALICE, asset, addr.clone(), amount); + assert_eq!( + decoded::(increase_allowance(addr.clone(), asset, BOB, amount)), + ConsumerRemaining + ); + let addr = + instantiate("../examples/fungibles/target/ink/fungibles.wasm", INIT_VALUE, vec![1]); // Asset does not exist. + let asset = 1; assert_eq!( - decoded::(transfer(addr.clone(), 1, BOB, amount,)), + decoded::(increase_allowance(addr.clone(), asset, BOB, amount)), Module { index: 52, error: 3 }, ); // Create asset with Alice as owner and mint `amount` to contract address. - let asset = create_asset_and_mint_to(ALICE, 1, addr.clone(), amount); + create_asset_and_mint_to(ALICE, asset, addr.clone(), amount); // Asset is not live, i.e. frozen or being destroyed. freeze_asset(ALICE, asset); assert_eq!( - decoded::(transfer(addr.clone(), asset, BOB, amount,)), + decoded::(increase_allowance(addr.clone(), asset, BOB, amount)), Module { index: 52, error: 16 }, ); thaw_asset(ALICE, asset); - // Not enough balance. - assert_eq!( - decoded::(transfer(addr.clone(), asset, BOB, amount + 1 * UNIT)), - Module { index: 52, error: 0 }, - ); - // Not enough balance due to ED. - assert_eq!( - decoded::(transfer(addr.clone(), asset, BOB, amount)), - Module { index: 52, error: 0 }, + // Successful approval. + assert_eq!(0, Assets::allowance(asset, &addr, &BOB)); + assert!( + !increase_allowance(addr.clone(), asset, BOB, amount).did_revert(), + "Contract reverted!" ); - // Successful transfer. - let bob_balance_before_mint = Assets::balance(asset, &BOB); - let result = transfer(addr.clone(), asset, BOB, amount / 2); - assert!(!result.did_revert(), "Contract reverted!"); - let bob_balance_after_mint = Assets::balance(asset, &BOB); - assert_eq!(bob_balance_after_mint, bob_balance_before_mint + amount / 2); - // Transfer asset to account that does not exist. - assert_eq!( - decoded::(transfer(addr.clone(), asset, FERDIE, amount / 4)), - Token(CannotCreate) + assert_eq!(Assets::allowance(asset, &addr, &BOB), amount); + // Additive. + assert!( + !increase_allowance(addr.clone(), asset, BOB, amount).did_revert(), + "Contract reverted!" ); + assert_eq!(Assets::allowance(asset, &addr, &BOB), amount * 2); // Asset is not live, i.e. frozen or being destroyed. start_destroy_asset(ALICE, asset); assert_eq!( - decoded::(transfer(addr.clone(), asset, BOB, amount / 4)), + decoded::(increase_allowance(addr.clone(), asset, BOB, amount)), Module { index: 52, error: 16 }, ); }); @@ -540,132 +540,132 @@ fn token_metadata_works() { }); } -#[test] -#[ignore] -fn asset_exists_works() { - new_test_ext().execute_with(|| { - let _ = env_logger::try_init(); - let addr = - instantiate("../examples/fungibles/target/ink/fungibles.wasm", INIT_VALUE, vec![]); - - // No tokens in circulation. - assert_eq!(Assets::asset_exists(ASSET_ID), asset_exists(addr.clone(), ASSET_ID)); - - // Tokens in circulation. - create_asset(addr.clone(), ASSET_ID, 1); - assert_eq!(Assets::asset_exists(ASSET_ID), asset_exists(addr, ASSET_ID)); - }); -} - -#[test] -#[ignore] -fn mint_works() { - new_test_ext().execute_with(|| { - let _ = env_logger::try_init(); - let addr = - instantiate("../examples/fungibles/target/ink/fungibles.wasm", INIT_VALUE, vec![]); - let amount: Balance = 100 * UNIT; - - // Asset does not exist. - assert_eq!( - decoded::(transfer_from(addr.clone(), 1, None, Some(BOB), amount, &[0u8])), - Token(UnknownAsset) - ); - let asset = create_asset(ALICE, 1, 2); - // Minting can only be done by the owner. - assert_eq!( - decoded::(transfer_from(addr.clone(), asset, None, Some(BOB), amount, &[0u8])), - Module { index: 52, error: 2 }, - ); - // Minimum balance of an asset can not be zero. - assert_eq!( - decoded::(transfer_from(addr.clone(), asset, None, Some(BOB), 1, &[0u8])), - Token(BelowMinimum) - ); - let asset = create_asset(addr.clone(), 2, 2); - // Asset is not live, i.e. frozen or being destroyed. - freeze_asset(addr.clone(), asset); - assert_eq!( - decoded::(transfer_from(addr.clone(), asset, None, Some(BOB), amount, &[0u8])), - Module { index: 52, error: 16 }, - ); - thaw_asset(addr.clone(), asset); - // Successful mint. - let bob_balance_before_mint = Assets::balance(asset, &BOB); - let result = transfer_from(addr.clone(), asset, None, Some(BOB), amount, &[0u8]); - assert!(!result.did_revert(), "Contract reverted!"); - let bob_balance_after_mint = Assets::balance(asset, &BOB); - assert_eq!(bob_balance_after_mint, bob_balance_before_mint + amount); - // Can not mint more tokens than Balance::MAX. - assert_eq!( - decoded::(transfer_from( - addr.clone(), - asset, - None, - Some(BOB), - Balance::MAX, - &[0u8] - )), - Arithmetic(Overflow) - ); - // Asset is not live, i.e. frozen or being destroyed. - start_destroy_asset(addr.clone(), asset); - assert_eq!( - decoded::(transfer_from(addr.clone(), asset, None, Some(BOB), amount, &[0u8])), - Module { index: 52, error: 16 }, - ); - }); -} - -#[test] -#[ignore] -fn create_works() { - new_test_ext().execute_with(|| { - let _ = env_logger::try_init(); - // Instantiate a contract without balance (relay token). - let addr = instantiate("../examples/fungibles/target/ink/fungibles.wasm", 0, vec![0]); - // No balance to pay for fees. - assert_eq!( - decoded::(create(addr.clone(), ASSET_ID, addr.clone(), 1)), - Module { index: 10, error: 2 }, - ); - // Instantiate a contract without balance (relay token). - let addr = instantiate("../examples/fungibles/target/ink/fungibles.wasm", 100, vec![2]); - // No balance to pay the deposit. - assert_eq!( - decoded::(create(addr.clone(), ASSET_ID, addr.clone(), 1)), - Module { index: 10, error: 2 }, - ); - // Instantiate a contract with balance. - let addr = - instantiate("../examples/fungibles/target/ink/fungibles.wasm", INIT_VALUE, vec![1]); - assert_eq!( - decoded::(create(addr.clone(), ASSET_ID, BOB, 0)), - Module { index: 52, error: 7 }, - ); - create_asset(ALICE, ASSET_ID, 1); - // Asset ID is already taken. - assert_eq!( - decoded::(create(addr.clone(), ASSET_ID, BOB, 1)), - Module { index: 52, error: 5 }, - ); - // The minimal balance for an asset must be non zero. - let new_asset = 2; - let result = create(addr.clone(), new_asset, BOB, 1); - assert!(!result.did_revert(), "Contract reverted!"); - }); -} - -#[test] -#[ignore] -fn set_metadata_works() { - new_test_ext().execute_with(|| { - let _ = env_logger::try_init(); - let addr = - instantiate("../examples/fungibles/target/ink/fungibles.wasm", INIT_VALUE, vec![]); - - create_asset(addr.clone(), ASSET_ID, 1); - let result = set_metadata(addr.clone(), ASSET_ID, vec![12], vec![12], 12); - assert!(!result.did_revert(), "Contract reverted!"); - }); -} +// #[test] +// #[ignore] +// fn asset_exists_works() { +// new_test_ext().execute_with(|| { +// let _ = env_logger::try_init(); +// let addr = +// instantiate("../examples/fungibles/target/ink/fungibles.wasm", INIT_VALUE, vec![]); +// +// // No tokens in circulation. +// assert_eq!(Assets::asset_exists(ASSET_ID), asset_exists(addr.clone(), ASSET_ID)); +// +// // Tokens in circulation. +// create_asset(addr.clone(), ASSET_ID, 1); +// assert_eq!(Assets::asset_exists(ASSET_ID), asset_exists(addr, ASSET_ID)); +// }); +// } + +// #[test] +// #[ignore] +// fn mint_works() { +// new_test_ext().execute_with(|| { +// let _ = env_logger::try_init(); +// let addr = +// instantiate("../examples/fungibles/target/ink/fungibles.wasm", INIT_VALUE, vec![]); +// let amount: Balance = 100 * UNIT; +// +// // Asset does not exist. +// assert_eq!( +// decoded::(transfer_from(addr.clone(), 1, None, Some(BOB), amount, &[0u8])), +// Token(UnknownAsset) +// ); +// let asset = create_asset(ALICE, 1, 2); +// // Minting can only be done by the owner. +// assert_eq!( +// decoded::(transfer_from(addr.clone(), asset, None, Some(BOB), amount, &[0u8])), +// Module { index: 52, error: 2 }, +// ); +// // Minimum balance of an asset can not be zero. +// assert_eq!( +// decoded::(transfer_from(addr.clone(), asset, None, Some(BOB), 1, &[0u8])), +// Token(BelowMinimum) +// ); +// let asset = create_asset(addr.clone(), 2, 2); +// // Asset is not live, i.e. frozen or being destroyed. +// freeze_asset(addr.clone(), asset); +// assert_eq!( +// decoded::(transfer_from(addr.clone(), asset, None, Some(BOB), amount, &[0u8])), +// Module { index: 52, error: 16 }, +// ); +// thaw_asset(addr.clone(), asset); +// // Successful mint. +// let bob_balance_before_mint = Assets::balance(asset, &BOB); +// let result = transfer_from(addr.clone(), asset, None, Some(BOB), amount, &[0u8]); +// assert!(!result.did_revert(), "Contract reverted!"); +// let bob_balance_after_mint = Assets::balance(asset, &BOB); +// assert_eq!(bob_balance_after_mint, bob_balance_before_mint + amount); +// // Can not mint more tokens than Balance::MAX. +// assert_eq!( +// decoded::(transfer_from( +// addr.clone(), +// asset, +// None, +// Some(BOB), +// Balance::MAX, +// &[0u8] +// )), +// Arithmetic(Overflow) +// ); +// // Asset is not live, i.e. frozen or being destroyed. +// start_destroy_asset(addr.clone(), asset); +// assert_eq!( +// decoded::(transfer_from(addr.clone(), asset, None, Some(BOB), amount, &[0u8])), +// Module { index: 52, error: 16 }, +// ); +// }); +// } + +// #[test] +// #[ignore] +// fn create_works() { +// new_test_ext().execute_with(|| { +// let _ = env_logger::try_init(); +// // Instantiate a contract without balance (relay token). +// let addr = instantiate("../examples/fungibles/target/ink/fungibles.wasm", 0, vec![0]); +// // No balance to pay for fees. +// assert_eq!( +// decoded::(create(addr.clone(), ASSET_ID, addr.clone(), 1)), +// Module { index: 10, error: 2 }, +// ); +// // Instantiate a contract without balance (relay token). +// let addr = instantiate("../examples/fungibles/target/ink/fungibles.wasm", 100, vec![2]); +// // No balance to pay the deposit. +// assert_eq!( +// decoded::(create(addr.clone(), ASSET_ID, addr.clone(), 1)), +// Module { index: 10, error: 2 }, +// ); +// // Instantiate a contract with balance. +// let addr = +// instantiate("../examples/fungibles/target/ink/fungibles.wasm", INIT_VALUE, vec![1]); +// assert_eq!( +// decoded::(create(addr.clone(), ASSET_ID, BOB, 0)), +// Module { index: 52, error: 7 }, +// ); +// create_asset(ALICE, ASSET_ID, 1); +// // Asset ID is already taken. +// assert_eq!( +// decoded::(create(addr.clone(), ASSET_ID, BOB, 1)), +// Module { index: 52, error: 5 }, +// ); +// // The minimal balance for an asset must be non zero. +// let new_asset = 2; +// let result = create(addr.clone(), new_asset, BOB, 1); +// assert!(!result.did_revert(), "Contract reverted!"); +// }); +// } + +// #[test] +// #[ignore] +// fn set_metadata_works() { +// new_test_ext().execute_with(|| { +// let _ = env_logger::try_init(); +// let addr = +// instantiate("../examples/fungibles/target/ink/fungibles.wasm", INIT_VALUE, vec![]); +// +// create_asset(addr.clone(), ASSET_ID, 1); +// let result = set_metadata(addr.clone(), ASSET_ID, vec![12], vec![12], 12); +// assert!(!result.did_revert(), "Contract reverted!"); +// }); +// } diff --git a/pop-api/src/lib.rs b/pop-api/src/lib.rs index cb27b17f..9e1deefe 100644 --- a/pop-api/src/lib.rs +++ b/pop-api/src/lib.rs @@ -26,6 +26,8 @@ pub type Result = core::result::Result; #[ink::scale_derive(Encode, Decode, TypeInfo)] pub struct StatusCode(pub u32); +pub(crate) const DECODING_FAILED: u32 = 255; + impl From for StatusCode { fn from(value: u32) -> Self { StatusCode(value) @@ -42,7 +44,7 @@ impl FromStatusCode for StatusCode { impl From for StatusCode { fn from(_: ink::scale::Error) -> Self { - StatusCode(255u32) + StatusCode(DECODING_FAILED) } } diff --git a/pop-api/src/v0/assets/mod.rs b/pop-api/src/v0/assets/mod.rs index ea8991a7..4d942dc6 100644 --- a/pop-api/src/v0/assets/mod.rs +++ b/pop-api/src/v0/assets/mod.rs @@ -1,6 +1,6 @@ use ink::{env::chain_extension::ChainExtensionMethod, prelude::vec::Vec, scale::Decode}; -use crate::{primitives::AssetId, AccountId, Balance, Result, StatusCode}; +use crate::{primitives::AssetId, AccountId, Balance, Result, StatusCode, DECODING_FAILED}; pub mod fungibles; @@ -197,7 +197,7 @@ pub fn total_supply(id: AssetId) -> Result { .output::>, true>() .handle_error_code::() .call(&(id)) - .and_then(|v| Balance::decode(&mut &v[..]).map_err(|_e| StatusCode(255u32))) + .and_then(|v| Balance::decode(&mut &v[..]).map_err(|_e| StatusCode(DECODING_FAILED))) } #[inline] @@ -212,7 +212,7 @@ pub fn balance_of(id: AssetId, owner: AccountId) -> Result { .output::>, true>() .handle_error_code::() .call(&(id, owner)) - .and_then(|v| Balance::decode(&mut &v[..]).map_err(|_e| StatusCode(255u32))) + .and_then(|v| Balance::decode(&mut &v[..]).map_err(|_e| StatusCode(DECODING_FAILED))) } #[inline] @@ -222,7 +222,7 @@ pub fn allowance(id: AssetId, owner: AccountId, spender: AccountId) -> Result>, true>() .handle_error_code::() .call(&(id, owner, spender)) - .and_then(|v| Balance::decode(&mut &v[..]).map_err(|_e| StatusCode(255u32))) + .and_then(|v| Balance::decode(&mut &v[..]).map_err(|_e| StatusCode(DECODING_FAILED))) } #[inline] @@ -237,7 +237,7 @@ pub fn token_name(id: AssetId) -> Result> { .output::>, true>() .handle_error_code::() .call(&(id)) - .and_then(|v| >::decode(&mut &v[..]).map_err(|_e| StatusCode(255u32))) + .and_then(|v| >::decode(&mut &v[..]).map_err(|_e| StatusCode(DECODING_FAILED))) } // #[inline] @@ -252,7 +252,7 @@ pub fn token_symbol(id: AssetId) -> Result> { .output::>, true>() .handle_error_code::() .call(&(id)) - .and_then(|v| >::decode(&mut &v[..]).map_err(|_e| StatusCode(255u32))) + .and_then(|v| >::decode(&mut &v[..]).map_err(|_e| StatusCode(DECODING_FAILED))) } #[inline] @@ -267,7 +267,7 @@ pub fn token_decimals(id: AssetId) -> Result { .output::>, true>() .handle_error_code::() .call(&(id)) - .and_then(|v| ::decode(&mut &v[..]).map_err(|_e| StatusCode(255u32))) + .and_then(|v| ::decode(&mut &v[..]).map_err(|_e| StatusCode(DECODING_FAILED))) } // pub(crate) fn asset_exists(id: AssetId) -> Result { diff --git a/primitives/src/lib.rs b/primitives/src/lib.rs index 9d31653a..c0d9f0d3 100644 --- a/primitives/src/lib.rs +++ b/primitives/src/lib.rs @@ -95,7 +95,7 @@ pub mod v0 { // Resize the encoded value to 4 bytes in order to decode the value in a u32 (4 bytes). encoded_error.resize(4, 0); u32::from_le_bytes( - encoded_error.try_into().expect("qid, resized to 4 bytes line above"), + encoded_error.try_into().expect("qed, resized to 4 bytes line above"), ) } } diff --git a/runtime/devnet/src/extensions/mod.rs b/runtime/devnet/src/extensions/mod.rs index c6bab850..f126031b 100644 --- a/runtime/devnet/src/extensions/mod.rs +++ b/runtime/devnet/src/extensions/mod.rs @@ -313,7 +313,7 @@ pub(crate) fn convert_to_status_code(error: DispatchError, version: u8) -> u32 { }; // Resize the encoded value to 4 bytes in order to decode the value in a u32 (4 bytes). encoded_error.resize(4, 0); - let mut encoded_error = encoded_error.try_into().expect("qid, resized to 4 bytes line above"); + let mut encoded_error = encoded_error.try_into().expect("qed, resized to 4 bytes line above"); match version { // If an unknown variant of the `DispatchError` is detected the error needs to be converted // into the encoded value of `Error::Other`. This conversion is performed by shifting the bytes one From b591222168e40099c3d2b759da9765f45ee0a488 Mon Sep 17 00:00:00 2001 From: Daanvdplas Date: Wed, 17 Jul 2024 18:00:11 +0200 Subject: [PATCH 022/112] style: renaming --- pop-api/examples/fungibles/lib.rs | 2 +- pop-api/integration-tests/src/lib.rs | 2 +- .../integration-tests/src/local_fungibles.rs | 50 +++++++++---------- 3 files changed, 27 insertions(+), 27 deletions(-) diff --git a/pop-api/examples/fungibles/lib.rs b/pop-api/examples/fungibles/lib.rs index 2abc422c..1b42fec4 100755 --- a/pop-api/examples/fungibles/lib.rs +++ b/pop-api/examples/fungibles/lib.rs @@ -71,7 +71,7 @@ mod fungibles { from: AccountId, to: AccountId, value: Balance, - // In the standard a `[u8]`, but the size needs to be known at compile time. + // In the PSP-22 standard a `[u8]`, but the size needs to be known at compile time. _data: Vec, ) -> Result<()> { api::transfer_from(id, from, to, value) diff --git a/pop-api/integration-tests/src/lib.rs b/pop-api/integration-tests/src/lib.rs index c6732d91..8c967855 100644 --- a/pop-api/integration-tests/src/lib.rs +++ b/pop-api/integration-tests/src/lib.rs @@ -59,7 +59,7 @@ fn function_selector(name: &str) -> Vec { [hash[0..4].to_vec()].concat() } -fn do_bare_call( +fn bare_call( addr: AccountId32, input: Vec, value: u128, diff --git a/pop-api/integration-tests/src/local_fungibles.rs b/pop-api/integration-tests/src/local_fungibles.rs index bef3aa6a..f39c2327 100644 --- a/pop-api/integration-tests/src/local_fungibles.rs +++ b/pop-api/integration-tests/src/local_fungibles.rs @@ -18,7 +18,7 @@ fn decoded(result: ExecReturnValue) -> T { fn total_supply(addr: AccountId32, asset_id: AssetId) -> Balance { let function = function_selector("total_supply"); let params = [function, asset_id.encode()].concat(); - let result = do_bare_call(addr, params, 0).expect("should work"); + let result = bare_call(addr, params, 0).expect("should work"); decoded::(result) } @@ -26,7 +26,7 @@ fn total_supply(addr: AccountId32, asset_id: AssetId) -> Balance { fn balance_of(addr: AccountId32, asset_id: AssetId, owner: AccountId32) -> Balance { let function = function_selector("balance_of"); let params = [function, asset_id.encode(), owner.encode()].concat(); - let result = do_bare_call(addr, params, 0).expect("should work"); + let result = bare_call(addr, params, 0).expect("should work"); decoded::(result) } @@ -39,7 +39,7 @@ fn allowance( ) -> Balance { let function = function_selector("allowance"); let params = [function, asset_id.encode(), owner.encode(), spender.encode()].concat(); - let result = do_bare_call(addr, params, 0).expect("should work"); + let result = bare_call(addr, params, 0).expect("should work"); decoded::(result) } @@ -47,7 +47,7 @@ fn allowance( fn token_name(addr: AccountId32, asset_id: AssetId) -> Vec { let function = function_selector("token_name"); let params = [function, asset_id.encode()].concat(); - let result = do_bare_call(addr, params, 0).expect("should work"); + let result = bare_call(addr, params, 0).expect("should work"); decoded::>(result) } @@ -55,7 +55,7 @@ fn token_name(addr: AccountId32, asset_id: AssetId) -> Vec { fn token_symbol(addr: AccountId32, asset_id: AssetId) -> Vec { let function = function_selector("token_symbol"); let params = [function, asset_id.encode()].concat(); - let result = do_bare_call(addr, params, 0).expect("should work"); + let result = bare_call(addr, params, 0).expect("should work"); decoded::>(result) } @@ -63,7 +63,7 @@ fn token_symbol(addr: AccountId32, asset_id: AssetId) -> Vec { fn token_decimals(addr: AccountId32, asset_id: AssetId) -> u8 { let function = function_selector("token_decimals"); let params = [function, asset_id.encode()].concat(); - let result = do_bare_call(addr, params, 0).expect("should work"); + let result = bare_call(addr, params, 0).expect("should work"); decoded::(result) } @@ -75,7 +75,7 @@ fn transfer( ) -> ExecReturnValue { let function = function_selector("transfer"); let params = [function, asset_id.encode(), to.encode(), value.encode()].concat(); - let result = do_bare_call(addr, params, 0).expect("should work"); + let result = bare_call(addr, params, 0).expect("should work"); result } @@ -91,7 +91,7 @@ fn transfer_from( let params = [function, asset_id.encode(), from.encode(), to.encode(), value.encode(), data.encode()] .concat(); - do_bare_call(addr, params, 0).expect("should work") + bare_call(addr, params, 0).expect("should work") } fn increase_allowance( @@ -102,14 +102,14 @@ fn increase_allowance( ) -> ExecReturnValue { let function = function_selector("increase_allowance"); let params = [function, asset_id.encode(), spender.encode(), value.encode()].concat(); - let result = do_bare_call(addr, params, 0).expect("should work"); + let result = bare_call(addr, params, 0).expect("should work"); result } // fn asset_exists(addr: AccountId32, asset_id: AssetId) -> bool { // let function = function_selector("asset_exists"); // let params = [function, asset_id.encode()].concat(); -// let result = do_bare_call(addr, params, 0).expect("should work"); +// let result = bare_call(addr, params, 0).expect("should work"); // decoded::(result) // } // @@ -121,7 +121,7 @@ fn increase_allowance( // ) -> ExecReturnValue { // let function = function_selector("create"); // let params = [function, asset_id.encode(), admin.encode(), min_balance.encode()].concat(); -// do_bare_call(addr, params, 0).expect("should work") +// bare_call(addr, params, 0).expect("should work") // } // // fn set_metadata( @@ -134,22 +134,22 @@ fn increase_allowance( // let function = function_selector("set_metadata"); // let params = // [function, asset_id.encode(), name.encode(), symbol.encode(), decimals.encode()].concat(); -// do_bare_call(addr, params, 0).expect("should work") -// } -// -// fn create_asset(owner: AccountId32, asset_id: AssetId, min_balance: Balance) -> AssetId { -// assert_eq!( -// Assets::create( -// RuntimeOrigin::signed(owner.clone()), -// asset_id.into(), -// owner.into(), -// min_balance -// ), -// Ok(()) -// ); -// asset_id +// bare_call(addr, params, 0).expect("should work") // } +fn create_asset(owner: AccountId32, asset_id: AssetId, min_balance: Balance) -> AssetId { + assert_eq!( + Assets::create( + RuntimeOrigin::signed(owner.clone()), + asset_id.into(), + owner.into(), + min_balance + ), + Ok(()) + ); + asset_id +} + fn mint_asset(owner: AccountId32, asset_id: AssetId, to: AccountId32, value: Balance) -> AssetId { assert_eq!( Assets::mint(RuntimeOrigin::signed(owner.clone()), asset_id.into(), to.into(), value), From c2acbb57ae9be348a9b4b0c2d7e81330b3a8ef47 Mon Sep 17 00:00:00 2001 From: Daanvdplas Date: Thu, 18 Jul 2024 11:43:37 +0200 Subject: [PATCH 023/112] refactor: bits and pieces --- pop-api/integration-tests/src/lib.rs | 7 +- .../integration-tests/src/local_fungibles.rs | 78 ++++++++----------- pop-api/src/lib.rs | 36 ++++----- pop-api/src/primitives.rs | 6 ++ pop-api/src/v0/assets/fungibles.rs | 58 +++++++++----- pop-api/src/v0/assets/mod.rs | 12 +-- pop-api/src/v0/mod.rs | 17 ++++ pop-api/src/v0/nfts.rs | 3 - primitives/src/lib.rs | 28 +++---- runtime/devnet/src/extensions/mod.rs | 2 +- runtime/testnet/src/extensions.rs | 4 +- 11 files changed, 138 insertions(+), 113 deletions(-) diff --git a/pop-api/integration-tests/src/lib.rs b/pop-api/integration-tests/src/lib.rs index 8c967855..ea5ccb05 100644 --- a/pop-api/integration-tests/src/lib.rs +++ b/pop-api/integration-tests/src/lib.rs @@ -1,6 +1,7 @@ #![cfg(test)] use frame_support::{ + assert_ok, traits::fungibles::{ approvals::Inspect as ApprovalInspect, metadata::Inspect as MetadataInspect, Inspect, }, @@ -17,17 +18,17 @@ use pop_runtime_devnet::{ mod local_fungibles; -type Balance = u128; type AssetId = u32; -const DEBUG_OUTPUT: pallet_contracts::DebugInfo = pallet_contracts::DebugInfo::UnsafeDebug; +type Balance = u128; const ALICE: AccountId32 = AccountId32::new([1_u8; 32]); const BOB: AccountId32 = AccountId32::new([2_u8; 32]); +const DEBUG_OUTPUT: pallet_contracts::DebugInfo = pallet_contracts::DebugInfo::UnsafeDebug; // FERDIE has no initial balance. const FERDIE: AccountId32 = AccountId32::new([3_u8; 32]); +const GAS_LIMIT: Weight = Weight::from_parts(100_000_000_000, 3 * 1024 * 1024); const INIT_AMOUNT: Balance = 100_000_000 * UNIT; const INIT_VALUE: Balance = 100 * UNIT; -const GAS_LIMIT: Weight = Weight::from_parts(100_000_000_000, 3 * 1024 * 1024); fn new_test_ext() -> sp_io::TestExternalities { let mut t = frame_system::GenesisConfig::::default() diff --git a/pop-api/integration-tests/src/local_fungibles.rs b/pop-api/integration-tests/src/local_fungibles.rs index f39c2327..8f0384c0 100644 --- a/pop-api/integration-tests/src/local_fungibles.rs +++ b/pop-api/integration-tests/src/local_fungibles.rs @@ -138,23 +138,22 @@ fn increase_allowance( // } fn create_asset(owner: AccountId32, asset_id: AssetId, min_balance: Balance) -> AssetId { - assert_eq!( - Assets::create( - RuntimeOrigin::signed(owner.clone()), - asset_id.into(), - owner.into(), - min_balance - ), - Ok(()) - ); + assert_ok!(Assets::create( + RuntimeOrigin::signed(owner.clone()), + asset_id.into(), + owner.into(), + min_balance + )); asset_id } fn mint_asset(owner: AccountId32, asset_id: AssetId, to: AccountId32, value: Balance) -> AssetId { - assert_eq!( - Assets::mint(RuntimeOrigin::signed(owner.clone()), asset_id.into(), to.into(), value), - Ok(()) - ); + assert_ok!(Assets::mint( + RuntimeOrigin::signed(owner.clone()), + asset_id.into(), + to.into(), + value + )); asset_id } @@ -178,30 +177,27 @@ fn create_asset_mint_and_approve( approve: Balance, ) { create_asset_and_mint_to(owner.clone(), asset_id, to.clone(), mint); - assert_eq!( - Assets::approve_transfer( - RuntimeOrigin::signed(to.into()), - asset_id.into(), - spender.into(), - approve, - ), - Ok(()) - ); + assert_ok!(Assets::approve_transfer( + RuntimeOrigin::signed(to.into()), + asset_id.into(), + spender.into(), + approve, + )); } // Freeze an asset. fn freeze_asset(owner: AccountId32, asset_id: AssetId) { - assert_eq!(Assets::freeze_asset(RuntimeOrigin::signed(owner.into()), asset_id.into()), Ok(())); + assert_ok!(Assets::freeze_asset(RuntimeOrigin::signed(owner.into()), asset_id.into())); } // Thaw an asset. fn thaw_asset(owner: AccountId32, asset_id: AssetId) { - assert_eq!(Assets::thaw_asset(RuntimeOrigin::signed(owner.into()), asset_id.into()), Ok(())); + assert_ok!(Assets::thaw_asset(RuntimeOrigin::signed(owner.into()), asset_id.into())); } // Start destroying an asset. fn start_destroy_asset(owner: AccountId32, asset_id: AssetId) { - assert_eq!(Assets::start_destroy(RuntimeOrigin::signed(owner.into()), asset_id.into()), Ok(())); + assert_ok!(Assets::start_destroy(RuntimeOrigin::signed(owner.into()), asset_id.into())); } // Create an asset and set metadata. @@ -212,15 +208,12 @@ fn create_asset_and_set_metadata( symbol: Vec, decimals: u8, ) { - assert_eq!( - Assets::create( - RuntimeOrigin::signed(owner.clone()), - asset_id.into(), - owner.clone().into(), - 100 - ), - Ok(()) - ); + assert_ok!(Assets::create( + RuntimeOrigin::signed(owner.clone()), + asset_id.into(), + owner.clone().into(), + 100 + )); set_metadata_asset(owner, asset_id, name, symbol, decimals); } @@ -232,16 +225,13 @@ fn set_metadata_asset( symbol: Vec, decimals: u8, ) { - assert_eq!( - Assets::set_metadata( - RuntimeOrigin::signed(owner.into()), - asset_id.into(), - name, - symbol, - decimals - ), - Ok(()) - ); + assert_ok!(Assets::set_metadata( + RuntimeOrigin::signed(owner.into()), + asset_id.into(), + name, + symbol, + decimals + )); } fn token_name_asset(asset_id: AssetId) -> Vec { diff --git a/pop-api/src/lib.rs b/pop-api/src/lib.rs index 9e1deefe..8d865f0b 100644 --- a/pop-api/src/lib.rs +++ b/pop-api/src/lib.rs @@ -1,7 +1,8 @@ #![cfg_attr(not(feature = "std"), no_std, no_main)] -use ink::env::{chain_extension::FromStatusCode, DefaultEnvironment, Environment}; -use primitives::error::Error; +use ink::env::chain_extension::FromStatusCode; + +use constants::DECODING_FAILED; #[cfg(feature = "assets")] pub use v0::assets; @@ -15,18 +16,25 @@ pub use v0::nfts; pub mod primitives; pub mod v0; -type AccountId = ::AccountId; -type Balance = ::Balance; -#[cfg(any(feature = "nfts", feature = "cross-chain"))] -type BlockNumber = ::BlockNumber; - pub type Result = core::result::Result; #[derive(Debug, Copy, Clone, PartialEq, Eq)] #[ink::scale_derive(Encode, Decode, TypeInfo)] pub struct StatusCode(pub u32); -pub(crate) const DECODING_FAILED: u32 = 255; +mod constants { + // Errors: + pub(crate) const DECODING_FAILED: u32 = 255; + pub(crate) const MODULE_ERROR: u8 = 3; + + // Function IDs: + pub(crate) const DISPATCH: u8 = 0; + pub(crate) const READ_STATE: u8 = 1; + + // Modules: + pub(crate) const ASSETS_MODULE: u8 = 52; + pub(crate) const BALANCES_MODULE: u8 = 10; +} impl From for StatusCode { fn from(value: u32) -> Self { @@ -47,15 +55,3 @@ impl From for StatusCode { StatusCode(DECODING_FAILED) } } - -impl From for Error { - fn from(value: StatusCode) -> Self { - value.0.into() - } -} - -impl From for StatusCode { - fn from(value: Error) -> Self { - StatusCode::from(u32::from(value)) - } -} diff --git a/pop-api/src/primitives.rs b/pop-api/src/primitives.rs index e174a111..b451ce79 100644 --- a/pop-api/src/primitives.rs +++ b/pop-api/src/primitives.rs @@ -1 +1,7 @@ +use ink::env::{DefaultEnvironment, Environment}; pub use pop_primitives::*; + +pub(crate) type AccountId = ::AccountId; +pub(crate) type Balance = ::Balance; +#[cfg(any(feature = "nfts", feature = "cross-chain"))] +type BlockNumber = ::BlockNumber; diff --git a/pop-api/src/v0/assets/fungibles.rs b/pop-api/src/v0/assets/fungibles.rs index 4abd46a6..8bc7d807 100644 --- a/pop-api/src/v0/assets/fungibles.rs +++ b/pop-api/src/v0/assets/fungibles.rs @@ -1,6 +1,11 @@ use ink::prelude::vec::Vec; -use crate::{assets, primitives::AssetId, AccountId, Balance, Result, StatusCode}; +use crate::{ + assets, + constants::{ASSETS_MODULE, BALANCES_MODULE, MODULE_ERROR}, + primitives::{AccountId, AssetId, Balance}, + Result, StatusCode, +}; /// Local Fungibles: /// 1. PSP-22 Interface @@ -101,7 +106,7 @@ pub fn transfer_from(id: AssetId, from: AccountId, to: AccountId, value: Balance /// Returns `Ok(())` if successful, or an error if the approval fails. #[inline] pub fn approve(id: AssetId, spender: AccountId, value: Balance) -> Result<()> { - assets::cancel_approval(id, spender)?; + assets::cancel_approval(id, spender.clone())?; assets::approve_transfer(id, spender, value) } @@ -312,15 +317,15 @@ impl From for FungiblesError { let encoded = value.0.to_le_bytes(); match encoded { // Balances. - [3, 10, 2, _] => FungiblesError::NoBalance, + [MODULE_ERROR, BALANCES_MODULE, 2, _] => FungiblesError::NoBalance, // Assets. - [3, 52, 0, _] => FungiblesError::NoAccount, - [3, 52, 1, _] => FungiblesError::NoPermission, - [3, 52, 2, _] => FungiblesError::Unknown, - [3, 52, 3, _] => FungiblesError::InUse, - [3, 52, 5, _] => FungiblesError::MinBalanceZero, - [3, 52, 7, _] => FungiblesError::InsufficientAllowance, - [3, 52, 10, _] => FungiblesError::AssetNotLive, + [MODULE_ERROR, ASSETS_MODULE, 0, _] => FungiblesError::NoAccount, + [MODULE_ERROR, ASSETS_MODULE, 1, _] => FungiblesError::NoPermission, + [MODULE_ERROR, ASSETS_MODULE, 2, _] => FungiblesError::Unknown, + [MODULE_ERROR, ASSETS_MODULE, 3, _] => FungiblesError::InUse, + [MODULE_ERROR, ASSETS_MODULE, 5, _] => FungiblesError::MinBalanceZero, + [MODULE_ERROR, ASSETS_MODULE, 7, _] => FungiblesError::InsufficientAllowance, + [MODULE_ERROR, ASSETS_MODULE, 10, _] => FungiblesError::AssetNotLive, _ => FungiblesError::Other(value), } } @@ -328,6 +333,7 @@ impl From for FungiblesError { #[cfg(test)] mod tests { + use crate::constants::{ASSETS_MODULE, BALANCES_MODULE}; use ink::scale::Decode; use super::FungiblesError; @@ -359,7 +365,7 @@ mod tests { #[test] fn conversion_status_code_into_fungibles_error_works() { - let errors = vec![ + let other_errors = vec![ Other { dispatch_error_index: 5, error_index: 5, error: 1 }, CannotLookup, BadOrigin, @@ -378,30 +384,42 @@ mod tests { UnknownFunctionId, DecodingFailed, ]; - for error in errors { + for error in other_errors { let status_code: StatusCode = error.into(); let fungibles_error: FungiblesError = status_code.into(); assert_eq!(fungibles_error, FungiblesError::Other(status_code)) } - assert_eq!(into_fungibles_error(Module { index: 10, error: 2 }), FungiblesError::NoBalance); - assert_eq!(into_fungibles_error(Module { index: 52, error: 0 }), FungiblesError::NoAccount); assert_eq!( - into_fungibles_error(Module { index: 52, error: 1 }), + into_fungibles_error(Module { index: BALANCES_MODULE, error: 2 }), + FungiblesError::NoBalance + ); + assert_eq!( + into_fungibles_error(Module { index: ASSETS_MODULE, error: 0 }), + FungiblesError::NoAccount + ); + assert_eq!( + into_fungibles_error(Module { index: ASSETS_MODULE, error: 1 }), FungiblesError::NoPermission ); - assert_eq!(into_fungibles_error(Module { index: 52, error: 2 }), FungiblesError::Unknown); - assert_eq!(into_fungibles_error(Module { index: 52, error: 3 }), FungiblesError::InUse); assert_eq!( - into_fungibles_error(Module { index: 52, error: 5 }), + into_fungibles_error(Module { index: ASSETS_MODULE, error: 2 }), + FungiblesError::Unknown + ); + assert_eq!( + into_fungibles_error(Module { index: ASSETS_MODULE, error: 3 }), + FungiblesError::InUse + ); + assert_eq!( + into_fungibles_error(Module { index: ASSETS_MODULE, error: 5 }), FungiblesError::MinBalanceZero ); assert_eq!( - into_fungibles_error(Module { index: 52, error: 7 }), + into_fungibles_error(Module { index: ASSETS_MODULE, error: 7 }), FungiblesError::InsufficientAllowance ); assert_eq!( - into_fungibles_error(Module { index: 52, error: 10 }), + into_fungibles_error(Module { index: ASSETS_MODULE, error: 10 }), FungiblesError::AssetNotLive ); } diff --git a/pop-api/src/v0/assets/mod.rs b/pop-api/src/v0/assets/mod.rs index 4d942dc6..fa7d523b 100644 --- a/pop-api/src/v0/assets/mod.rs +++ b/pop-api/src/v0/assets/mod.rs @@ -1,18 +1,19 @@ use ink::{env::chain_extension::ChainExtensionMethod, prelude::vec::Vec, scale::Decode}; -use crate::{primitives::AssetId, AccountId, Balance, Result, StatusCode, DECODING_FAILED}; +use crate::{ + constants::{ASSETS_MODULE, DECODING_FAILED, DISPATCH, READ_STATE}, + primitives::{AccountId, AssetId, Balance}, + v0::VERSION, + Result, StatusCode, +}; pub mod fungibles; -const ASSETS_MODULE: u8 = 52; -const VERSION: u8 = 0; - /// [Pallet Assets](https://github.com/paritytech/polkadot-sdk/blob/master/substrate/frame/assets/src/lib.rs): /// 1. Dispatchables /// 2. Read state functions /// /// 1. Dispatchables within pallet assets (TrustBackedAssets instance): -const DISPATCH: u8 = 0; /// - create /// - start_destroy /// - destroy_accounts @@ -170,7 +171,6 @@ pub fn transfer_approved( } /// 2. Read state functions: -const READ_STATE: u8 = 1; /// - total_supply const TOTAL_SUPPLY: u8 = 0; /// - balance_of diff --git a/pop-api/src/v0/mod.rs b/pop-api/src/v0/mod.rs index 310b360c..56bccfc1 100644 --- a/pop-api/src/v0/mod.rs +++ b/pop-api/src/v0/mod.rs @@ -1,3 +1,6 @@ +use crate::StatusCode; +use pop_primitives::error::Error; + #[cfg(feature = "assets")] pub mod assets; #[cfg(feature = "balances")] @@ -6,3 +9,17 @@ pub mod balances; pub mod cross_chain; #[cfg(feature = "nfts")] pub mod nfts; + +pub(crate) const VERSION: u8 = 0; + +impl From for Error { + fn from(value: StatusCode) -> Self { + value.0.into() + } +} + +impl From for StatusCode { + fn from(value: Error) -> Self { + StatusCode::from(u32::from(value)) + } +} diff --git a/pop-api/src/v0/nfts.rs b/pop-api/src/v0/nfts.rs index e111c8dc..63b90a1f 100644 --- a/pop-api/src/v0/nfts.rs +++ b/pop-api/src/v0/nfts.rs @@ -6,12 +6,9 @@ pub use primitives::{CollectionId, ItemId}; use scale::Encode; pub use types::*; -type Result = core::result::Result; type StringLimit = u32; type MaxTips = u32; -type Result = core::result::Result; - /// Issue a new collection of non-fungible items pub fn create( admin: impl Into>, diff --git a/primitives/src/lib.rs b/primitives/src/lib.rs index c0d9f0d3..3b3ff16d 100644 --- a/primitives/src/lib.rs +++ b/primitives/src/lib.rs @@ -48,34 +48,34 @@ pub mod v0 { error_index: u8, // Index for further nesting, e.g. pallet error. error: u8, - } = 0, + }, /// Failed to lookup some data. - CannotLookup = 1, + CannotLookup, /// A bad origin. - BadOrigin = 2, + BadOrigin, /// A custom error in a module. - Module { index: u8, error: u8 } = 3, + Module { index: u8, error: u8 }, /// At least one consumer is remaining so the account cannot be destroyed. - ConsumerRemaining = 4, + ConsumerRemaining, /// There are no providers so the account cannot be created. - NoProviders = 5, + NoProviders, /// There are too many consumers so the account cannot be created. - TooManyConsumers = 6, + TooManyConsumers, /// An error to do with tokens. - Token(TokenError) = 7, + Token(TokenError), /// An arithmetic error. - Arithmetic(ArithmeticError) = 8, + Arithmetic(ArithmeticError), /// The number of transactional layers has been reached, or we are not in a transactional /// layer. - Transactional(TransactionalError) = 9, + Transactional(TransactionalError), /// Resources exhausted, e.g. attempt to read/write data which is too large to manipulate. - Exhausted = 10, + Exhausted, /// The state is corrupt; this is generally not going to fix itself. - Corruption = 11, + Corruption, /// Some resource (e.g. a preimage) is unavailable right now. This might fix itself later. - Unavailable = 12, + Unavailable, /// Root origin is not allowed. - RootNotAllowed = 13, + RootNotAllowed, /// Unknown function id. UnknownFunctionId = 254, /// Decoding failed on the runtime. diff --git a/runtime/devnet/src/extensions/mod.rs b/runtime/devnet/src/extensions/mod.rs index f126031b..720458c8 100644 --- a/runtime/devnet/src/extensions/mod.rs +++ b/runtime/devnet/src/extensions/mod.rs @@ -172,7 +172,7 @@ fn construct_call( params: Vec, ) -> Result { match pallet_index { - 52 => { + index if index == super::Assets::index() as u8 => { let call = versioned_construct_assets_call(version, call_index, params)?; Ok(RuntimeCall::Assets(call)) }, diff --git a/runtime/testnet/src/extensions.rs b/runtime/testnet/src/extensions.rs index 866cb12c..bcb0f835 100644 --- a/runtime/testnet/src/extensions.rs +++ b/runtime/testnet/src/extensions.rs @@ -1,9 +1,9 @@ use cumulus_pallet_parachain_system::RelaychainDataProvider; -use frame_support::traits::{Contains, OriginTrait}; use frame_support::{ dispatch::{GetDispatchInfo, RawOrigin}, pallet_prelude::*, traits::nonfungibles_v2::Inspect, + traits::{Contains, OriginTrait}, }; use pallet_contracts::chain_extension::{ BufInBufOutState, ChainExtension, ChargedAmount, Environment, Ext, InitState, RetVal, @@ -206,7 +206,7 @@ where RuntimeStateKeys::ParachainSystem(key) => { read_parachain_system_state::(key, &mut env) }, - _ => Ok(Vec::from([0u8])), + _ => Ok(Vec::default()), }? .encode(); From 363932022c62e88e28b1360ff3e8c2a6a1aa6ffb Mon Sep 17 00:00:00 2001 From: Daanvdplas Date: Thu, 18 Jul 2024 14:50:52 +0200 Subject: [PATCH 024/112] docs: add docs to code --- pop-api/src/lib.rs | 25 +++++++++++++--- pop-api/src/v0/assets/fungibles.rs | 25 ++++++++++++---- primitives/src/lib.rs | 45 ++++++++++++++++++---------- runtime/devnet/src/extensions/mod.rs | 13 ++++++++ 4 files changed, 84 insertions(+), 24 deletions(-) diff --git a/pop-api/src/lib.rs b/pop-api/src/lib.rs index 8d865f0b..7a0fe75b 100644 --- a/pop-api/src/lib.rs +++ b/pop-api/src/lib.rs @@ -16,12 +16,9 @@ pub use v0::nfts; pub mod primitives; pub mod v0; +/// A result type used by the API, with the `StatusCode` as the error type. pub type Result = core::result::Result; -#[derive(Debug, Copy, Clone, PartialEq, Eq)] -#[ink::scale_derive(Encode, Decode, TypeInfo)] -pub struct StatusCode(pub u32); - mod constants { // Errors: pub(crate) const DECODING_FAILED: u32 = 255; @@ -36,12 +33,31 @@ mod constants { pub(crate) const BALANCES_MODULE: u8 = 10; } +/// Represents a status code returned by the runtime. +/// +/// `StatusCode` encapsulates a `u32` value that indicates the status of an operation performed +/// by the runtime. It helps to communicate the success or failure of a chain extension method +/// call to the contract, providing a standardized way to handle errors. +/// +/// This status code can be used to determine if an operation succeeded or if it encountered +/// an error. A `StatusCode` of `0` typically indicates success, while any other value represents +/// an error. +#[derive(Debug, Copy, Clone, PartialEq, Eq)] +#[ink::scale_derive(Encode, Decode, TypeInfo)] +pub struct StatusCode(pub u32); + impl From for StatusCode { + /// Converts a `u32` into a `StatusCode`. fn from(value: u32) -> Self { StatusCode(value) } } + impl FromStatusCode for StatusCode { + /// Converts a `u32` status code to a `Result`. + /// + /// `Ok(())` if the status code is `0` and `Err(StatusCode(status_code))` for any other status + /// code. fn from_status_code(status_code: u32) -> Result<()> { match status_code { 0 => Ok(()), @@ -51,6 +67,7 @@ impl FromStatusCode for StatusCode { } impl From for StatusCode { + /// Converts a scale decoding error into a `StatusCode` indicating a decoding failure. fn from(_: ink::scale::Error) -> Self { StatusCode(DECODING_FAILED) } diff --git a/pop-api/src/v0/assets/fungibles.rs b/pop-api/src/v0/assets/fungibles.rs index 8bc7d807..e3c9b6be 100644 --- a/pop-api/src/v0/assets/fungibles.rs +++ b/pop-api/src/v0/assets/fungibles.rs @@ -284,9 +284,20 @@ pub fn token_decimals(id: AssetId) -> Result { // assets::asset_exists(id) // } +/// Represents various errors related to local fungible assets in the API. +/// +/// The `FungiblesError` provides a detailed and specific set of error types that can occur when +/// interacting with fungible assets through the Pop API. Each variant signifies a particular error +/// condition, facilitating precise error handling and debugging. +/// +/// It is designed to be lightweight, including only the essential errors relevant to fungible asset +/// operations. The `Other` variant serves as a catch-all for any unexpected errors. For more +/// detailed debugging, the `Other` variant can be converted into the richer `Error` type defined in +/// the primitives crate. #[derive(Debug, PartialEq, Eq)] #[ink::scale_derive(Encode, Decode, TypeInfo)] pub enum FungiblesError { + /// An unspecified or unknown error occurred. Other(StatusCode), /// The asset is not live; either frozen or being destroyed. AssetNotLive, @@ -305,14 +316,18 @@ pub enum FungiblesError { /// The given asset ID is unknown. Unknown, /// No balance for creation of assets or fees. - // - // Originally `pallet_balances::Error::InsufficientBalance` but collides with the - // `InsufficientBalance` error that is used for `pallet_assets::Error::BalanceLow` to adhere to - // standard. + // TODO: Originally `pallet_balances::Error::InsufficientBalance` but collides with the + // `InsufficientBalance` error that is used for `pallet_assets::Error::BalanceLow` to adhere to + // standard. This deserves a second look. NoBalance, } impl From for FungiblesError { + /// Converts a `StatusCode` to a `FungiblesError`. + /// + /// This conversion maps a `StatusCode`, returned by the runtime, to a more descriptive + /// `FungiblesError`. This provides better context and understanding of the error, allowing + /// developers to handle the most important errors effectively. fn from(value: StatusCode) -> Self { let encoded = value.0.to_le_bytes(); match encoded { @@ -381,7 +396,7 @@ mod tests { Corruption, Unavailable, RootNotAllowed, - UnknownFunctionId, + UnknownFunctionCall, DecodingFailed, ]; for error in other_errors { diff --git a/primitives/src/lib.rs b/primitives/src/lib.rs index 3b3ff16d..d177b60f 100644 --- a/primitives/src/lib.rs +++ b/primitives/src/lib.rs @@ -10,20 +10,21 @@ pub use v0::error; pub mod cross_chain; pub mod storage_keys; +/// An opaque 32-byte cryptographic identifier. #[derive(Encode, Decode, Debug, MaxEncodedLen, Eq, PartialEq)] #[cfg_attr(feature = "std", derive(TypeInfo))] pub struct AccountId(pub [u8; 32]); -// Identifier for the class of asset. +/// Identifier for the class of asset. pub type AssetId = u32; #[cfg(feature = "nfts")] pub mod nfts { use bounded_collections::ConstU32; - // Id used for identifying non-fungible collections. + /// Id used for identifying non-fungible collections. pub type CollectionId = u32; - // Id used for identifying non-fungible items. + /// Id used for identifying non-fungible items. pub type ItemId = u32; /// The maximum length of an attribute key. pub type KeyLimit = ConstU32<64>; @@ -36,24 +37,29 @@ pub mod v0 { pub mod error { use super::*; + /// Reason why a Pop API function call failed. #[derive(Encode, Decode, Debug, Eq, PartialEq)] #[cfg_attr(feature = "std", derive(TypeInfo))] #[repr(u8)] pub enum Error { - /// Some unknown error occurred. Go to the Pop API docs section `Pop API error`. - Other { - // Index within the `DispatchError` - dispatch_error_index: u8, - // Index within the `DispatchError` variant. - error_index: u8, - // Index for further nesting, e.g. pallet error. - error: u8, - }, + /// An unknown error occurred. This variant captures any unexpected errors that the + /// contract cannot specifically handle. It is useful for cases where there are breaking + /// changes in the runtime or when an error falls outside the predefined categories. The + /// variant includes: + /// + /// - `dispatch_error_index`: The index within the `DispatchError`. + /// - `error_index`: The index within the `DispatchError` variant (e.g. a `TokenError`). + /// - `error`: The specific error code or sub-index, providing additional context (e.g. + /// `error` in `ModuleError`). + Other { dispatch_error_index: u8, error_index: u8, error: u8 }, /// Failed to lookup some data. CannotLookup, /// A bad origin. BadOrigin, /// A custom error in a module. + /// + /// - `index`: The pallet index. + /// - `error`: The error within the pallet. Module { index: u8, error: u8 }, /// At least one consumer is remaining so the account cannot be destroyed. ConsumerRemaining, @@ -76,13 +82,18 @@ pub mod v0 { Unavailable, /// Root origin is not allowed. RootNotAllowed, - /// Unknown function id. - UnknownFunctionId = 254, - /// Decoding failed on the runtime. + /// Unknown function called. + UnknownFunctionCall = 254, + /// Decoding failed. DecodingFailed = 255, } impl From for Error { + /// Converts a `u32` status code into an `Error`. + /// + /// This conversion maps a raw status code returned by the runtime into the more + /// descriptive `Error` enum variant, providing better context and understanding of the + /// error. fn from(value: u32) -> Self { let encoded = value.to_le_bytes(); Error::decode(&mut &encoded[..]).unwrap_or(Error::DecodingFailed) @@ -90,6 +101,7 @@ pub mod v0 { } impl From for u32 { + /// Converts an `Error` to a `u32` status code. fn from(value: Error) -> Self { let mut encoded_error = value.encode(); // Resize the encoded value to 4 bytes in order to decode the value in a u32 (4 bytes). @@ -100,6 +112,7 @@ pub mod v0 { } } + /// Description of what went wrong when trying to complete an operation on a token. #[derive(Encode, Decode, Clone, Debug, MaxEncodedLen, Eq, PartialEq, Ord, PartialOrd)] #[cfg_attr(feature = "std", derive(TypeInfo))] pub enum TokenError { @@ -126,6 +139,7 @@ pub mod v0 { Blocked, } + /// Arithmetic errors. #[derive(Encode, Decode, Debug, Eq, PartialEq)] #[cfg_attr(feature = "std", derive(TypeInfo))] pub enum ArithmeticError { @@ -137,6 +151,7 @@ pub mod v0 { DivisionByZero, } + /// Errors related to transactional storage layers. #[derive(Encode, Decode, Debug, Eq, PartialEq)] #[cfg_attr(feature = "std", derive(TypeInfo))] pub enum TransactionalError { diff --git a/runtime/devnet/src/extensions/mod.rs b/runtime/devnet/src/extensions/mod.rs index 720458c8..ec2d0bc2 100644 --- a/runtime/devnet/src/extensions/mod.rs +++ b/runtime/devnet/src/extensions/mod.rs @@ -337,6 +337,15 @@ pub(crate) fn convert_to_status_code(error: DispatchError, version: u8) -> u32 { u32::from_le_bytes(encoded_error) } +/// Enum representing the different function identifiers used in the Pop API chain extension. +/// +/// The `FuncId` enum specifies the available functions that can be called through the Pop API chain +/// extension. Each variant corresponds to a specific functionality provided by the chain extension, +/// facilitating the interaction between smart contracts and the runtime. +/// +/// - `Dispatch`: Represents a function call to dispatch a runtime call. +/// - `ReadState`: Represents a function call to read the state from the runtime. +/// - `SendXcm`: Represents a function call to send an XCM message. #[derive(Debug)] pub enum FuncId { Dispatch, @@ -347,6 +356,10 @@ pub enum FuncId { impl TryFrom for FuncId { type Error = DispatchError; + /// Attempts to convert a `u8` value to its corresponding `FuncId` variant. + /// + /// If the `u8` value does not match any known function identifier, it returns a + /// `DispatchError::Other` indicating an unknown function ID. fn try_from(func_id: u8) -> Result { let id = match func_id { 0 => Self::Dispatch, From 81e9844f056123abe88985e64463a753d50f004a Mon Sep 17 00:00:00 2001 From: Daanvdplas Date: Thu, 18 Jul 2024 15:05:42 +0200 Subject: [PATCH 025/112] fix: replace test code to api fungibles --- pop-api/src/v0/assets/fungibles.rs | 15 ++++++++++++--- pop-api/src/v0/mod.rs | 6 ------ primitives/src/lib.rs | 12 ------------ 3 files changed, 12 insertions(+), 21 deletions(-) diff --git a/pop-api/src/v0/assets/fungibles.rs b/pop-api/src/v0/assets/fungibles.rs index e3c9b6be..9084708d 100644 --- a/pop-api/src/v0/assets/fungibles.rs +++ b/pop-api/src/v0/assets/fungibles.rs @@ -349,7 +349,7 @@ impl From for FungiblesError { #[cfg(test)] mod tests { use crate::constants::{ASSETS_MODULE, BALANCES_MODULE}; - use ink::scale::Decode; + use ink::scale::{Decode, Encode}; use super::FungiblesError; use crate::primitives::error::{ @@ -360,8 +360,17 @@ mod tests { }; use crate::StatusCode; + fn error_into_status_code(error: Error) -> StatusCode { + let mut encoded_error = error.encode(); + encoded_error.resize(4, 0); + let value = u32::from_le_bytes( + encoded_error.try_into().expect("qed, resized to 4 bytes line above"), + ); + value.into() + } + fn into_fungibles_error(error: Error) -> FungiblesError { - let status_code: StatusCode = error.into(); + let status_code: StatusCode = error_into_status_code(error); status_code.into() } @@ -400,7 +409,7 @@ mod tests { DecodingFailed, ]; for error in other_errors { - let status_code: StatusCode = error.into(); + let status_code: StatusCode = error_into_status_code(error); let fungibles_error: FungiblesError = status_code.into(); assert_eq!(fungibles_error, FungiblesError::Other(status_code)) } diff --git a/pop-api/src/v0/mod.rs b/pop-api/src/v0/mod.rs index 56bccfc1..8b7a8469 100644 --- a/pop-api/src/v0/mod.rs +++ b/pop-api/src/v0/mod.rs @@ -17,9 +17,3 @@ impl From for Error { value.0.into() } } - -impl From for StatusCode { - fn from(value: Error) -> Self { - StatusCode::from(u32::from(value)) - } -} diff --git a/primitives/src/lib.rs b/primitives/src/lib.rs index d177b60f..b9caf111 100644 --- a/primitives/src/lib.rs +++ b/primitives/src/lib.rs @@ -100,18 +100,6 @@ pub mod v0 { } } - impl From for u32 { - /// Converts an `Error` to a `u32` status code. - fn from(value: Error) -> Self { - let mut encoded_error = value.encode(); - // Resize the encoded value to 4 bytes in order to decode the value in a u32 (4 bytes). - encoded_error.resize(4, 0); - u32::from_le_bytes( - encoded_error.try_into().expect("qed, resized to 4 bytes line above"), - ) - } - } - /// Description of what went wrong when trying to complete an operation on a token. #[derive(Encode, Decode, Clone, Debug, MaxEncodedLen, Eq, PartialEq, Ord, PartialOrd)] #[cfg_attr(feature = "std", derive(TypeInfo))] From 023d3dcffd96e28fd05dcefe84f088b6b64a4f6a Mon Sep 17 00:00:00 2001 From: Daanvdplas Date: Thu, 18 Jul 2024 15:50:44 +0200 Subject: [PATCH 026/112] fix: own review + fixing CI fail --- pop-api/src/lib.rs | 8 +- pop-api/src/primitives.rs | 1 + pop-api/src/v0/assets/fungibles.rs | 57 +++++---- pop-api/src/v0/assets/mod.rs | 140 ++++++++-------------- pop-api/src/v0/mod.rs | 5 +- primitives/src/lib.rs | 6 +- runtime/devnet/src/extensions/mod.rs | 8 +- runtime/devnet/src/extensions/v0/error.rs | 6 +- 8 files changed, 95 insertions(+), 136 deletions(-) diff --git a/pop-api/src/lib.rs b/pop-api/src/lib.rs index 7a0fe75b..86621c51 100644 --- a/pop-api/src/lib.rs +++ b/pop-api/src/lib.rs @@ -29,15 +29,15 @@ mod constants { pub(crate) const READ_STATE: u8 = 1; // Modules: - pub(crate) const ASSETS_MODULE: u8 = 52; - pub(crate) const BALANCES_MODULE: u8 = 10; + pub(crate) const ASSETS: u8 = 52; + pub(crate) const BALANCES: u8 = 10; } /// Represents a status code returned by the runtime. /// /// `StatusCode` encapsulates a `u32` value that indicates the status of an operation performed -/// by the runtime. It helps to communicate the success or failure of a chain extension method -/// call to the contract, providing a standardized way to handle errors. +/// by the runtime. It helps to communicate the success or failure of a Pop API call to the contract, +/// providing a standardized way to handle errors. /// /// This status code can be used to determine if an operation succeeded or if it encountered /// an error. A `StatusCode` of `0` typically indicates success, while any other value represents diff --git a/pop-api/src/primitives.rs b/pop-api/src/primitives.rs index b451ce79..33285044 100644 --- a/pop-api/src/primitives.rs +++ b/pop-api/src/primitives.rs @@ -1,4 +1,5 @@ use ink::env::{DefaultEnvironment, Environment}; + pub use pop_primitives::*; pub(crate) type AccountId = ::AccountId; diff --git a/pop-api/src/v0/assets/fungibles.rs b/pop-api/src/v0/assets/fungibles.rs index 9084708d..255e8502 100644 --- a/pop-api/src/v0/assets/fungibles.rs +++ b/pop-api/src/v0/assets/fungibles.rs @@ -2,7 +2,7 @@ use ink::prelude::vec::Vec; use crate::{ assets, - constants::{ASSETS_MODULE, BALANCES_MODULE, MODULE_ERROR}, + constants::{ASSETS, BALANCES, MODULE_ERROR}, primitives::{AccountId, AssetId, Balance}, Result, StatusCode, }; @@ -106,7 +106,7 @@ pub fn transfer_from(id: AssetId, from: AccountId, to: AccountId, value: Balance /// Returns `Ok(())` if successful, or an error if the approval fails. #[inline] pub fn approve(id: AssetId, spender: AccountId, value: Balance) -> Result<()> { - assets::cancel_approval(id, spender.clone())?; + assets::cancel_approval(id, spender)?; assets::approve_transfer(id, spender, value) } @@ -284,7 +284,7 @@ pub fn token_decimals(id: AssetId) -> Result { // assets::asset_exists(id) // } -/// Represents various errors related to local fungible assets in the API. +/// Represents various errors related to local fungible assets in the Pop API. /// /// The `FungiblesError` provides a detailed and specific set of error types that can occur when /// interacting with fungible assets through the Pop API. Each variant signifies a particular error @@ -332,15 +332,15 @@ impl From for FungiblesError { let encoded = value.0.to_le_bytes(); match encoded { // Balances. - [MODULE_ERROR, BALANCES_MODULE, 2, _] => FungiblesError::NoBalance, + [MODULE_ERROR, BALANCES, 2, _] => FungiblesError::NoBalance, // Assets. - [MODULE_ERROR, ASSETS_MODULE, 0, _] => FungiblesError::NoAccount, - [MODULE_ERROR, ASSETS_MODULE, 1, _] => FungiblesError::NoPermission, - [MODULE_ERROR, ASSETS_MODULE, 2, _] => FungiblesError::Unknown, - [MODULE_ERROR, ASSETS_MODULE, 3, _] => FungiblesError::InUse, - [MODULE_ERROR, ASSETS_MODULE, 5, _] => FungiblesError::MinBalanceZero, - [MODULE_ERROR, ASSETS_MODULE, 7, _] => FungiblesError::InsufficientAllowance, - [MODULE_ERROR, ASSETS_MODULE, 10, _] => FungiblesError::AssetNotLive, + [MODULE_ERROR, ASSETS, 0, _] => FungiblesError::NoAccount, + [MODULE_ERROR, ASSETS, 1, _] => FungiblesError::NoPermission, + [MODULE_ERROR, ASSETS, 2, _] => FungiblesError::Unknown, + [MODULE_ERROR, ASSETS, 3, _] => FungiblesError::InUse, + [MODULE_ERROR, ASSETS, 5, _] => FungiblesError::MinBalanceZero, + [MODULE_ERROR, ASSETS, 7, _] => FungiblesError::InsufficientAllowance, + [MODULE_ERROR, ASSETS, 10, _] => FungiblesError::AssetNotLive, _ => FungiblesError::Other(value), } } @@ -348,17 +348,19 @@ impl From for FungiblesError { #[cfg(test)] mod tests { - use crate::constants::{ASSETS_MODULE, BALANCES_MODULE}; use ink::scale::{Decode, Encode}; use super::FungiblesError; - use crate::primitives::error::{ - ArithmeticError::*, - Error::{self, *}, - TokenError::*, - TransactionalError::*, + use crate::{ + constants::{ASSETS, BALANCES}, + primitives::error::{ + ArithmeticError::*, + Error::{self, *}, + TokenError::*, + TransactionalError::*, + }, + StatusCode, }; - use crate::StatusCode; fn error_into_status_code(error: Error) -> StatusCode { let mut encoded_error = error.encode(); @@ -415,35 +417,32 @@ mod tests { } assert_eq!( - into_fungibles_error(Module { index: BALANCES_MODULE, error: 2 }), + into_fungibles_error(Module { index: BALANCES, error: 2 }), FungiblesError::NoBalance ); assert_eq!( - into_fungibles_error(Module { index: ASSETS_MODULE, error: 0 }), + into_fungibles_error(Module { index: ASSETS, error: 0 }), FungiblesError::NoAccount ); assert_eq!( - into_fungibles_error(Module { index: ASSETS_MODULE, error: 1 }), + into_fungibles_error(Module { index: ASSETS, error: 1 }), FungiblesError::NoPermission ); assert_eq!( - into_fungibles_error(Module { index: ASSETS_MODULE, error: 2 }), + into_fungibles_error(Module { index: ASSETS, error: 2 }), FungiblesError::Unknown ); + assert_eq!(into_fungibles_error(Module { index: ASSETS, error: 3 }), FungiblesError::InUse); assert_eq!( - into_fungibles_error(Module { index: ASSETS_MODULE, error: 3 }), - FungiblesError::InUse - ); - assert_eq!( - into_fungibles_error(Module { index: ASSETS_MODULE, error: 5 }), + into_fungibles_error(Module { index: ASSETS, error: 5 }), FungiblesError::MinBalanceZero ); assert_eq!( - into_fungibles_error(Module { index: ASSETS_MODULE, error: 7 }), + into_fungibles_error(Module { index: ASSETS, error: 7 }), FungiblesError::InsufficientAllowance ); assert_eq!( - into_fungibles_error(Module { index: ASSETS_MODULE, error: 10 }), + into_fungibles_error(Module { index: ASSETS, error: 10 }), FungiblesError::AssetNotLive ); } diff --git a/pop-api/src/v0/assets/mod.rs b/pop-api/src/v0/assets/mod.rs index fa7d523b..00021fc0 100644 --- a/pop-api/src/v0/assets/mod.rs +++ b/pop-api/src/v0/assets/mod.rs @@ -1,9 +1,9 @@ use ink::{env::chain_extension::ChainExtensionMethod, prelude::vec::Vec, scale::Decode}; use crate::{ - constants::{ASSETS_MODULE, DECODING_FAILED, DISPATCH, READ_STATE}, + constants::{ASSETS, DECODING_FAILED, DISPATCH, READ_STATE}, primitives::{AccountId, AssetId, Balance}, - v0::VERSION, + v0::V0, Result, StatusCode, }; @@ -92,9 +92,9 @@ const TRANSFER_APPROVED: u8 = 25; #[inline] pub fn transfer_keep_alive(id: AssetId, target: AccountId, amount: Balance) -> Result<()> { ChainExtensionMethod::build(u32::from_le_bytes([ - VERSION, + V0, DISPATCH, - ASSETS_MODULE, + ASSETS, // E.D. is always respected with transferring tokens via the API. TRANSFER_KEEP_ALIVE, ])) @@ -122,31 +122,21 @@ pub fn transfer_keep_alive(id: AssetId, target: AccountId, amount: Balance) -> R /// Approve an amount of asset for transfer by a delegated third-party account. #[inline] pub fn approve_transfer(id: AssetId, delegate: AccountId, amount: Balance) -> Result<()> { - ChainExtensionMethod::build(u32::from_le_bytes([ - VERSION, - DISPATCH, - ASSETS_MODULE, - APPROVE_TRANSFER, - ])) - .input::<(AssetId, AccountId, Balance)>() - .output::, true>() - .handle_error_code::() - .call(&(id, delegate, amount)) + ChainExtensionMethod::build(u32::from_le_bytes([V0, DISPATCH, ASSETS, APPROVE_TRANSFER])) + .input::<(AssetId, AccountId, Balance)>() + .output::, true>() + .handle_error_code::() + .call(&(id, delegate, amount)) } /// Cancel all of some asset approved for delegated transfer by a third-party account. #[inline] pub fn cancel_approval(id: AssetId, delegate: AccountId) -> Result<()> { - ChainExtensionMethod::build(u32::from_le_bytes([ - VERSION, - DISPATCH, - ASSETS_MODULE, - CANCEL_APPROVAL, - ])) - .input::<(AssetId, AccountId)>() - .output::, true>() - .handle_error_code::() - .call(&(id, delegate)) + ChainExtensionMethod::build(u32::from_le_bytes([V0, DISPATCH, ASSETS, CANCEL_APPROVAL])) + .input::<(AssetId, AccountId)>() + .output::, true>() + .handle_error_code::() + .call(&(id, delegate)) } /// Transfer some asset balance from a previously delegated account to some third-party @@ -158,16 +148,11 @@ pub fn transfer_approved( to: AccountId, amount: Balance, ) -> Result<()> { - ChainExtensionMethod::build(u32::from_le_bytes([ - VERSION, - DISPATCH, - ASSETS_MODULE, - TRANSFER_APPROVED, - ])) - .input::<(AssetId, AccountId, AccountId, Balance)>() - .output::, true>() - .handle_error_code::() - .call(&(id, from, to, amount)) + ChainExtensionMethod::build(u32::from_le_bytes([V0, DISPATCH, ASSETS, TRANSFER_APPROVED])) + .input::<(AssetId, AccountId, AccountId, Balance)>() + .output::, true>() + .handle_error_code::() + .call(&(id, from, to, amount)) } /// 2. Read state functions: @@ -187,37 +172,27 @@ const TOKEN_DECIMALS: u8 = 5; #[inline] pub fn total_supply(id: AssetId) -> Result { - ChainExtensionMethod::build(u32::from_le_bytes([ - VERSION, - READ_STATE, - ASSETS_MODULE, - TOTAL_SUPPLY, - ])) - .input::() - .output::>, true>() - .handle_error_code::() - .call(&(id)) - .and_then(|v| Balance::decode(&mut &v[..]).map_err(|_e| StatusCode(DECODING_FAILED))) + ChainExtensionMethod::build(u32::from_le_bytes([V0, READ_STATE, ASSETS, TOTAL_SUPPLY])) + .input::() + .output::>, true>() + .handle_error_code::() + .call(&(id)) + .and_then(|v| Balance::decode(&mut &v[..]).map_err(|_e| StatusCode(DECODING_FAILED))) } #[inline] pub fn balance_of(id: AssetId, owner: AccountId) -> Result { - ChainExtensionMethod::build(u32::from_le_bytes([ - VERSION, - READ_STATE, - ASSETS_MODULE, - BALANCE_OF, - ])) - .input::<(AssetId, AccountId)>() - .output::>, true>() - .handle_error_code::() - .call(&(id, owner)) - .and_then(|v| Balance::decode(&mut &v[..]).map_err(|_e| StatusCode(DECODING_FAILED))) + ChainExtensionMethod::build(u32::from_le_bytes([V0, READ_STATE, ASSETS, BALANCE_OF])) + .input::<(AssetId, AccountId)>() + .output::>, true>() + .handle_error_code::() + .call(&(id, owner)) + .and_then(|v| Balance::decode(&mut &v[..]).map_err(|_e| StatusCode(DECODING_FAILED))) } #[inline] pub fn allowance(id: AssetId, owner: AccountId, spender: AccountId) -> Result { - ChainExtensionMethod::build(u32::from_le_bytes([VERSION, READ_STATE, ASSETS_MODULE, ALLOWANCE])) + ChainExtensionMethod::build(u32::from_le_bytes([V0, READ_STATE, ASSETS, ALLOWANCE])) .input::<(AssetId, AccountId, AccountId)>() .output::>, true>() .handle_error_code::() @@ -227,47 +202,32 @@ pub fn allowance(id: AssetId, owner: AccountId, spender: AccountId) -> Result Result> { - ChainExtensionMethod::build(u32::from_le_bytes([ - VERSION, - READ_STATE, - ASSETS_MODULE, - TOKEN_NAME, - ])) - .input::() - .output::>, true>() - .handle_error_code::() - .call(&(id)) - .and_then(|v| >::decode(&mut &v[..]).map_err(|_e| StatusCode(DECODING_FAILED))) + ChainExtensionMethod::build(u32::from_le_bytes([V0, READ_STATE, ASSETS, TOKEN_NAME])) + .input::() + .output::>, true>() + .handle_error_code::() + .call(&(id)) + .and_then(|v| >::decode(&mut &v[..]).map_err(|_e| StatusCode(DECODING_FAILED))) } // #[inline] pub fn token_symbol(id: AssetId) -> Result> { - ChainExtensionMethod::build(u32::from_le_bytes([ - VERSION, - READ_STATE, - ASSETS_MODULE, - TOKEN_SYMBOL, - ])) - .input::() - .output::>, true>() - .handle_error_code::() - .call(&(id)) - .and_then(|v| >::decode(&mut &v[..]).map_err(|_e| StatusCode(DECODING_FAILED))) + ChainExtensionMethod::build(u32::from_le_bytes([V0, READ_STATE, ASSETS, TOKEN_SYMBOL])) + .input::() + .output::>, true>() + .handle_error_code::() + .call(&(id)) + .and_then(|v| >::decode(&mut &v[..]).map_err(|_e| StatusCode(DECODING_FAILED))) } #[inline] pub fn token_decimals(id: AssetId) -> Result { - ChainExtensionMethod::build(u32::from_le_bytes([ - VERSION, - READ_STATE, - ASSETS_MODULE, - TOKEN_DECIMALS, - ])) - .input::() - .output::>, true>() - .handle_error_code::() - .call(&(id)) - .and_then(|v| ::decode(&mut &v[..]).map_err(|_e| StatusCode(DECODING_FAILED))) + ChainExtensionMethod::build(u32::from_le_bytes([V0, READ_STATE, ASSETS, TOKEN_DECIMALS])) + .input::() + .output::>, true>() + .handle_error_code::() + .call(&(id)) + .and_then(|v| ::decode(&mut &v[..]).map_err(|_e| StatusCode(DECODING_FAILED))) } // pub(crate) fn asset_exists(id: AssetId) -> Result { diff --git a/pop-api/src/v0/mod.rs b/pop-api/src/v0/mod.rs index 8b7a8469..f7dab6b4 100644 --- a/pop-api/src/v0/mod.rs +++ b/pop-api/src/v0/mod.rs @@ -1,5 +1,4 @@ -use crate::StatusCode; -use pop_primitives::error::Error; +use crate::{primitives::error::Error, StatusCode}; #[cfg(feature = "assets")] pub mod assets; @@ -10,7 +9,7 @@ pub mod cross_chain; #[cfg(feature = "nfts")] pub mod nfts; -pub(crate) const VERSION: u8 = 0; +pub(crate) const V0: u8 = 0; impl From for Error { fn from(value: StatusCode) -> Self { diff --git a/primitives/src/lib.rs b/primitives/src/lib.rs index b9caf111..ec6670ba 100644 --- a/primitives/src/lib.rs +++ b/primitives/src/lib.rs @@ -37,7 +37,7 @@ pub mod v0 { pub mod error { use super::*; - /// Reason why a Pop API function call failed. + /// Reason why a Pop API call failed. #[derive(Encode, Decode, Debug, Eq, PartialEq)] #[cfg_attr(feature = "std", derive(TypeInfo))] #[repr(u8)] @@ -82,8 +82,8 @@ pub mod v0 { Unavailable, /// Root origin is not allowed. RootNotAllowed, - /// Unknown function called. - UnknownFunctionCall = 254, + /// Unknown call. + UnknownCall = 254, /// Decoding failed. DecodingFailed = 255, } diff --git a/runtime/devnet/src/extensions/mod.rs b/runtime/devnet/src/extensions/mod.rs index ec2d0bc2..d2bd63e7 100644 --- a/runtime/devnet/src/extensions/mod.rs +++ b/runtime/devnet/src/extensions/mod.rs @@ -337,11 +337,11 @@ pub(crate) fn convert_to_status_code(error: DispatchError, version: u8) -> u32 { u32::from_le_bytes(encoded_error) } -/// Enum representing the different function identifiers used in the Pop API chain extension. +/// Function identifiers used in the Pop API. /// -/// The `FuncId` enum specifies the available functions that can be called through the Pop API chain -/// extension. Each variant corresponds to a specific functionality provided by the chain extension, -/// facilitating the interaction between smart contracts and the runtime. +/// The `FuncId` specifies the available functions that can be called through the Pop API. Each +/// variant corresponds to a specific functionality provided by the API, facilitating the +/// interaction between smart contracts and the runtime. /// /// - `Dispatch`: Represents a function call to dispatch a runtime call. /// - `ReadState`: Represents a function call to read the state from the runtime. diff --git a/runtime/devnet/src/extensions/v0/error.rs b/runtime/devnet/src/extensions/v0/error.rs index b8af2250..b26668f7 100644 --- a/runtime/devnet/src/extensions/v0/error.rs +++ b/runtime/devnet/src/extensions/v0/error.rs @@ -76,7 +76,7 @@ mod tests { DispatchError::Other(""), (Other { dispatch_error_index: 0, error_index: 0, error: 0 }), ), - (DispatchError::Other("UnknownFunctionId"), UnknownFunctionId), + (DispatchError::Other("UnknownFunctionId"), UnknownCall), (DispatchError::Other("DecodingFailed"), DecodingFailed), (DispatchError::CannotLookup, CannotLookup), (DispatchError::BadOrigin, BadOrigin), @@ -120,7 +120,7 @@ mod tests { DispatchError::Other("Random"), (Other { dispatch_error_index: 0, error_index: 0, error: 0 }), ), - (DispatchError::Other("UnknownFunctionId"), UnknownFunctionId), + (DispatchError::Other("UnknownFunctionId"), UnknownCall), (DispatchError::Other("DecodingFailed"), DecodingFailed), ]; for (dispatch_error, expected) in test_cases { @@ -185,7 +185,7 @@ mod tests { Corruption, Unavailable, RootNotAllowed, - UnknownFunctionId, + UnknownCall, DecodingFailed, ]; // Compare an `Error`, which is converted from an encoded value, with the expected `Error`. From e683e160f4a753ecfcd596c823947ab02917c797 Mon Sep 17 00:00:00 2001 From: Daanvdplas Date: Fri, 19 Jul 2024 10:24:21 +0200 Subject: [PATCH 027/112] refactor: add Error variants index + clippy allowance --- primitives/src/lib.rs | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/primitives/src/lib.rs b/primitives/src/lib.rs index ec6670ba..376b440d 100644 --- a/primitives/src/lib.rs +++ b/primitives/src/lib.rs @@ -41,6 +41,7 @@ pub mod v0 { #[derive(Encode, Decode, Debug, Eq, PartialEq)] #[cfg_attr(feature = "std", derive(TypeInfo))] #[repr(u8)] + #[allow(clippy::unnecessary_cast)] pub enum Error { /// An unknown error occurred. This variant captures any unexpected errors that the /// contract cannot specifically handle. It is useful for cases where there are breaking @@ -51,37 +52,37 @@ pub mod v0 { /// - `error_index`: The index within the `DispatchError` variant (e.g. a `TokenError`). /// - `error`: The specific error code or sub-index, providing additional context (e.g. /// `error` in `ModuleError`). - Other { dispatch_error_index: u8, error_index: u8, error: u8 }, + Other { dispatch_error_index: u8, error_index: u8, error: u8 } = 0, /// Failed to lookup some data. - CannotLookup, + CannotLookup = 1, /// A bad origin. - BadOrigin, + BadOrigin = 2, /// A custom error in a module. /// /// - `index`: The pallet index. /// - `error`: The error within the pallet. - Module { index: u8, error: u8 }, + Module { index: u8, error: u8 } = 3, /// At least one consumer is remaining so the account cannot be destroyed. - ConsumerRemaining, + ConsumerRemaining = 4, /// There are no providers so the account cannot be created. - NoProviders, + NoProviders = 5, /// There are too many consumers so the account cannot be created. - TooManyConsumers, + TooManyConsumers = 6, /// An error to do with tokens. - Token(TokenError), + Token(TokenError) = 7, /// An arithmetic error. - Arithmetic(ArithmeticError), + Arithmetic(ArithmeticError) = 8, /// The number of transactional layers has been reached, or we are not in a transactional /// layer. - Transactional(TransactionalError), + Transactional(TransactionalError) = 9, /// Resources exhausted, e.g. attempt to read/write data which is too large to manipulate. - Exhausted, + Exhausted = 10, /// The state is corrupt; this is generally not going to fix itself. - Corruption, + Corruption = 11, /// Some resource (e.g. a preimage) is unavailable right now. This might fix itself later. - Unavailable, + Unavailable = 12, /// Root origin is not allowed. - RootNotAllowed, + RootNotAllowed = 13, /// Unknown call. UnknownCall = 254, /// Decoding failed. From 28d971b11666aa16f3d4fd040f85473ce0d6a401 Mon Sep 17 00:00:00 2001 From: Daan van der Plas <93204684+Daanvdplas@users.noreply.github.com> Date: Fri, 26 Jul 2024 11:00:18 +0200 Subject: [PATCH 028/112] feat: api fungibles pallet (#113) Co-authored-by: Frank Bell --- Cargo.lock | 231 ++--- Cargo.toml | 2 + node/src/command.rs | 13 +- pallets/api/Cargo.toml | 55 ++ pallets/api/src/fungibles/benchmarking.rs | 106 +++ pallets/api/src/fungibles/mod.rs | 240 +++++ pallets/api/src/fungibles/tests.rs | 147 +++ pallets/api/src/fungibles/weights.rs | 94 ++ pallets/api/src/lib.rs | 5 + pallets/api/src/mock.rs | 123 +++ pop-api/Cargo.toml | 10 +- pop-api/examples/fungibles/Cargo.toml | 2 +- pop-api/integration-tests/Cargo.toml | 2 +- .../contracts/fungibles/Cargo.toml | 21 + .../contracts/fungibles/lib.rs | 185 ++++ .../integration-tests/src/local_fungibles.rs | 135 +-- pop-api/src/lib.rs | 14 +- pop-api/src/primitives.rs | 3 - pop-api/src/v0/assets/fungibles.rs | 284 +++--- pop-api/src/v0/assets/mod.rs | 235 +---- pop-api/src/v0/balances.rs | 88 -- pop-api/src/v0/cross_chain/coretime.rs | 11 - pop-api/src/v0/cross_chain/mod.rs | 107 --- pop-api/src/v0/mod.rs | 6 - pop-api/src/v0/nfts.rs | 883 ------------------ primitives/Cargo.toml | 14 +- primitives/README.md | 1 + primitives/src/cross_chain.rs | 19 - primitives/src/lib.rs | 28 +- primitives/src/storage_keys.rs | 56 -- runtime/devnet/Cargo.toml | 8 +- runtime/devnet/src/config/api.rs | 34 + runtime/devnet/src/config/assets.rs | 9 +- runtime/devnet/src/config/mod.rs | 1 + runtime/devnet/src/extensions/mod.rs | 824 ++-------------- .../src/extensions/{v0/error.rs => v0.rs} | 0 runtime/devnet/src/extensions/v0/assets.rs | 76 -- runtime/devnet/src/extensions/v0/mod.rs | 2 - runtime/devnet/src/lib.rs | 101 +- runtime/testnet/Cargo.toml | 5 +- runtime/testnet/src/extensions.rs | 558 +---------- runtime/testnet/src/lib.rs | 41 +- scripts/pallet-weights-template.hbs | 122 +++ 43 files changed, 1610 insertions(+), 3291 deletions(-) create mode 100644 pallets/api/Cargo.toml create mode 100644 pallets/api/src/fungibles/benchmarking.rs create mode 100644 pallets/api/src/fungibles/mod.rs create mode 100644 pallets/api/src/fungibles/tests.rs create mode 100644 pallets/api/src/fungibles/weights.rs create mode 100644 pallets/api/src/lib.rs create mode 100644 pallets/api/src/mock.rs create mode 100755 pop-api/integration-tests/contracts/fungibles/Cargo.toml create mode 100755 pop-api/integration-tests/contracts/fungibles/lib.rs delete mode 100644 pop-api/src/v0/balances.rs delete mode 100644 pop-api/src/v0/cross_chain/coretime.rs delete mode 100644 pop-api/src/v0/cross_chain/mod.rs delete mode 100644 pop-api/src/v0/nfts.rs create mode 100644 primitives/README.md delete mode 100644 primitives/src/cross_chain.rs delete mode 100644 primitives/src/storage_keys.rs create mode 100644 runtime/devnet/src/config/api.rs rename runtime/devnet/src/extensions/{v0/error.rs => v0.rs} (100%) delete mode 100644 runtime/devnet/src/extensions/v0/assets.rs delete mode 100644 runtime/devnet/src/extensions/v0/mod.rs create mode 100644 scripts/pallet-weights-template.hbs diff --git a/Cargo.lock b/Cargo.lock index 1983b157..d3ca53e7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -215,7 +215,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.71", + "syn 2.0.72", ] [[package]] @@ -361,9 +361,9 @@ checksum = "5d5dde061bd34119e902bbb2d9b90c5692635cf59fb91d582c2b68043f1b8293" [[package]] name = "arrayref" -version = "0.3.7" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b4930d2cb77ce62f89ee5d5289b4ac049559b1c45539271f5ed4fdc7db34545" +checksum = "9d151e35f61089500b617991b791fc8bfd237ae50cd5950803758a179b41e67a" [[package]] name = "arrayvec" @@ -740,9 +740,9 @@ dependencies = [ [[package]] name = "async-signal" -version = "0.2.8" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "794f185324c2f00e771cd9f1ae8b5ac68be2ca7abb129a87afd6e86d228bc54d" +checksum = "dfb3634b73397aa844481f814fad23bbf07fdb0eabec10f2eb95e58944b1ec32" dependencies = [ "async-io 2.3.3", "async-lock 3.4.0", @@ -770,7 +770,7 @@ checksum = "6e0c28dcc82d7c8ead5cb13beb15405b57b8546e93215673ff8ca0349a028107" dependencies = [ "proc-macro2", "quote", - "syn 2.0.71", + "syn 2.0.72", ] [[package]] @@ -907,7 +907,7 @@ dependencies = [ "regex", "rustc-hash", "shlex", - "syn 2.0.71", + "syn 2.0.72", ] [[package]] @@ -1051,18 +1051,6 @@ dependencies = [ "piper", ] -[[package]] -name = "bounded-collections" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca548b6163b872067dc5eb82fd130c56881435e30367d2073594a3d9744120dd" -dependencies = [ - "log", - "parity-scale-codec", - "scale-info", - "serde", -] - [[package]] name = "bounded-collections" version = "0.2.0" @@ -1457,9 +1445,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.1.5" +version = "1.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "324c74f2155653c90b04f25b2a47a8a631360cb908f92a772695f430c7e31052" +checksum = "2aba8f4e9906c7ce3c73463f62a7f0c65183ada1a2d47e397cc8810827f9694f" dependencies = [ "jobserver", "libc", @@ -1628,7 +1616,7 @@ dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.71", + "syn 2.0.72", ] [[package]] @@ -1676,7 +1664,7 @@ dependencies = [ "nom", "proc-macro2", "quote", - "syn 2.0.71", + "syn 2.0.72", ] [[package]] @@ -2342,7 +2330,7 @@ dependencies = [ "proc-macro-crate 3.1.0", "proc-macro2", "quote", - "syn 2.0.71", + "syn 2.0.72", ] [[package]] @@ -2383,7 +2371,7 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fa22d6e479a4d3a2790bab291269ba0917a1ac384255a54a2ebc3f7c37e505e" dependencies = [ - "bounded-collections 0.2.0", + "bounded-collections", "bp-xcm-bridge-hub-router", "cumulus-primitives-core", "frame-benchmarking", @@ -2662,7 +2650,7 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.71", + "syn 2.0.72", ] [[package]] @@ -2702,7 +2690,7 @@ dependencies = [ "proc-macro2", "quote", "scratch", - "syn 2.0.71", + "syn 2.0.72", ] [[package]] @@ -2719,7 +2707,7 @@ checksum = "4b2c1c1776b986979be68bb2285da855f8d8a35851a769fca8740df7c3d07877" dependencies = [ "proc-macro2", "quote", - "syn 2.0.71", + "syn 2.0.72", ] [[package]] @@ -2767,7 +2755,7 @@ dependencies = [ "proc-macro2", "quote", "strsim 0.11.1", - "syn 2.0.71", + "syn 2.0.72", ] [[package]] @@ -2789,7 +2777,7 @@ checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" dependencies = [ "darling_core 0.20.10", "quote", - "syn 2.0.71", + "syn 2.0.72", ] [[package]] @@ -2881,7 +2869,7 @@ checksum = "d65d7ce8132b7c0e54497a4d9a55a1c2a0912a0d786cf894472ba818fba45762" dependencies = [ "proc-macro2", "quote", - "syn 2.0.71", + "syn 2.0.72", ] [[package]] @@ -2894,7 +2882,7 @@ dependencies = [ "proc-macro2", "quote", "rustc_version", - "syn 2.0.71", + "syn 2.0.72", ] [[package]] @@ -2983,7 +2971,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.71", + "syn 2.0.72", ] [[package]] @@ -3007,9 +2995,9 @@ dependencies = [ "proc-macro2", "quote", "regex", - "syn 2.0.71", + "syn 2.0.72", "termcolor", - "toml 0.8.14", + "toml 0.8.15", "walkdir", ] @@ -3219,7 +3207,7 @@ checksum = "de0d48a183585823424a4ce1aa132d174a6a81bd540895822eb4c8373a8e49e8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.71", + "syn 2.0.72", ] [[package]] @@ -3230,7 +3218,7 @@ checksum = "6fd000fd6988e73bbe993ea3db9b1aa64906ab88766d654973924340c8cddb42" dependencies = [ "proc-macro2", "quote", - "syn 2.0.71", + "syn 2.0.72", ] [[package]] @@ -3413,7 +3401,7 @@ dependencies = [ "prettyplease 0.2.20", "proc-macro2", "quote", - "syn 2.0.71", + "syn 2.0.72", ] [[package]] @@ -3688,7 +3676,7 @@ dependencies = [ "proc-macro-crate 3.1.0", "proc-macro2", "quote", - "syn 2.0.71", + "syn 2.0.72", ] [[package]] @@ -3849,7 +3837,7 @@ dependencies = [ "proc-macro2", "quote", "sp-crypto-hashing", - "syn 2.0.71", + "syn 2.0.72", ] [[package]] @@ -3862,7 +3850,7 @@ dependencies = [ "proc-macro-crate 3.1.0", "proc-macro2", "quote", - "syn 2.0.71", + "syn 2.0.72", ] [[package]] @@ -3873,7 +3861,7 @@ checksum = "68672b9ec6fe72d259d3879dc212c5e42e977588cdac830c76f54d9f492aeb58" dependencies = [ "proc-macro2", "quote", - "syn 2.0.71", + "syn 2.0.72", ] [[package]] @@ -4066,7 +4054,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn 2.0.71", + "syn 2.0.72", ] [[package]] @@ -5197,9 +5185,9 @@ checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" [[package]] name = "libloading" -version = "0.8.4" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e310b3a6b5907f99202fcdb4960ff45b93735d7c7d96b760fcff8db2dc0e103d" +checksum = "4979f22fdb869068da03c9f7528f8297c6fd2606bc3a4affe42e6a823fdb8da4" dependencies = [ "cfg-if", "windows-targets 0.52.6", @@ -5847,7 +5835,7 @@ dependencies = [ "macro_magic_core", "macro_magic_macros", "quote", - "syn 2.0.71", + "syn 2.0.72", ] [[package]] @@ -5861,7 +5849,7 @@ dependencies = [ "macro_magic_core_macros", "proc-macro2", "quote", - "syn 2.0.71", + "syn 2.0.72", ] [[package]] @@ -5872,7 +5860,7 @@ checksum = "b02abfe41815b5bd98dbd4260173db2c116dda171dc0fe7838cb206333b83308" dependencies = [ "proc-macro2", "quote", - "syn 2.0.71", + "syn 2.0.72", ] [[package]] @@ -5883,7 +5871,7 @@ checksum = "73ea28ee64b88876bf45277ed9a5817c1817df061a74f2b988971a12570e5869" dependencies = [ "macro_magic_core", "quote", - "syn 2.0.71", + "syn 2.0.72", ] [[package]] @@ -6245,7 +6233,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.71", + "syn 2.0.72", "synstructure 0.13.1", ] @@ -6293,7 +6281,7 @@ checksum = "254a5372af8fc138e36684761d3c0cdb758a4410e938babcff1c860ce14ddbfc" dependencies = [ "proc-macro2", "quote", - "syn 2.0.71", + "syn 2.0.72", ] [[package]] @@ -6616,6 +6604,23 @@ dependencies = [ "num-traits", ] +[[package]] +name = "pallet-api" +version = "0.1.0" +dependencies = [ + "frame-benchmarking", + "frame-support", + "frame-system", + "pallet-assets", + "pallet-balances", + "parity-scale-codec", + "scale-info", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", +] + [[package]] name = "pallet-asset-conversion" version = "11.0.0" @@ -7087,7 +7092,7 @@ checksum = "3163c6bc21b55a0ccb74c546ba784d9c9e69beb9240c059d28a3052f4cbce509" dependencies = [ "proc-macro2", "quote", - "syn 2.0.71", + "syn 2.0.72", ] [[package]] @@ -7755,7 +7760,7 @@ dependencies = [ "proc-macro-crate 3.1.0", "proc-macro2", "quote", - "syn 2.0.71", + "syn 2.0.72", ] [[package]] @@ -7993,7 +7998,7 @@ version = "8.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ba9138b04168b07b1aff4a2079f5514753c31dddba40e5fb471b9cda7da27ad6" dependencies = [ - "bounded-collections 0.2.0", + "bounded-collections", "frame-benchmarking", "frame-support", "frame-system", @@ -8345,7 +8350,7 @@ dependencies = [ "pest_meta", "proc-macro2", "quote", - "syn 2.0.71", + "syn 2.0.72", ] [[package]] @@ -8386,7 +8391,7 @@ checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" dependencies = [ "proc-macro2", "quote", - "syn 2.0.71", + "syn 2.0.72", ] [[package]] @@ -9203,7 +9208,7 @@ version = "7.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "248ab090959a92e61493277e33b7e85104280a4beb4cb0815137d3c8c50a07f4" dependencies = [ - "bounded-collections 0.2.0", + "bounded-collections", "derive_more", "parity-scale-codec", "polkadot-core-primitives", @@ -9560,7 +9565,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6380dbe1fb03ecc74ad55d841cfc75480222d153ba69ddcb00977866cbdabdb8" dependencies = [ "polkavm-derive-impl", - "syn 2.0.71", + "syn 2.0.72", ] [[package]] @@ -9572,7 +9577,7 @@ dependencies = [ "polkavm-common", "proc-macro2", "quote", - "syn 2.0.71", + "syn 2.0.72", ] [[package]] @@ -9697,7 +9702,6 @@ dependencies = [ name = "pop-primitives" version = "0.0.0" dependencies = [ - "bounded-collections 0.1.9", "parity-scale-codec", "scale-info", ] @@ -9727,7 +9731,6 @@ dependencies = [ "cumulus-primitives-aura", "cumulus-primitives-core", "cumulus-primitives-utility", - "enumflags2", "env_logger 0.11.3", "frame-benchmarking", "frame-executive", @@ -9739,6 +9742,7 @@ dependencies = [ "hex", "hex-literal", "log", + "pallet-api", "pallet-assets", "pallet-aura", "pallet-authorship", @@ -9801,7 +9805,6 @@ dependencies = [ "cumulus-primitives-aura", "cumulus-primitives-core", "cumulus-primitives-utility", - "enumflags2", "env_logger 0.11.3", "frame-benchmarking", "frame-executive", @@ -9864,9 +9867,9 @@ dependencies = [ [[package]] name = "portable-atomic" -version = "1.6.0" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7170ef9988bc169ba16dd36a7fa041e5c4cbeb6a35b76d4c03daded371eae7c0" +checksum = "da544ee218f0d287a911e9c99a39a8c9bc8fcad3cb8db5959940044ecfc67265" [[package]] name = "powerfmt" @@ -9927,7 +9930,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5f12335488a2f3b0a83b14edad48dca9879ce89b2edd10e80237e4e852dd645e" dependencies = [ "proc-macro2", - "syn 2.0.71", + "syn 2.0.72", ] [[package]] @@ -10021,7 +10024,7 @@ checksum = "834da187cfe638ae8abb0203f0b33e5ccdb02a28e7199f2f47b3e2754f50edca" dependencies = [ "proc-macro2", "quote", - "syn 2.0.71", + "syn 2.0.72", ] [[package]] @@ -10067,7 +10070,7 @@ checksum = "440f724eba9f6996b75d63681b0a92b06947f1457076d503a4d2e2c8f56442b8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.71", + "syn 2.0.72", ] [[package]] @@ -10135,7 +10138,7 @@ dependencies = [ "itertools 0.12.1", "proc-macro2", "quote", - "syn 2.0.71", + "syn 2.0.72", ] [[package]] @@ -10401,7 +10404,7 @@ checksum = "bcc303e793d3734489387d205e9b186fac9c6cfacedd98cbb2e8a5943595f3e6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.71", + "syn 2.0.72", ] [[package]] @@ -11062,7 +11065,7 @@ dependencies = [ "proc-macro-crate 3.1.0", "proc-macro2", "quote", - "syn 2.0.71", + "syn 2.0.72", ] [[package]] @@ -12076,7 +12079,7 @@ dependencies = [ "proc-macro-crate 3.1.0", "proc-macro2", "quote", - "syn 2.0.71", + "syn 2.0.72", ] [[package]] @@ -12242,7 +12245,7 @@ dependencies = [ "proc-macro2", "quote", "scale-info", - "syn 2.0.71", + "syn 2.0.72", "thiserror", ] @@ -12475,7 +12478,7 @@ checksum = "e0cd7e117be63d3c3678776753929474f3b04a43a080c744d6b0ae2a8c28e222" dependencies = [ "proc-macro2", "quote", - "syn 2.0.71", + "syn 2.0.72", ] [[package]] @@ -13094,7 +13097,7 @@ dependencies = [ "proc-macro-crate 3.1.0", "proc-macro2", "quote", - "syn 2.0.71", + "syn 2.0.72", ] [[package]] @@ -13288,7 +13291,7 @@ dependencies = [ "bip39", "bitflags 1.3.2", "blake2 0.10.6", - "bounded-collections 0.2.0", + "bounded-collections", "bs58 0.5.1", "dyn-clonable", "ed25519-zebra 3.1.0", @@ -13360,7 +13363,7 @@ checksum = "b85d0f1f1e44bd8617eb2a48203ee854981229e3e79e6f468c7175d5fd37489b" dependencies = [ "quote", "sp-crypto-hashing", - "syn 2.0.71", + "syn 2.0.72", ] [[package]] @@ -13381,7 +13384,7 @@ checksum = "48d09fa0a5f7299fb81ee25ae3853d26200f7a348148aed6de76be905c007dbe" dependencies = [ "proc-macro2", "quote", - "syn 2.0.71", + "syn 2.0.72", ] [[package]] @@ -13630,7 +13633,7 @@ dependencies = [ "proc-macro-crate 3.1.0", "proc-macro2", "quote", - "syn 2.0.71", + "syn 2.0.72", ] [[package]] @@ -13837,7 +13840,7 @@ dependencies = [ "parity-scale-codec", "proc-macro2", "quote", - "syn 2.0.71", + "syn 2.0.72", ] [[package]] @@ -13860,7 +13863,7 @@ version = "28.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a3be30aec904994451dcacf841a9168cfbbaf817de6b24b6a1c1418cbf1af2fe" dependencies = [ - "bounded-collections 0.2.0", + "bounded-collections", "parity-scale-codec", "scale-info", "serde", @@ -13969,7 +13972,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "48fa328b87de3466bc38cc9a07244c42c647b7755b81115e1dfeb47cc13fc6e6" dependencies = [ "array-bytes 6.2.3", - "bounded-collections 0.2.0", + "bounded-collections", "derivative", "environmental", "impl-trait-for-tuples", @@ -14123,7 +14126,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.71", + "syn 2.0.72", ] [[package]] @@ -14224,7 +14227,7 @@ dependencies = [ "sp-maybe-compressed-blob", "strum 0.24.1", "tempfile", - "toml 0.8.14", + "toml 0.8.15", "walkdir", "wasm-opt", ] @@ -14299,7 +14302,7 @@ dependencies = [ "scale-info", "scale-typegen", "subxt-metadata", - "syn 2.0.71", + "syn 2.0.72", "thiserror", "tokio", ] @@ -14333,7 +14336,7 @@ dependencies = [ "quote", "scale-typegen", "subxt-codegen", - "syn 2.0.71", + "syn 2.0.72", ] [[package]] @@ -14384,9 +14387,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.71" +version = "2.0.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b146dcf730474b4bcd16c311627b31ede9ab149045db4d6088b3becaea046462" +checksum = "dc4b9b9bf2add8093d3f2c0204471e951b2285580335de42f9d2534f3ae7a8af" dependencies = [ "proc-macro2", "quote", @@ -14413,7 +14416,7 @@ checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" dependencies = [ "proc-macro2", "quote", - "syn 2.0.71", + "syn 2.0.72", ] [[package]] @@ -14503,9 +14506,9 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.62" +version = "1.0.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2675633b1499176c2dff06b0856a27976a8f9d436737b4cf4f312d4d91d8bbb" +checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724" dependencies = [ "thiserror-impl", ] @@ -14527,18 +14530,18 @@ checksum = "e4c60d69f36615a077cc7663b9cb8e42275722d23e58a7fa3d2c7f2915d09d04" dependencies = [ "proc-macro2", "quote", - "syn 2.0.71", + "syn 2.0.72", ] [[package]] name = "thiserror-impl" -version = "1.0.62" +version = "1.0.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d20468752b09f49e909e55a5d338caa8bedf615594e9d80bc4c565d30faf798c" +checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261" dependencies = [ "proc-macro2", "quote", - "syn 2.0.71", + "syn 2.0.72", ] [[package]] @@ -14657,9 +14660,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.38.0" +version = "1.38.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba4f4a02a7a80d6f274636f0aa95c7e383b912d41fe721a31f29e29698585a4a" +checksum = "eb2caba9f80616f438e09748d5acda951967e1ea58508ef53d9c6402485a46df" dependencies = [ "backtrace", "bytes", @@ -14682,7 +14685,7 @@ checksum = "5f5ae998a069d4b5aba8ee9dad856af7d520c3699e6159b185c2acd48155d39a" dependencies = [ "proc-macro2", "quote", - "syn 2.0.71", + "syn 2.0.72", ] [[package]] @@ -14754,14 +14757,14 @@ dependencies = [ [[package]] name = "toml" -version = "0.8.14" +version = "0.8.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f49eb2ab21d2f26bd6db7bf383edc527a7ebaee412d17af4d40fdccd442f335" +checksum = "ac2caab0bf757388c6c0ae23b3293fdb463fee59434529014f85e3263b995c28" dependencies = [ "serde", "serde_spanned", "toml_datetime", - "toml_edit 0.22.15", + "toml_edit 0.22.16", ] [[package]] @@ -14797,15 +14800,15 @@ dependencies = [ [[package]] name = "toml_edit" -version = "0.22.15" +version = "0.22.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d59a3a72298453f564e2b111fa896f8d07fabb36f51f06d7e875fc5e0b5a3ef1" +checksum = "278f3d518e152219c994ce877758516bca5e118eaed6996192a774fb9fbf0788" dependencies = [ "indexmap 2.2.6", "serde", "serde_spanned", "toml_datetime", - "winnow 0.6.13", + "winnow 0.6.14", ] [[package]] @@ -14873,7 +14876,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.71", + "syn 2.0.72", ] [[package]] @@ -14918,7 +14921,7 @@ dependencies = [ "proc-macro-crate 3.1.0", "proc-macro2", "quote", - "syn 2.0.71", + "syn 2.0.72", ] [[package]] @@ -15344,7 +15347,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.71", + "syn 2.0.72", "wasm-bindgen-shared", ] @@ -15378,7 +15381,7 @@ checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.71", + "syn 2.0.72", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -15866,9 +15869,9 @@ dependencies = [ [[package]] name = "wide" -version = "0.7.25" +version = "0.7.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2caba658a80831539b30698ae9862a72db6697dfdd7151e46920f5f2755c3ce2" +checksum = "901e8597c777fa042e9e245bd56c0dc4418c5db3f845b6ff94fbac732c6a0692" dependencies = [ "bytemuck", "safe_arch", @@ -16155,9 +16158,9 @@ dependencies = [ [[package]] name = "winnow" -version = "0.6.13" +version = "0.6.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59b5e5f6c299a3c7890b876a2a587f3115162487e704907d9b6cd29473052ba1" +checksum = "374ec40a2d767a3c1b4972d9475ecd557356637be906f2cb3f7fe17a6eb5e22f" dependencies = [ "memchr", ] @@ -16266,7 +16269,7 @@ dependencies = [ "Inflector", "proc-macro2", "quote", - "syn 2.0.71", + "syn 2.0.72", ] [[package]] @@ -16315,7 +16318,7 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.71", + "syn 2.0.72", ] [[package]] @@ -16335,7 +16338,7 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.71", + "syn 2.0.72", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 6b3cde02..8b2d0a8f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,6 +20,7 @@ members = [ "runtime/devnet", "runtime/testnet", "integration-tests", + "pallets/*", "primitives", "scripts/fund-dev-accounts", ] @@ -51,6 +52,7 @@ substrate-wasm-builder = "18.0.1" substrate-build-script-utils = "11.0.0" # Local +pallet-api = { path = "pallets/api", default-features = false } pop-runtime-devnet = { path = "runtime/devnet", default-features = true } # default-features=true required for `-p pop-node` builds pop-runtime-testnet = { path = "runtime/testnet", default-features = true } # default-features=true required for `-p pop-node` builds pop-runtime-common = { path = "runtime/common", default-features = false } diff --git a/node/src/command.rs b/node/src/command.rs index 98af5450..8ba956e1 100644 --- a/node/src/command.rs +++ b/node/src/command.rs @@ -64,18 +64,9 @@ impl RuntimeResolver for PathBuf { fn load_spec(id: &str) -> std::result::Result, String> { Ok(match id { - #[cfg(not(feature = "paseo"))] - "dev-rococo" => Box::new(chain_spec::development_config(Relay::RococoLocal)), - #[cfg(feature = "paseo")] - "dev-paseo" => Box::new(chain_spec::development_config(Relay::PaseoLocal)), - #[cfg(not(feature = "paseo"))] - "pop-rococo" => Box::new(chain_spec::testnet_config(Relay::Rococo)), - #[cfg(feature = "paseo")] - "pop-paseo" => Box::new(chain_spec::testnet_config(Relay::Paseo)), - #[cfg(feature = "paseo")] + "dev" | "dev-paseo" => Box::new(chain_spec::development_config(Relay::PaseoLocal)), + "test" | "pop-paseo" => Box::new(chain_spec::testnet_config(Relay::Paseo)), "" | "local" => Box::new(chain_spec::development_config(Relay::PaseoLocal)), - #[cfg(not(feature = "paseo"))] - "" | "local" => Box::new(chain_spec::development_config(Relay::RococoLocal)), path => { let path: PathBuf = path.into(); match path.runtime() { diff --git a/pallets/api/Cargo.toml b/pallets/api/Cargo.toml new file mode 100644 index 00000000..a813a09c --- /dev/null +++ b/pallets/api/Cargo.toml @@ -0,0 +1,55 @@ +[package] +name = "pallet-api" +authors.workspace = true +description = "Api pallet, enabling smart(er) contracts with the power of Polkadot" +edition.workspace = true +license.workspace = true +version = "0.1.0" + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + +[dependencies] +codec.workspace = true +scale-info.workspace = true + +# Substrate +frame-benchmarking.workspace = true +frame-support.workspace = true +frame-system.workspace = true +pallet-assets.workspace = true +sp-runtime.workspace = true +sp-std.workspace = true + +[dev-dependencies] +pallet-balances.workspace = true +sp-core.workspace = true +sp-io.workspace = true + +[features] +default = ["std"] +runtime-benchmarks = [ + "frame-benchmarking/runtime-benchmarks", + "frame-support/runtime-benchmarks", + "frame-system/runtime-benchmarks", + "pallet-assets/runtime-benchmarks", + "sp-runtime/runtime-benchmarks", +] +std = [ + "codec/std", + "frame-benchmarking/std", + "frame-support/std", + "frame-system/std", + "pallet-assets/std", + "pallet-balances/std", + "scale-info/std", + "sp-core/std", + "sp-io/std", + "sp-runtime/std", + "sp-std/std", +] +try-runtime = [ + "frame-support/try-runtime", + "frame-system/try-runtime", + "sp-runtime/try-runtime", +] diff --git a/pallets/api/src/fungibles/benchmarking.rs b/pallets/api/src/fungibles/benchmarking.rs new file mode 100644 index 00000000..d3d65b97 --- /dev/null +++ b/pallets/api/src/fungibles/benchmarking.rs @@ -0,0 +1,106 @@ +//! Benchmarking setup for pallet-api::fungibles + +use super::{AccountIdOf, AssetIdOf, AssetsInstanceOf, AssetsOf, BalanceOf, Call, Config, Pallet}; +use frame_benchmarking::{account, v2::*}; +use frame_support::{ + assert_ok, + traits::{ + fungibles::{ + approvals::{Inspect as ApprovalInspect, Mutate}, + Create, Inspect, + }, + Currency, + }, +}; +use frame_system::RawOrigin; +use sp_runtime::traits::Zero; + +const SEED: u32 = 1; + +// See if `generic_event` has been emitted. +fn assert_has_event( + generic_event: >>::RuntimeEvent, +) { + frame_system::Pallet::::assert_has_event(generic_event.into()); +} + +#[benchmarks( + where + > as Inspect<::AccountId>>::AssetId: Zero, +)] +mod benchmarks { + use super::*; + + // Parameter: + // - 'a': whether `approve_transfer` is required. + // - 'c': whether `cancel_approval` is required. + #[benchmark] + fn approve(a: Linear<0, 1>, c: Linear<0, 1>) -> Result<(), BenchmarkError> { + let asset_id = AssetIdOf::::zero(); + let min_balance = >::from(1u32); + let owner: AccountIdOf = account("Alice", 0, SEED); + let spender: AccountIdOf = account("Bob", 0, SEED); + let current_allowance = >::from(u32::MAX / 2); + T::Currency::make_free_balance_be(&owner, u32::MAX.into()); + // Set the `current_allowance`. + assert_ok!( as Create>>::create( + asset_id.clone(), + owner.clone(), + true, + min_balance + )); + assert_ok!( as Mutate>>::approve( + asset_id.clone(), + &owner, + &spender, + current_allowance, + )); + let approval_value = match (a, c) { + // Equal to the current allowance. + (0, 0) => current_allowance, + // Greater than the current allowance. + (1, 0) => >::from(u32::MAX), + // Zero. + (0, 1) => >::from(0u32), + // Smaller than the current allowance. + (1, 1) => >::from(u32::MAX / 4), + _ => unreachable!("values can only be 0 or 1"), + }; + + #[extrinsic_call] + _(RawOrigin::Signed(owner.clone()), asset_id.clone(), spender.clone(), approval_value); + + assert_eq!(AssetsOf::::allowance(asset_id.clone(), &owner, &spender), approval_value); + if c == 1 { + assert_has_event::( + pallet_assets::Event::ApprovalCancelled { + asset_id: asset_id.clone(), + owner: owner.clone(), + delegate: spender.clone(), + } + .into(), + ); + } + if a == 1 { + let amount = match c { + // When the allowance was cancelled and then approved with the new value. + 1 => approval_value, + // When the allowance was increased. + 0 => approval_value - current_allowance, + _ => unreachable!("`c` can only be 0 or 1"), + }; + assert_has_event::( + pallet_assets::Event::ApprovedTransfer { + asset_id, + source: owner, + delegate: spender, + amount, + } + .into(), + ); + } + Ok(()) + } + + impl_benchmark_test_suite!(Pallet, crate::mock::new_test_ext(), crate::mock::Test); +} diff --git a/pallets/api/src/fungibles/mod.rs b/pallets/api/src/fungibles/mod.rs new file mode 100644 index 00000000..cd34664a --- /dev/null +++ b/pallets/api/src/fungibles/mod.rs @@ -0,0 +1,240 @@ +/// The fungibles pallet serves as a wrapper around the pallet_assets, offering a streamlined +/// interface for interacting with fungible assets. The goal is to provide a simplified, consistent +/// API that adheres to standards in the smart contract space. + +#[cfg(feature = "runtime-benchmarks")] +mod benchmarking; +#[cfg(test)] +mod tests; +pub mod weights; + +use frame_support::traits::fungibles::{metadata::Inspect as MetadataInspect, Inspect}; +pub use pallet::*; +use pallet_assets::WeightInfo as AssetsWeightInfoTrait; +use weights::WeightInfo; + +type AccountIdOf = ::AccountId; +type AssetIdOf = > as Inspect< + ::AccountId, +>>::AssetId; +type AssetIdParameterOf = >>::AssetIdParameter; +type AssetsOf = pallet_assets::Pallet>; +type AssetsInstanceOf = ::AssetsInstance; +type AssetsWeightInfoOf = >>::WeightInfo; +type BalanceOf = > as Inspect< + ::AccountId, +>>::Balance; + +#[frame_support::pallet] +pub mod pallet { + use super::*; + use frame_support::{ + dispatch::{DispatchResult, DispatchResultWithPostInfo, WithPostDispatchInfo}, + pallet_prelude::*, + traits::fungibles::approvals::Inspect as ApprovalInspect, + }; + use frame_system::pallet_prelude::*; + use sp_runtime::{ + traits::{StaticLookup, Zero}, + Saturating, + }; + use sp_std::vec::Vec; + + /// State reads for the fungibles api with required input. + #[derive(Encode, Decode, Debug, MaxEncodedLen)] + #[repr(u8)] + #[allow(clippy::unnecessary_cast)] + pub enum Read { + /// Total token supply for a given asset ID. + #[codec(index = 0)] + TotalSupply(AssetIdOf), + /// Account balance for a given asset ID. + #[codec(index = 1)] + BalanceOf { + /// The asset ID. + id: AssetIdOf, + /// The account ID of the owner. + owner: AccountIdOf, + }, + /// Allowance for a spender approved by an owner, for a given asset ID. + #[codec(index = 2)] + Allowance { + /// The asset ID. + id: AssetIdOf, + /// The account ID of the owner. + owner: AccountIdOf, + /// The account ID of the spender. + spender: AccountIdOf, + }, + /// Token name for a given asset ID. + #[codec(index = 8)] + TokenName(AssetIdOf), + /// Token symbol for a given asset ID. + #[codec(index = 9)] + TokenSymbol(AssetIdOf), + /// Token decimals for a given asset ID. + #[codec(index = 10)] + TokenDecimals(AssetIdOf), + } + + /// Configure the pallet by specifying the parameters and types on which it depends. + #[pallet::config] + pub trait Config: frame_system::Config + pallet_assets::Config { + /// The instance of pallet assets it is tightly coupled to. + type AssetsInstance; + /// Weight information for dispatchables in this pallet. + type WeightInfo: WeightInfo; + } + + #[pallet::pallet] + pub struct Pallet(_); + + #[pallet::call] + impl Pallet { + /// Transfers `value` amount of tokens from the caller's account to account `to`, with additional + /// `data` in unspecified format. + /// + /// # Parameters + /// * `id` - The ID of the asset. + /// * `to` - The recipient account. + /// * `value` - The number of tokens to transfer. + #[pallet::call_index(3)] + #[pallet::weight(AssetsWeightInfoOf::::transfer_keep_alive())] + pub fn transfer( + origin: OriginFor, + id: AssetIdOf, + target: AccountIdOf, + amount: BalanceOf, + ) -> DispatchResult { + let target = T::Lookup::unlookup(target); + AssetsOf::::transfer_keep_alive(origin, id.into(), target, amount) + } + + /// Approves an account to spend a specified number of tokens on behalf of the caller. + /// + /// # Parameters + /// * `id` - The ID of the asset. + /// * `spender` - The account that is allowed to spend the tokens. + /// * `value` - The number of tokens to approve. + #[pallet::call_index(5)] + #[pallet::weight(::WeightInfo::approve(1, 1))] + pub fn approve( + origin: OriginFor, + id: AssetIdOf, + spender: AccountIdOf, + value: BalanceOf, + ) -> DispatchResultWithPostInfo { + let weight = |approve: u32, cancel: u32| -> Weight { + ::WeightInfo::approve(cancel, approve) + }; + let who = ensure_signed(origin.clone()).map_err(|e| e.with_weight(weight(0, 0)))?; + let current_allowance = AssetsOf::::allowance(id.clone(), &who, &spender); + let spender = T::Lookup::unlookup(spender); + let id: AssetIdParameterOf = id.into(); + + // If the new value is equal to the current allowance, do nothing. + let return_weight = if value == current_allowance { + weight(0, 0) + } + // If the new value is greater than the current allowance, approve the difference + // because `approve_transfer` works additively (see `pallet-assets`). + else if value > current_allowance { + AssetsOf::::approve_transfer( + origin, + id, + spender, + value.saturating_sub(current_allowance), + ) + .map_err(|e| e.with_weight(weight(1, 0)))?; + weight(1, 0) + } else { + // If the new value is less than the current allowance, cancel the approval and set the new value + AssetsOf::::cancel_approval(origin.clone(), id.clone(), spender.clone()) + .map_err(|e| e.with_weight(weight(0, 1)))?; + if value.is_zero() { + return Ok(Some(weight(0, 1)).into()); + } + AssetsOf::::approve_transfer(origin, id, spender, value)?; + weight(1, 1) + }; + Ok(Some(return_weight).into()) + } + + /// Increases the allowance of a spender. + /// + /// # Parameters + /// * `id` - The ID of the asset. + /// * `spender` - The account that is allowed to spend the tokens. + /// * `value` - The number of tokens to increase the allowance by. + #[pallet::call_index(6)] + #[pallet::weight(AssetsWeightInfoOf::::approve_transfer())] + pub fn increase_allowance( + origin: OriginFor, + id: AssetIdOf, + spender: AccountIdOf, + value: BalanceOf, + ) -> DispatchResult { + let spender = T::Lookup::unlookup(spender); + AssetsOf::::approve_transfer(origin, id.into(), spender, value) + } + } + + impl Pallet { + /// Returns the total token supply for a given asset ID. + /// + /// # Parameters + /// * `id` - The ID of the asset. + pub fn total_supply(id: AssetIdOf) -> BalanceOf { + AssetsOf::::total_supply(id) + } + + /// Returns the account balance for the specified `owner` for a given asset ID. Returns `0` if + /// the account is non-existent. + /// + /// # Parameters + /// * `id` - The ID of the asset. + /// * `owner` - The account whose balance is being queried. + pub fn balance_of(id: AssetIdOf, owner: &AccountIdOf) -> BalanceOf { + AssetsOf::::balance(id, owner) + } + + /// Returns the amount which `spender` is still allowed to withdraw from `owner` for a given + /// asset ID. Returns `0` if no allowance has been set. + /// + /// # Parameters + /// * `id` - The ID of the asset. + /// * `owner` - The account that owns the tokens. + /// * `spender` - The account that is allowed to spend the tokens. + pub fn allowance( + id: AssetIdOf, + owner: &AccountIdOf, + spender: &AccountIdOf, + ) -> BalanceOf { + AssetsOf::::allowance(id, owner, spender) + } + + /// Returns the token name for a given asset ID. + /// + /// # Parameters + /// * `id` - The ID of the asset. + pub fn token_name(id: AssetIdOf) -> Vec { + as MetadataInspect>>::name(id) + } + + /// Returns the token symbol for a given asset ID. + /// + /// # Parameters + /// * `id` - The ID of the asset. + pub fn token_symbol(id: AssetIdOf) -> Vec { + as MetadataInspect>>::symbol(id) + } + + /// Returns the token decimals for a given asset ID. + /// + /// # Parameters + /// * `id` - The ID of the asset. + pub fn token_decimals(id: AssetIdOf) -> u8 { + as MetadataInspect>>::decimals(id) + } + } +} diff --git a/pallets/api/src/fungibles/tests.rs b/pallets/api/src/fungibles/tests.rs new file mode 100644 index 00000000..dbfa0b34 --- /dev/null +++ b/pallets/api/src/fungibles/tests.rs @@ -0,0 +1,147 @@ +use crate::mock::*; +use frame_support::{ + assert_ok, + traits::fungibles::{approvals::Inspect, metadata::Inspect as MetadataInspect}, +}; + +const ASSET: u32 = 42; + +#[test] +fn transfer_works() { + new_test_ext().execute_with(|| { + let amount: Balance = 100 * UNIT; + create_asset_and_mint_to(ALICE, ASSET, ALICE, amount); + let balance_before_transfer = Assets::balance(ASSET, &BOB); + assert_ok!(Fungibles::transfer(signed(ALICE), ASSET, BOB, amount / 2)); + let balance_after_transfer = Assets::balance(ASSET, &BOB); + assert_eq!(balance_after_transfer, balance_before_transfer + amount / 2); + }); +} + +// Non-additive, sets new value. +#[test] +fn approve_works() { + new_test_ext().execute_with(|| { + let amount: Balance = 100 * UNIT; + create_asset_and_mint_to(ALICE, ASSET, ALICE, amount); + assert_eq!(0, Assets::allowance(ASSET, &ALICE, &BOB)); + assert_ok!(Fungibles::approve(signed(ALICE), ASSET, BOB, amount)); + assert_eq!(Assets::allowance(ASSET, &ALICE, &BOB), amount); + // Approves an amount to spend that is lower than the current allowance. + assert_ok!(Fungibles::approve(signed(ALICE), ASSET, BOB, amount / 2)); + assert_eq!(Assets::allowance(ASSET, &ALICE, &BOB), amount / 2); + // Approves an amount to spend that is higher than the current allowance. + assert_ok!(Fungibles::approve(signed(ALICE), ASSET, BOB, amount * 2)); + assert_eq!(Assets::allowance(ASSET, &ALICE, &BOB), amount * 2); + // Approves an amount to spend that is equal to the current allowance. + assert_ok!(Fungibles::approve(signed(ALICE), ASSET, BOB, amount * 2)); + assert_eq!(Assets::allowance(ASSET, &ALICE, &BOB), amount * 2); + // Sets allowance to zero. + assert_ok!(Fungibles::approve(signed(ALICE), ASSET, BOB, 0)); + assert_eq!(Assets::allowance(ASSET, &ALICE, &BOB), 0); + }); +} + +#[test] +fn increase_allowance_works() { + new_test_ext().execute_with(|| { + let amount: Balance = 100 * UNIT; + create_asset_and_mint_to(ALICE, ASSET, ALICE, amount); + assert_eq!(0, Assets::allowance(ASSET, &ALICE, &BOB)); + assert_ok!(Fungibles::increase_allowance(signed(ALICE), ASSET, BOB, amount)); + assert_eq!(Assets::allowance(ASSET, &ALICE, &BOB), amount); + // Additive. + assert_ok!(Fungibles::increase_allowance(signed(ALICE), ASSET, BOB, amount)); + assert_eq!(Assets::allowance(ASSET, &ALICE, &BOB), amount * 2); + }); +} + +#[test] +fn total_supply_works() { + new_test_ext().execute_with(|| { + create_asset_and_mint_to(ALICE, ASSET, ALICE, 100); + assert_eq!(Assets::total_supply(ASSET), Fungibles::total_supply(ASSET)); + }); +} + +#[test] +fn balance_of_works() { + new_test_ext().execute_with(|| { + create_asset_and_mint_to(ALICE, ASSET, ALICE, 100); + assert_eq!(Assets::balance(ASSET, ALICE), Fungibles::balance_of(ASSET, &ALICE)); + }); +} + +#[test] +fn allowance_works() { + new_test_ext().execute_with(|| { + create_asset_mint_and_approve(ALICE, ASSET, BOB, 100, ALICE, 50); + assert_eq!( + Assets::allowance(ASSET, &ALICE, &BOB), + Fungibles::allowance(ASSET, &ALICE, &BOB) + ); + }); +} + +#[test] +fn token_metadata_works() { + new_test_ext().execute_with(|| { + let name: Vec = vec![11, 12, 13]; + let symbol: Vec = vec![21, 22, 23]; + let decimals: u8 = 69; + create_asset_and_set_metadata(ALICE, ASSET, name.clone(), symbol.clone(), decimals); + assert_eq!(Assets::name(ASSET), Fungibles::token_name(ASSET)); + assert_eq!(Assets::symbol(ASSET), Fungibles::token_symbol(ASSET)); + assert_eq!(Assets::decimals(ASSET), Fungibles::token_decimals(ASSET)); + }); +} + +fn signed(account: AccountId) -> RuntimeOrigin { + RuntimeOrigin::signed(account) +} + +fn create_asset(owner: AccountId, asset_id: AssetId, min_balance: Balance) { + assert_ok!(Assets::create(signed(owner), asset_id, owner, min_balance)); +} + +fn mint_asset(owner: AccountId, asset_id: AssetId, to: AccountId, value: Balance) { + assert_ok!(Assets::mint(signed(owner), asset_id, to, value)); +} + +fn create_asset_and_mint_to(owner: AccountId, asset_id: AssetId, to: AccountId, value: Balance) { + create_asset(owner, asset_id, 1); + mint_asset(owner, asset_id, to, value) +} + +fn create_asset_mint_and_approve( + owner: AccountId, + asset_id: AssetId, + to: AccountId, + mint: Balance, + spender: AccountId, + approve: Balance, +) { + create_asset_and_mint_to(owner, asset_id, to, mint); + assert_ok!(Assets::approve_transfer(signed(to), asset_id, spender, approve,)); +} + +fn create_asset_and_set_metadata( + owner: AccountId, + asset_id: AssetId, + name: Vec, + symbol: Vec, + decimals: u8, +) { + assert_ok!(Assets::create(signed(owner), asset_id, owner, 100)); + set_metadata_asset(owner, asset_id, name, symbol, decimals); +} + +fn set_metadata_asset( + owner: AccountId, + asset_id: AssetId, + name: Vec, + symbol: Vec, + decimals: u8, +) { + assert_ok!(Assets::set_metadata(signed(owner), asset_id, name, symbol, decimals)); +} diff --git a/pallets/api/src/fungibles/weights.rs b/pallets/api/src/fungibles/weights.rs new file mode 100644 index 00000000..a6c31654 --- /dev/null +++ b/pallets/api/src/fungibles/weights.rs @@ -0,0 +1,94 @@ + +//! Autogenerated weights for `pallet_api::fungibles` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 33.0.0 +//! DATE: 2024-07-25, STEPS: `20`, REPEAT: `5`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `R0GUE`, CPU: `` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` + +// Executed Command: +// ./target/release/pop-node +// benchmark +// pallet +// --chain=dev +// --wasm-execution=compiled +// --pallet=pallet_api::fungibles +// --steps=20 +// --repeat=5 +// --json +// --template +// ./scripts/pallet-weights-template.hbs +// --output=./pallets/api/src/fungibles/weights.rs +// --extrinsic= + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; +use core::marker::PhantomData; + +/// Weight functions needed for `pallet_api::fungibles`. +pub trait WeightInfo { + fn approve(a: u32, c: u32, ) -> Weight; +} + +/// Weights for `pallet_api::fungibles` using the Substrate node and recommended hardware. +pub struct SubstrateWeight(PhantomData); +impl WeightInfo for SubstrateWeight { + /// Storage: `Assets::Approvals` (r:1 w:1) + /// Proof: `Assets::Approvals` (`max_values`: None, `max_size`: Some(148), added: 2623, mode: `MaxEncodedLen`) + /// Storage: `Assets::Asset` (r:1 w:1) + /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// The range of component `a` is `[0, 1]`. + /// The range of component `c` is `[0, 1]`. + fn approve(a: u32, c: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `413 + c * (102 ±0)` + // Estimated: `3675 + c * (1797 ±0)` + // Minimum execution time: 35_000_000 picoseconds. + Weight::from_parts(1_207_482, 3675) + // Standard Error: 948_955 + .saturating_add(Weight::from_parts(34_649_659, 0).saturating_mul(a.into())) + // Standard Error: 948_955 + .saturating_add(Weight::from_parts(56_976_190, 0).saturating_mul(c.into())) + .saturating_add(T::DbWeight::get().reads(2_u64)) + .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(c.into()))) + .saturating_add(T::DbWeight::get().writes(2_u64)) + .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(c.into()))) + .saturating_add(Weight::from_parts(0, 1797).saturating_mul(c.into())) + } +} + +// For backwards compatibility and tests. +impl WeightInfo for () { + /// Storage: `Assets::Approvals` (r:1 w:1) + /// Proof: `Assets::Approvals` (`max_values`: None, `max_size`: Some(148), added: 2623, mode: `MaxEncodedLen`) + /// Storage: `Assets::Asset` (r:1 w:1) + /// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// The range of component `a` is `[0, 1]`. + /// The range of component `c` is `[0, 1]`. + fn approve(a: u32, c: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `413 + c * (102 ±0)` + // Estimated: `3675 + c * (1797 ±0)` + // Minimum execution time: 35_000_000 picoseconds. + Weight::from_parts(1_207_482, 3675) + // Standard Error: 948_955 + .saturating_add(Weight::from_parts(34_649_659, 0).saturating_mul(a.into())) + // Standard Error: 948_955 + .saturating_add(Weight::from_parts(56_976_190, 0).saturating_mul(c.into())) + .saturating_add(RocksDbWeight::get().reads(2_u64)) + .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(c.into()))) + .saturating_add(RocksDbWeight::get().writes(2_u64)) + .saturating_add(RocksDbWeight::get().writes((1_u64).saturating_mul(c.into()))) + .saturating_add(Weight::from_parts(0, 1797).saturating_mul(c.into())) + } +} + diff --git a/pallets/api/src/lib.rs b/pallets/api/src/lib.rs new file mode 100644 index 00000000..5cba0551 --- /dev/null +++ b/pallets/api/src/lib.rs @@ -0,0 +1,5 @@ +#![cfg_attr(not(feature = "std"), no_std)] + +pub mod fungibles; +#[cfg(test)] +mod mock; diff --git a/pallets/api/src/mock.rs b/pallets/api/src/mock.rs new file mode 100644 index 00000000..f5d155ef --- /dev/null +++ b/pallets/api/src/mock.rs @@ -0,0 +1,123 @@ +use frame_support::{ + derive_impl, parameter_types, + traits::{AsEnsureOriginWithArg, ConstU128, ConstU32, Everything}, +}; +use frame_system::{EnsureRoot, EnsureSigned}; +use sp_core::H256; +use sp_runtime::{ + traits::{BlakeTwo256, IdentityLookup}, + BuildStorage, +}; + +type Block = frame_system::mocking::MockBlock; +pub(crate) type AccountId = u64; +pub(crate) type AssetId = u32; +pub(crate) type Balance = u128; + +// Configure a mock runtime to test the pallet. +frame_support::construct_runtime!( + pub enum Test + { + System: frame_system, + Assets: pallet_assets::, + Balances: pallet_balances, + Fungibles: crate::fungibles, + } +); + +parameter_types! { + pub const BlockHashCount: u64 = 250; + pub const SS58Prefix: u8 = 42; +} + +#[derive_impl(frame_system::config_preludes::TestDefaultConfig as frame_system::DefaultConfig)] +impl frame_system::Config for Test { + type BaseCallFilter = Everything; + type BlockWeights = (); + type BlockLength = (); + type RuntimeOrigin = RuntimeOrigin; + type RuntimeCall = RuntimeCall; + type Nonce = u64; + type Hash = H256; + type Hashing = BlakeTwo256; + type AccountId = AccountId; + type Lookup = IdentityLookup; + type Block = Block; + type RuntimeEvent = RuntimeEvent; + type BlockHashCount = BlockHashCount; + type DbWeight = (); + type Version = (); + type PalletInfo = PalletInfo; + type AccountData = pallet_balances::AccountData; + type OnNewAccount = (); + type OnKilledAccount = (); + type SystemWeightInfo = (); + type SS58Prefix = SS58Prefix; + type OnSetCode = (); + type MaxConsumers = ConstU32<16>; +} + +impl pallet_balances::Config for Test { + type Balance = Balance; + type DustRemoval = (); + type RuntimeEvent = RuntimeEvent; + type ExistentialDeposit = ConstU128<1>; + type AccountStore = System; + type FreezeIdentifier = (); + type MaxFreezes = ConstU32<0>; + type WeightInfo = (); + type MaxLocks = (); + type MaxReserves = (); + type ReserveIdentifier = [u8; 8]; + type RuntimeHoldReason = RuntimeHoldReason; + type RuntimeFreezeReason = RuntimeFreezeReason; +} + +type AssetsInstance = pallet_assets::Instance1; +impl pallet_assets::Config for Test { + type RuntimeEvent = RuntimeEvent; + type Balance = Balance; + type RemoveItemsLimit = ConstU32<5>; + type AssetId = AssetId; + type AssetIdParameter = u32; + type Currency = Balances; + type CreateOrigin = AsEnsureOriginWithArg>; + type ForceOrigin = EnsureRoot; + type AssetDeposit = ConstU128<1>; + type AssetAccountDeposit = ConstU128<10>; + type MetadataDepositBase = ConstU128<1>; + type MetadataDepositPerByte = ConstU128<1>; + type ApprovalDeposit = ConstU128<1>; + type StringLimit = ConstU32<50>; + type Freezer = (); + type Extra = (); + type CallbackHandle = (); + type WeightInfo = (); + #[cfg(feature = "runtime-benchmarks")] + type BenchmarkHelper = (); +} +impl crate::fungibles::Config for Test { + type AssetsInstance = AssetsInstance; + type WeightInfo = (); +} + +pub(crate) const ALICE: AccountId = 1; +pub(crate) const BOB: AccountId = 2; +pub(crate) const INIT_AMOUNT: Balance = 100_000_000 * UNIT; +pub(crate) const UNIT: Balance = 10_000_000_000; + +pub(crate) fn new_test_ext() -> sp_io::TestExternalities { + let mut t = frame_system::GenesisConfig::::default() + .build_storage() + .expect("Frame system builds valid default genesis config"); + + pallet_balances::GenesisConfig:: { + balances: vec![(ALICE, INIT_AMOUNT), (BOB, INIT_AMOUNT)], + } + .assimilate_storage(&mut t) + .expect("Pallet balances storage can be assimilated"); + + let mut ext = sp_io::TestExternalities::new(t); + ext.execute_with(|| System::set_block_number(1)); + ext +} diff --git a/pop-api/Cargo.toml b/pop-api/Cargo.toml index dc48ea8a..9946abf7 100644 --- a/pop-api/Cargo.toml +++ b/pop-api/Cargo.toml @@ -1,12 +1,11 @@ [package] name = "pop-api" -description = "Easily access the power of Polkadot via the Pop Network" +description = "Enabling smart(er) contracts with the power of Polkadot" license = "GPL-3.0-only" version = "0.0.0" edition = "2021" [dependencies] -enumflags2 = { version = "0.7.7" } ink = { version = "5.0.0", default-features = false } sp-io = { version = "31.0.0", default-features = false, features = ["disable_panic_handler", "disable_oom", "disable_allocator"] } @@ -20,12 +19,9 @@ crate-type = ["rlib"] [features] default = ["std"] std = [ - "enumflags2/std", "ink/std", "pop-primitives/std", "sp-io/std", ] -assets = ["pop-primitives/assets"] -balances = [] -nfts = ["pop-primitives/nfts"] -cross-chain = ["pop-primitives/cross-chain"] +assets = [] +fungibles = ["assets"] diff --git a/pop-api/examples/fungibles/Cargo.toml b/pop-api/examples/fungibles/Cargo.toml index 565b0554..19d9ce12 100755 --- a/pop-api/examples/fungibles/Cargo.toml +++ b/pop-api/examples/fungibles/Cargo.toml @@ -6,7 +6,7 @@ edition = "2021" [dependencies] ink = { version = "5.0.0", default-features = false } -pop-api = { path = "../../../pop-api", default-features = false, features = ["assets"] } +pop-api = { path = "../../../pop-api", default-features = false, features = ["fungibles"] } [lib] path = "lib.rs" diff --git a/pop-api/integration-tests/Cargo.toml b/pop-api/integration-tests/Cargo.toml index 94c0ba83..cc56630a 100644 --- a/pop-api/integration-tests/Cargo.toml +++ b/pop-api/integration-tests/Cargo.toml @@ -11,7 +11,7 @@ frame-system = { version = "29.0.0", default-features = false } pallet-balances = { version = "29.0.2", default-features = false } pallet-assets = { version = "30.0.0", default-features = false } pallet-contracts = { version = "28.0.0", default-features = false } -pop-primitives = { path = "../../primitives", default-features = false, features = ["assets"] } +pop-primitives = { path = "../../primitives", default-features = false } pop-runtime-devnet = { path = "../../runtime/devnet", default-features = false } sp-io = { version = "31.0.0", default-features = false } sp-runtime = { version = "32.0.0", default-features = false } diff --git a/pop-api/integration-tests/contracts/fungibles/Cargo.toml b/pop-api/integration-tests/contracts/fungibles/Cargo.toml new file mode 100755 index 00000000..7c322004 --- /dev/null +++ b/pop-api/integration-tests/contracts/fungibles/Cargo.toml @@ -0,0 +1,21 @@ +[package] +name = "fungibles" +version = "0.1.0" +authors = ["[your_name] <[your_email]>"] +edition = "2021" + +[dependencies] +ink = { version = "5.0.0", default-features = false } +pop-api = { path = "../../../../pop-api", default-features = false, features = ["fungibles"] } + +[lib] +path = "lib.rs" + +[features] +default = ["std"] +std = [ + "ink/std", + "pop-api/std", +] +ink-as-dependency = [] +e2e-tests = [] diff --git a/pop-api/integration-tests/contracts/fungibles/lib.rs b/pop-api/integration-tests/contracts/fungibles/lib.rs new file mode 100755 index 00000000..1b42fec4 --- /dev/null +++ b/pop-api/integration-tests/contracts/fungibles/lib.rs @@ -0,0 +1,185 @@ +#![cfg_attr(not(feature = "std"), no_std, no_main)] + +/// Local Fungibles: +/// 1. PSP-22 Interface +/// 2. PSP-22 Metadata Interface +/// 3. Asset Management +/// +use ink::prelude::vec::Vec; +use pop_api::{ + assets::fungibles::{self as api}, + primitives::AssetId, + StatusCode, +}; + +pub type Result = core::result::Result; + +#[ink::contract] +mod fungibles { + use super::*; + + #[ink(storage)] + #[derive(Default)] + pub struct Fungibles; + + impl Fungibles { + #[ink(constructor, payable)] + pub fn new() -> Self { + ink::env::debug_println!("PopApiFungiblesExample::new"); + Default::default() + } + + /// 1. PSP-22 Interface: + /// - total_supply + /// - balance_of + /// - allowance + /// - transfer + /// - transfer_from + /// - approve + /// - increase_allowance + /// - decrease_allowance + + #[ink(message)] + pub fn total_supply(&self, id: AssetId) -> Result { + api::total_supply(id) + } + + #[ink(message)] + pub fn balance_of(&self, id: AssetId, owner: AccountId) -> Result { + api::balance_of(id, owner) + } + + #[ink(message)] + pub fn allowance( + &self, + id: AssetId, + owner: AccountId, + spender: AccountId, + ) -> Result { + api::allowance(id, owner, spender) + } + + #[ink(message)] + pub fn transfer(&self, id: AssetId, to: AccountId, value: Balance) -> Result<()> { + api::transfer(id, to, value) + } + + #[ink(message)] + pub fn transfer_from( + &self, + id: AssetId, + from: AccountId, + to: AccountId, + value: Balance, + // In the PSP-22 standard a `[u8]`, but the size needs to be known at compile time. + _data: Vec, + ) -> Result<()> { + api::transfer_from(id, from, to, value) + } + + #[ink(message)] + pub fn approve(&self, id: AssetId, spender: AccountId, value: Balance) -> Result<()> { + api::approve(id, spender, value) + } + + #[ink(message)] + pub fn increase_allowance( + &self, + id: AssetId, + spender: AccountId, + value: Balance, + ) -> Result<()> { + api::increase_allowance(id, spender, value) + } + + #[ink(message)] + pub fn decrease_allowance( + &self, + id: AssetId, + spender: AccountId, + value: Balance, + ) -> Result<()> { + api::decrease_allowance(id, spender, value) + } + + /// 2. PSP-22 Metadata Interface: + /// - token_name + /// - token_symbol + /// - token_decimals + + #[ink(message)] + pub fn token_name(&self, id: AssetId) -> Result> { + api::token_name(id) + } + + #[ink(message)] + pub fn token_symbol(&self, id: AssetId) -> Result> { + api::token_symbol(id) + } + + #[ink(message)] + pub fn token_decimals(&self, id: AssetId) -> Result { + api::token_decimals(id) + } + + // 3. Asset Management: + // - create + // - start_destroy + // - destroy_accounts + // - destroy_approvals + // - finish_destroy + // - set_metadata + // - clear_metadata + + // #[ink(message)] + // pub fn create(&self, id: AssetId, admin: AccountId, min_balance: Balance) -> Result<()> { + // ink::env::debug_println!( + // "PopApiFungiblesExample::create: id: {:?} admin: {:?} min_balance: {:?}", + // id, + // admin, + // min_balance, + // ); + // let result = api::create(id, admin, min_balance); + // ink::env::debug_println!("Result: {:?}", result); + // result.map_err(|e| e.into()) + // result + // } + + // #[ink(message)] + // pub fn set_metadata( + // &self, + // id: AssetId, + // name: Vec, + // symbol: Vec, + // decimals: u8, + // ) -> Result<()> { + // ink::env::debug_println!( + // "PopApiFungiblesExample::set_metadata: id: {:?} name: {:?} symbol: {:?}, decimals: {:?}", + // id, + // name, + // symbol, + // decimals, + // ); + // let result = api::set_metadata(id, name, symbol, decimals); + // ink::env::debug_println!("Result: {:?}", result); + // // result.map_err(|e| e.into()) + // result + // } + // + // #[ink(message)] + // pub fn asset_exists(&self, id: AssetId) -> Result { + // // api::asset_exists(id).map_err(|e| e.into()) + // api::asset_exists(id) + // } + } + + #[cfg(test)] + mod tests { + use super::*; + + #[ink::test] + fn default_works() { + PopApiFungiblesExample::new(); + } + } +} diff --git a/pop-api/integration-tests/src/local_fungibles.rs b/pop-api/integration-tests/src/local_fungibles.rs index 8f0384c0..c62f0713 100644 --- a/pop-api/integration-tests/src/local_fungibles.rs +++ b/pop-api/integration-tests/src/local_fungibles.rs @@ -6,6 +6,7 @@ use pop_primitives::error::{ }; const ASSET_ID: AssetId = 1; +const CONTRACT: &str = "contracts/fungibles/target/ink/fungibles.wasm"; fn decoded(result: ExecReturnValue) -> T { match ::decode(&mut &result.data[2..]) { @@ -79,19 +80,16 @@ fn transfer( result } -fn transfer_from( +fn approve( addr: AccountId32, asset_id: AssetId, - from: Option, - to: Option, + spender: AccountId32, value: Balance, - data: &[u8], ) -> ExecReturnValue { - let function = function_selector("transfer_from"); - let params = - [function, asset_id.encode(), from.encode(), to.encode(), value.encode(), data.encode()] - .concat(); - bare_call(addr, params, 0).expect("should work") + let function = function_selector("approve"); + let params = [function, asset_id.encode(), spender.encode(), value.encode()].concat(); + let result = bare_call(addr, params, 0).expect("should work"); + result } fn increase_allowance( @@ -263,15 +261,10 @@ fn token_decimals_asset(asset_id: AssetId) -> u8 { /// - decrease_allowance #[test] -#[ignore] fn total_supply_works() { new_test_ext().execute_with(|| { let _ = env_logger::try_init(); - let addr = instantiate( - "../../pop-api/examples/fungibles/target/ink/fungibles.wasm", - INIT_VALUE, - vec![], - ); + let addr = instantiate(CONTRACT, INIT_VALUE, vec![]); // No tokens in circulation. assert_eq!(Assets::total_supply(ASSET_ID), total_supply(addr.clone(), ASSET_ID)); @@ -285,12 +278,10 @@ fn total_supply_works() { } #[test] -#[ignore] fn balance_of_works() { new_test_ext().execute_with(|| { let _ = env_logger::try_init(); - let addr = - instantiate("../examples/fungibles/target/ink/fungibles.wasm", INIT_VALUE, vec![]); + let addr = instantiate(CONTRACT, INIT_VALUE, vec![]); // No tokens in circulation. assert_eq!(Assets::balance(ASSET_ID, BOB), balance_of(addr.clone(), ASSET_ID, BOB)); @@ -304,12 +295,10 @@ fn balance_of_works() { } #[test] -#[ignore] fn allowance_works() { new_test_ext().execute_with(|| { let _ = env_logger::try_init(); - let addr = - instantiate("../examples/fungibles/target/ink/fungibles.wasm", INIT_VALUE, vec![]); + let addr = instantiate(CONTRACT, INIT_VALUE, vec![]); // No tokens in circulation. assert_eq!( @@ -329,12 +318,10 @@ fn allowance_works() { } #[test] -#[ignore] fn transfer_works() { new_test_ext().execute_with(|| { let _ = env_logger::try_init(); - let addr = - instantiate("../examples/fungibles/target/ink/fungibles.wasm", INIT_VALUE, vec![]); + let addr = instantiate(CONTRACT, INIT_VALUE, vec![]); let amount: Balance = 100 * UNIT; // Asset does not exist. @@ -362,11 +349,11 @@ fn transfer_works() { Module { index: 52, error: 0 }, ); // Successful transfer. - let bob_balance_before_mint = Assets::balance(asset, &BOB); + let balance_before_transfer = Assets::balance(asset, &BOB); let result = transfer(addr.clone(), asset, BOB, amount / 2); assert!(!result.did_revert(), "Contract reverted!"); - let bob_balance_after_mint = Assets::balance(asset, &BOB); - assert_eq!(bob_balance_after_mint, bob_balance_before_mint + amount / 2); + let balance_after_transfer = Assets::balance(asset, &BOB); + assert_eq!(balance_after_transfer, balance_before_transfer + amount / 2); // Transfer asset to account that does not exist. assert_eq!( decoded::(transfer(addr.clone(), asset, FERDIE, amount / 4)), @@ -382,82 +369,65 @@ fn transfer_works() { } #[test] -#[ignore] -fn transfer_from_works() { +fn approve_works() { new_test_ext().execute_with(|| { let _ = env_logger::try_init(); - let addr = - instantiate("../examples/fungibles/target/ink/fungibles.wasm", INIT_VALUE, vec![]); + let addr = instantiate(CONTRACT, 0, vec![]); let amount: Balance = 100 * UNIT; - // Asset does not exist. assert_eq!( - decoded::(transfer(addr.clone(), 1, BOB, amount,)), + decoded::(approve(addr.clone(), 0, BOB, amount)), Module { index: 52, error: 3 }, ); + let asset = create_asset_and_mint_to(ALICE, 0, addr.clone(), amount); + assert_eq!(decoded::(approve(addr.clone(), asset, BOB, amount)), ConsumerRemaining); + + let addr = instantiate(CONTRACT, INIT_VALUE, vec![1]); // Create asset with Alice as owner and mint `amount` to contract address. let asset = create_asset_and_mint_to(ALICE, 1, addr.clone(), amount); // Asset is not live, i.e. frozen or being destroyed. freeze_asset(ALICE, asset); assert_eq!( - decoded::(transfer(addr.clone(), asset, BOB, amount,)), + decoded::(approve(addr.clone(), asset, BOB, amount)), Module { index: 52, error: 16 }, ); thaw_asset(ALICE, asset); - // Not enough balance. - assert_eq!( - decoded::(transfer(addr.clone(), asset, BOB, amount + 1 * UNIT)), - Module { index: 52, error: 0 }, - ); - // Not enough balance due to ED. - assert_eq!( - decoded::(transfer(addr.clone(), asset, BOB, amount)), - Module { index: 52, error: 0 }, - ); - // Successful transfer. - let bob_balance_before_mint = Assets::balance(asset, &BOB); - let result = transfer(addr.clone(), asset, BOB, amount / 2); - assert!(!result.did_revert(), "Contract reverted!"); - let bob_balance_after_mint = Assets::balance(asset, &BOB); - assert_eq!(bob_balance_after_mint, bob_balance_before_mint + amount / 2); - // Transfer asset to account that does not exist. - assert_eq!( - decoded::(transfer(addr.clone(), asset, FERDIE, amount / 4)), - Token(CannotCreate) - ); + // Successful approvals: + assert_eq!(0, Assets::allowance(asset, &addr, &BOB)); + assert!(!approve(addr.clone(), asset, BOB, amount).did_revert(), "Contract reverted!"); + assert_eq!(Assets::allowance(asset, &addr, &BOB), amount); + // Non-additive, sets new value. + assert!(!approve(addr.clone(), asset, BOB, amount / 2).did_revert(), "Contract reverted!"); + assert_eq!(Assets::allowance(asset, &addr, &BOB), amount / 2); // Asset is not live, i.e. frozen or being destroyed. start_destroy_asset(ALICE, asset); assert_eq!( - decoded::(transfer(addr.clone(), asset, BOB, amount / 4)), + decoded::(approve(addr.clone(), asset, BOB, amount)), Module { index: 52, error: 16 }, ); }); } #[test] -#[ignore] fn increase_allowance_works() { new_test_ext().execute_with(|| { let _ = env_logger::try_init(); - let addr = instantiate("../examples/fungibles/target/ink/fungibles.wasm", 0, vec![]); + let addr = instantiate(CONTRACT, 0, vec![]); let amount: Balance = 100 * UNIT; - let asset = 0; - create_asset_and_mint_to(ALICE, asset, addr.clone(), amount); + // Asset does not exist. assert_eq!( - decoded::(increase_allowance(addr.clone(), asset, BOB, amount)), - ConsumerRemaining + decoded::(increase_allowance(addr.clone(), 0, BOB, amount)), + Module { index: 52, error: 3 }, ); - - let addr = - instantiate("../examples/fungibles/target/ink/fungibles.wasm", INIT_VALUE, vec![1]); - // Asset does not exist. - let asset = 1; + let asset = create_asset_and_mint_to(ALICE, 0, addr.clone(), amount); assert_eq!( decoded::(increase_allowance(addr.clone(), asset, BOB, amount)), - Module { index: 52, error: 3 }, + ConsumerRemaining ); + + let addr = instantiate(CONTRACT, INIT_VALUE, vec![1]); // Create asset with Alice as owner and mint `amount` to contract address. - create_asset_and_mint_to(ALICE, asset, addr.clone(), amount); + let asset = create_asset_and_mint_to(ALICE, 1, addr.clone(), amount); // Asset is not live, i.e. frozen or being destroyed. freeze_asset(ALICE, asset); assert_eq!( @@ -465,7 +435,7 @@ fn increase_allowance_works() { Module { index: 52, error: 16 }, ); thaw_asset(ALICE, asset); - // Successful approval. + // Successful approvals: assert_eq!(0, Assets::allowance(asset, &addr, &BOB)); assert!( !increase_allowance(addr.clone(), asset, BOB, amount).did_revert(), @@ -493,15 +463,10 @@ fn increase_allowance_works() { /// - token_decimals #[test] -#[ignore] fn token_metadata_works() { new_test_ext().execute_with(|| { let _ = env_logger::try_init(); - let addr = instantiate( - "../../pop-api/examples/fungibles/target/ink/fungibles.wasm", - INIT_VALUE, - vec![], - ); + let addr = instantiate(CONTRACT, INIT_VALUE, vec![]); let name: Vec = vec![11, 12, 13]; let symbol: Vec = vec![21, 22, 23]; @@ -536,7 +501,7 @@ fn token_metadata_works() { // new_test_ext().execute_with(|| { // let _ = env_logger::try_init(); // let addr = -// instantiate("../examples/fungibles/target/ink/fungibles.wasm", INIT_VALUE, vec![]); +// instantiate(CONTRACT, INIT_VALUE, vec![]); // // // No tokens in circulation. // assert_eq!(Assets::asset_exists(ASSET_ID), asset_exists(addr.clone(), ASSET_ID)); @@ -553,7 +518,7 @@ fn token_metadata_works() { // new_test_ext().execute_with(|| { // let _ = env_logger::try_init(); // let addr = -// instantiate("../examples/fungibles/target/ink/fungibles.wasm", INIT_VALUE, vec![]); +// instantiate(CONTRACT, INIT_VALUE, vec![]); // let amount: Balance = 100 * UNIT; // // // Asset does not exist. @@ -581,11 +546,11 @@ fn token_metadata_works() { // ); // thaw_asset(addr.clone(), asset); // // Successful mint. -// let bob_balance_before_mint = Assets::balance(asset, &BOB); +// let balance_before_mint = Assets::balance(asset, &BOB); // let result = transfer_from(addr.clone(), asset, None, Some(BOB), amount, &[0u8]); // assert!(!result.did_revert(), "Contract reverted!"); -// let bob_balance_after_mint = Assets::balance(asset, &BOB); -// assert_eq!(bob_balance_after_mint, bob_balance_before_mint + amount); +// let balance_after_mint = Assets::balance(asset, &BOB); +// assert_eq!(balance_after_mint, balance_before_mint + amount); // // Can not mint more tokens than Balance::MAX. // assert_eq!( // decoded::(transfer_from( @@ -613,14 +578,14 @@ fn token_metadata_works() { // new_test_ext().execute_with(|| { // let _ = env_logger::try_init(); // // Instantiate a contract without balance (relay token). -// let addr = instantiate("../examples/fungibles/target/ink/fungibles.wasm", 0, vec![0]); +// let addr = instantiate(CONTRACT, 0, vec![0]); // // No balance to pay for fees. // assert_eq!( // decoded::(create(addr.clone(), ASSET_ID, addr.clone(), 1)), // Module { index: 10, error: 2 }, // ); // // Instantiate a contract without balance (relay token). -// let addr = instantiate("../examples/fungibles/target/ink/fungibles.wasm", 100, vec![2]); +// let addr = instantiate(CONTRACT, 100, vec![2]); // // No balance to pay the deposit. // assert_eq!( // decoded::(create(addr.clone(), ASSET_ID, addr.clone(), 1)), @@ -628,7 +593,7 @@ fn token_metadata_works() { // ); // // Instantiate a contract with balance. // let addr = -// instantiate("../examples/fungibles/target/ink/fungibles.wasm", INIT_VALUE, vec![1]); +// instantiate(CONTRACT, INIT_VALUE, vec![1]); // assert_eq!( // decoded::(create(addr.clone(), ASSET_ID, BOB, 0)), // Module { index: 52, error: 7 }, @@ -652,7 +617,7 @@ fn token_metadata_works() { // new_test_ext().execute_with(|| { // let _ = env_logger::try_init(); // let addr = -// instantiate("../examples/fungibles/target/ink/fungibles.wasm", INIT_VALUE, vec![]); +// instantiate(CONTRACT, INIT_VALUE, vec![]); // // create_asset(addr.clone(), ASSET_ID, 1); // let result = set_metadata(addr.clone(), ASSET_ID, vec![12], vec![12], 12); diff --git a/pop-api/src/lib.rs b/pop-api/src/lib.rs index 86621c51..a984bb9e 100644 --- a/pop-api/src/lib.rs +++ b/pop-api/src/lib.rs @@ -1,17 +1,9 @@ #![cfg_attr(not(feature = "std"), no_std, no_main)] -use ink::env::chain_extension::FromStatusCode; - use constants::DECODING_FAILED; - +use ink::env::chain_extension::FromStatusCode; #[cfg(feature = "assets")] pub use v0::assets; -#[cfg(feature = "balances")] -pub use v0::balances; -#[cfg(feature = "cross-chain")] -pub use v0::cross_chain; -#[cfg(feature = "nfts")] -pub use v0::nfts; pub mod primitives; pub mod v0; @@ -22,7 +14,8 @@ pub type Result = core::result::Result; mod constants { // Errors: pub(crate) const DECODING_FAILED: u32 = 255; - pub(crate) const MODULE_ERROR: u8 = 3; + // TODO: will be used in the future when the remaining fungibles features will be implemented. + pub(crate) const _MODULE_ERROR: u8 = 3; // Function IDs: pub(crate) const DISPATCH: u8 = 0; @@ -31,6 +24,7 @@ mod constants { // Modules: pub(crate) const ASSETS: u8 = 52; pub(crate) const BALANCES: u8 = 10; + pub(crate) const FUNGIBLES: u8 = 150; } /// Represents a status code returned by the runtime. diff --git a/pop-api/src/primitives.rs b/pop-api/src/primitives.rs index 33285044..a3d596a5 100644 --- a/pop-api/src/primitives.rs +++ b/pop-api/src/primitives.rs @@ -1,8 +1,5 @@ use ink::env::{DefaultEnvironment, Environment}; - pub use pop_primitives::*; pub(crate) type AccountId = ::AccountId; pub(crate) type Balance = ::Balance; -#[cfg(any(feature = "nfts", feature = "cross-chain"))] -type BlockNumber = ::BlockNumber; diff --git a/pop-api/src/v0/assets/fungibles.rs b/pop-api/src/v0/assets/fungibles.rs index 255e8502..42373cd7 100644 --- a/pop-api/src/v0/assets/fungibles.rs +++ b/pop-api/src/v0/assets/fungibles.rs @@ -1,26 +1,55 @@ -use ink::prelude::vec::Vec; +use ink::{env::chain_extension::ChainExtensionMethod, prelude::vec::Vec, scale::Decode}; use crate::{ - assets, - constants::{ASSETS, BALANCES, MODULE_ERROR}, + constants::{ASSETS, BALANCES, DECODING_FAILED, DISPATCH, FUNGIBLES, READ_STATE}, primitives::{AccountId, AssetId, Balance}, + v0::V0, Result, StatusCode, }; +use constants::*; +pub use metadata::*; /// Local Fungibles: /// 1. PSP-22 Interface /// 2. PSP-22 Metadata Interface /// 3. Asset Management -/// 1. PSP-22 Interface: -/// - total_supply -/// - balance_of -/// - allowance -/// - transfer -/// - transfer_from -/// - approve -/// - increase_allowance -/// - decrease_allowance +mod constants { + /// 1. PSP-22 Interface: + /// - total_supply + pub const TOTAL_SUPPLY: u8 = 0; + /// - balance_of + pub const BALANCE_OF: u8 = 1; + /// - allowance + pub const ALLOWANCE: u8 = 2; + /// - transfer + pub(super) const TRANSFER: u8 = 3; + /// - transfer_from + pub(super) const TRANSFER_FROM: u8 = 4; + /// - approve + pub(super) const APPROVE: u8 = 5; + /// - increase_allowance + pub(super) const INCREASE_ALLOWANCE: u8 = 6; + /// - decrease_allowance + pub(super) const DECREASE_ALLOWANCE: u8 = 7; + + /// 2. PSP-22 Metadata Interface: + /// - token_name + pub const TOKEN_NAME: u8 = 8; + /// - token_symbol + pub const TOKEN_SYMBOL: u8 = 9; + /// - token_decimals + pub const TOKEN_DECIMALS: u8 = 10; + + // 3. Asset Management: + // - create + // - start_destroy + // - destroy_accounts + // - destroy_approvals + // - finish_destroy + // - set_metadata + // - clear_metadata +} /// Returns the total token supply for a given asset ID. /// @@ -31,7 +60,12 @@ use crate::{ /// The total supply of the token, or an error if the operation fails. #[inline] pub fn total_supply(id: AssetId) -> Result { - assets::total_supply(id) + ChainExtensionMethod::build(u32::from_le_bytes([V0, READ_STATE, FUNGIBLES, TOTAL_SUPPLY])) + .input::() + .output::>, true>() + .handle_error_code::() + .call(&(id)) + .and_then(|v| Balance::decode(&mut &v[..]).map_err(|_e| StatusCode(DECODING_FAILED))) } /// Returns the account balance for the specified `owner` for a given asset ID. Returns `0` if @@ -45,7 +79,12 @@ pub fn total_supply(id: AssetId) -> Result { /// The balance of the specified account, or an error if the operation fails. #[inline] pub fn balance_of(id: AssetId, owner: AccountId) -> Result { - assets::balance_of(id, owner) + ChainExtensionMethod::build(u32::from_le_bytes([V0, READ_STATE, FUNGIBLES, BALANCE_OF])) + .input::<(AssetId, AccountId)>() + .output::>, true>() + .handle_error_code::() + .call(&(id, owner)) + .and_then(|v| Balance::decode(&mut &v[..]).map_err(|_e| StatusCode(DECODING_FAILED))) } /// Returns the amount which `spender` is still allowed to withdraw from `owner` for a given @@ -60,7 +99,12 @@ pub fn balance_of(id: AssetId, owner: AccountId) -> Result { /// The remaining allowance, or an error if the operation fails. #[inline] pub fn allowance(id: AssetId, owner: AccountId, spender: AccountId) -> Result { - assets::allowance(id, owner, spender) + ChainExtensionMethod::build(u32::from_le_bytes([V0, READ_STATE, FUNGIBLES, ALLOWANCE])) + .input::<(AssetId, AccountId, AccountId)>() + .output::>, true>() + .handle_error_code::() + .call(&(id, owner, spender)) + .and_then(|v| Balance::decode(&mut &v[..]).map_err(|_e| StatusCode(DECODING_FAILED))) } /// Transfers `value` amount of tokens from the caller's account to account `to`, with additional @@ -74,8 +118,12 @@ pub fn allowance(id: AssetId, owner: AccountId, spender: AccountId) -> Result Result<()> { - assets::transfer_keep_alive(id, to, value) +pub fn transfer(id: AssetId, target: AccountId, amount: Balance) -> Result<()> { + ChainExtensionMethod::build(u32::from_le_bytes([V0, DISPATCH, FUNGIBLES, TRANSFER])) + .input::<(AssetId, AccountId, Balance)>() + .output::, true>() + .handle_error_code::() + .call(&(id, target, amount)) } /// Transfers `value` tokens on behalf of `from` to account `to` with additional `data` @@ -91,8 +139,12 @@ pub fn transfer(id: AssetId, to: AccountId, value: Balance) -> Result<()> { /// # Returns /// Returns `Ok(())` if successful, or an error if the transfer fails. #[inline] -pub fn transfer_from(id: AssetId, from: AccountId, to: AccountId, value: Balance) -> Result<()> { - assets::transfer_approved(id, from, to, value) +pub fn transfer_from(id: AssetId, from: AccountId, to: AccountId, amount: Balance) -> Result<()> { + ChainExtensionMethod::build(u32::from_le_bytes([V0, DISPATCH, FUNGIBLES, TRANSFER_FROM])) + .input::<(AssetId, AccountId, AccountId, Balance)>() + .output::, true>() + .handle_error_code::() + .call(&(id, from, to, amount)) } /// Approves an account to spend a specified number of tokens on behalf of the caller. @@ -105,9 +157,12 @@ pub fn transfer_from(id: AssetId, from: AccountId, to: AccountId, value: Balance /// # Returns /// Returns `Ok(())` if successful, or an error if the approval fails. #[inline] -pub fn approve(id: AssetId, spender: AccountId, value: Balance) -> Result<()> { - assets::cancel_approval(id, spender)?; - assets::approve_transfer(id, spender, value) +pub fn approve(id: AssetId, spender: AccountId, amount: Balance) -> Result<()> { + ChainExtensionMethod::build(u32::from_le_bytes([V0, DISPATCH, FUNGIBLES, APPROVE])) + .input::<(AssetId, AccountId, Balance)>() + .output::, true>() + .handle_error_code::() + .call(&(id, spender, amount)) } /// Increases the allowance of a spender. @@ -121,7 +176,11 @@ pub fn approve(id: AssetId, spender: AccountId, value: Balance) -> Result<()> { /// Returns `Ok(())` if successful, or an error if the operation fails. #[inline] pub fn increase_allowance(id: AssetId, spender: AccountId, value: Balance) -> Result<()> { - assets::approve_transfer(id, spender, value) + ChainExtensionMethod::build(u32::from_le_bytes([V0, DISPATCH, FUNGIBLES, INCREASE_ALLOWANCE])) + .input::<(AssetId, AccountId, Balance)>() + .output::, true>() + .handle_error_code::() + .call(&(id, spender, value)) } /// Decreases the allowance of a spender. @@ -134,63 +193,69 @@ pub fn increase_allowance(id: AssetId, spender: AccountId, value: Balance) -> Re /// # Returns /// Returns `Ok(())` if successful, or an error if the operation fails. #[inline] -pub fn decrease_allowance(_id: AssetId, _spender: AccountId, _value: Balance) -> Result<()> { - // let allowance = assets::allowance(id, owner, spender)?; - // assets::cancel_approval(id, spender.clone())?; - // assets::approve_transfer(id, spender, value) - Ok(()) +pub fn decrease_allowance(id: AssetId, spender: AccountId, value: Balance) -> Result<()> { + ChainExtensionMethod::build(u32::from_le_bytes([V0, DISPATCH, FUNGIBLES, DECREASE_ALLOWANCE])) + .input::<(AssetId, AccountId, Balance)>() + .output::, true>() + .handle_error_code::() + .call(&(id, spender, value)) } -/// 2. PSP-22 Metadata Interface: -/// - token_name -/// - token_symbol -/// - token_decimals - -/// Returns the token name for a given asset ID. -/// -/// # Arguments -/// * `id` - The ID of the asset. -/// -/// # Returns -/// The name of the token as a byte vector, or an error if the operation fails. -#[inline] -pub fn token_name(id: AssetId) -> Result> { - assets::token_name(id) -} +pub mod metadata { + use super::*; + /// Returns the token name for a given asset ID. + /// + /// # Arguments + /// * `id` - The ID of the asset. + /// + /// # Returns + /// The name of the token as a byte vector, or an error if the operation fails. + #[inline] + pub fn token_name(id: AssetId) -> Result> { + ChainExtensionMethod::build(u32::from_le_bytes([V0, READ_STATE, FUNGIBLES, TOKEN_NAME])) + .input::() + .output::>, true>() + .handle_error_code::() + .call(&(id)) + .and_then(|v| >::decode(&mut &v[..]).map_err(|_e| StatusCode(DECODING_FAILED))) + } -/// Returns the token symbol for a given asset ID. -/// -/// # Arguments -/// * `id` - The ID of the asset. -/// -/// # Returns -/// The symbol of the token as a byte vector, or an error if the operation fails. -#[inline] -pub fn token_symbol(id: AssetId) -> Result> { - assets::token_symbol(id) -} + /// Returns the token symbol for a given asset ID. + /// + /// # Arguments + /// * `id` - The ID of the asset. + /// + /// # Returns + /// The symbol of the token as a byte vector, or an error if the operation fails. + #[inline] + pub fn token_symbol(id: AssetId) -> Result> { + ChainExtensionMethod::build(u32::from_le_bytes([V0, READ_STATE, FUNGIBLES, TOKEN_SYMBOL])) + .input::() + .output::>, true>() + .handle_error_code::() + .call(&(id)) + .and_then(|v| >::decode(&mut &v[..]).map_err(|_e| StatusCode(DECODING_FAILED))) + } -/// Returns the token decimals for a given asset ID. -/// -/// # Arguments -/// * `id` - The ID of the asset. -/// -/// # Returns -/// The number of decimals of the token as a byte vector, or an error if the operation fails. -#[inline] -pub fn token_decimals(id: AssetId) -> Result { - assets::token_decimals(id) + /// Returns the token decimals for a given asset ID. + /// + /// # Arguments + /// * `id` - The ID of the asset. + /// + /// # Returns + /// The number of decimals of the token as a byte vector, or an error if the operation fails. + #[inline] + pub fn token_decimals(id: AssetId) -> Result { + ChainExtensionMethod::build(u32::from_le_bytes([V0, READ_STATE, FUNGIBLES, TOKEN_DECIMALS])) + .input::() + .output::>, true>() + .handle_error_code::() + .call(&(id)) + .and_then(|v| ::decode(&mut &v[..]).map_err(|_e| StatusCode(DECODING_FAILED))) + } } -// /// 3. Asset Management: -// /// - create -// /// - start_destroy -// /// - destroy_accounts -// /// - destroy_approvals -// /// - finish_destroy -// /// - set_metadata -// /// - clear_metadata -// +// pub asset_management { // /// Create a new token with a given asset ID. // /// // /// # Arguments @@ -200,9 +265,9 @@ pub fn token_decimals(id: AssetId) -> Result { // /// // /// # Returns // /// Returns `Ok(())` if successful, or an error if the creation fails. -// // pub fn create(id: AssetId, admin: impl Into>, min_balance: Balance) -> Result<()> { -// // assets::create(id, admin, min_balance) -// // } +// pub fn create(id: AssetId, admin: impl Into>, min_balance: Balance) -> Result<()> { +// Ok(()) +// } // // /// Start the process of destroying a token with a given asset ID. // /// @@ -211,11 +276,9 @@ pub fn token_decimals(id: AssetId) -> Result { // /// // /// # Returns // /// Returns `Ok(())` if successful, or an error if the operation fails. -// // fn start_destroy(id: AssetId) -> Result<()> { -// // Ok(dispatch(RuntimeCall::Assets(AssetsCall::StartDestroy { -// // id: id.into(), -// // }))?) -// // } +// fn start_destroy(id: AssetId) -> Result<()> { +// Ok(()) +// } // // /// Destroy all accounts associated with a token with a given asset ID. // /// @@ -224,11 +287,9 @@ pub fn token_decimals(id: AssetId) -> Result { // /// // /// # Returns // /// Returns `Ok(())` if successful, or an error if the operation fails. -// // fn destroy_accounts(id: AssetId) -> Result<()> { -// // Ok(dispatch(RuntimeCall::Assets(AssetsCall::DestroyAccounts { -// // id: id.into(), -// // }))?) -// // } +// fn destroy_accounts(id: AssetId) -> Result<()> { +// Ok(()) +// } // // /// Destroy all approvals associated with a token with a given asset ID. // /// @@ -237,11 +298,9 @@ pub fn token_decimals(id: AssetId) -> Result { // /// // /// # Returns // /// Returns `Ok(())` if successful, or an error if the operation fails. -// // fn destroy_approvals(id: AssetId) -> Result<()> { -// // Ok(dispatch(RuntimeCall::Assets(AssetsCall::DestroyApprovals { -// // id: id.into(), -// // }))?) -// // } +// fn destroy_approvals(id: AssetId) -> Result<()> { +// Ok(()) +// } // // /// Complete the process of destroying a token with a given asset ID. // /// @@ -250,11 +309,9 @@ pub fn token_decimals(id: AssetId) -> Result { // /// // /// # Returns // /// Returns `Ok(())` if successful, or an error if the operation fails. -// // fn finish_destroy(id: AssetId) -> Result<()> { -// // Ok(dispatch(RuntimeCall::Assets(AssetsCall::FinishDestroy { -// // id: id.into(), -// // }))?) -// // } +// fn finish_destroy(id: AssetId) -> Result<()> { +// Ok(()) +// } // // /// Set the metadata for a token with a given asset ID. // /// @@ -263,9 +320,9 @@ pub fn token_decimals(id: AssetId) -> Result { // /// // /// # Returns // /// Returns `Ok(())` if successful, or an error if the operation fails. -// // pub fn set_metadata(id: AssetId, name: Vec, symbol: Vec, decimals: u8) -> Result<()> { -// // assets::set_metadata(id, name, symbol, decimals) -// // } +// pub fn set_metadata(id: AssetId, name: Vec, symbol: Vec, decimals: u8) -> Result<()> { +// Ok(()) +// } // // /// Clear the metadata for a token with a given asset ID. // /// @@ -274,11 +331,10 @@ pub fn token_decimals(id: AssetId) -> Result { // /// // /// # Returns // /// Returns `Ok(())` if successful, or an error if the operation fails. -// // fn clear_metadata(id: AssetId) -> Result<()> { -// // Ok(dispatch(RuntimeCall::Assets(AssetsCall::ClearMetadata { -// // id: id.into(), -// // }))?) -// // } +// fn clear_metadata(id: AssetId) -> Result<()> { +// Ok(()) +// } +// } // // pub fn asset_exists(id: AssetId) -> Result { // assets::asset_exists(id) @@ -332,15 +388,15 @@ impl From for FungiblesError { let encoded = value.0.to_le_bytes(); match encoded { // Balances. - [MODULE_ERROR, BALANCES, 2, _] => FungiblesError::NoBalance, + [_, BALANCES, 2, _] => FungiblesError::NoBalance, // Assets. - [MODULE_ERROR, ASSETS, 0, _] => FungiblesError::NoAccount, - [MODULE_ERROR, ASSETS, 1, _] => FungiblesError::NoPermission, - [MODULE_ERROR, ASSETS, 2, _] => FungiblesError::Unknown, - [MODULE_ERROR, ASSETS, 3, _] => FungiblesError::InUse, - [MODULE_ERROR, ASSETS, 5, _] => FungiblesError::MinBalanceZero, - [MODULE_ERROR, ASSETS, 7, _] => FungiblesError::InsufficientAllowance, - [MODULE_ERROR, ASSETS, 10, _] => FungiblesError::AssetNotLive, + [_, ASSETS, 0, _] => FungiblesError::NoAccount, + [_, ASSETS, 1, _] => FungiblesError::NoPermission, + [_, ASSETS, 2, _] => FungiblesError::Unknown, + [_, ASSETS, 3, _] => FungiblesError::InUse, + [_, ASSETS, 5, _] => FungiblesError::MinBalanceZero, + [_, ASSETS, 7, _] => FungiblesError::InsufficientAllowance, + [_, ASSETS, 10, _] => FungiblesError::AssetNotLive, _ => FungiblesError::Other(value), } } @@ -407,7 +463,7 @@ mod tests { Corruption, Unavailable, RootNotAllowed, - UnknownFunctionCall, + UnknownCall, DecodingFailed, ]; for error in other_errors { diff --git a/pop-api/src/v0/assets/mod.rs b/pop-api/src/v0/assets/mod.rs index 00021fc0..197db710 100644 --- a/pop-api/src/v0/assets/mod.rs +++ b/pop-api/src/v0/assets/mod.rs @@ -1,235 +1,2 @@ -use ink::{env::chain_extension::ChainExtensionMethod, prelude::vec::Vec, scale::Decode}; - -use crate::{ - constants::{ASSETS, DECODING_FAILED, DISPATCH, READ_STATE}, - primitives::{AccountId, AssetId, Balance}, - v0::V0, - Result, StatusCode, -}; - +#[cfg(feature = "fungibles")] pub mod fungibles; - -/// [Pallet Assets](https://github.com/paritytech/polkadot-sdk/blob/master/substrate/frame/assets/src/lib.rs): -/// 1. Dispatchables -/// 2. Read state functions -/// -/// 1. Dispatchables within pallet assets (TrustBackedAssets instance): -/// - create -/// - start_destroy -/// - destroy_accounts -/// - destroy_approvals -/// - finish_destroy -/// - mint -/// - burn -/// - transfer -/// - transfer_keep_alive -const TRANSFER_KEEP_ALIVE: u8 = 9; -/// - set_metadata -/// - clear_metadata -/// - approve_transfer -const APPROVE_TRANSFER: u8 = 22; -/// - cancel_approval -const CANCEL_APPROVAL: u8 = 23; -/// - transfer_approved -const TRANSFER_APPROVED: u8 = 25; - -/// Issue a new class of fungible assets from a public origin. -// pub(crate) fn create( -// id: AssetId, -// admin: impl Into>, -// min_balance: Balance, -// ) -> Result<()> { -// dispatch(RuntimeCall::Assets(AssetsCall::Create { -// id: id.into(), -// admin: admin.into(), -// min_balance, -// })) -// } -// -// /// Start the process of destroying a fungible asset class. -// pub(crate) fn start_destroy(id: AssetId) -> Result<()> { -// dispatch(RuntimeCall::Assets(AssetsCall::StartDestroy { id: id.into() })) -// } -// -// /// Destroy all accounts associated with a given asset. -// pub(crate) fn destroy_accounts(id: AssetId) -> Result<()> { -// dispatch(RuntimeCall::Assets(AssetsCall::DestroyAccounts { id: id.into() })) -// } -// -// /// Destroy all approvals associated with a given asset up to the max (see runtime configuration Assets `RemoveItemsLimit`). -// pub(crate) fn destroy_approvals(id: AssetId) -> Result<()> { -// dispatch(RuntimeCall::Assets(AssetsCall::DestroyApprovals { id: id.into() })) -// } -// -// /// Complete destroying asset and unreserve currency. -// pub(crate) fn finish_destroy(id: AssetId) -> Result<()> { -// dispatch(RuntimeCall::Assets(AssetsCall::FinishDestroy { id: id.into() })) -// } - -// /// Mint assets of a particular class. -// pub(crate) fn mint( -// id: AssetId, -// beneficiary: impl Into>, -// amount: Balance, -// ) -> Result<()> { -// dispatch(RuntimeCall::Assets(AssetsCall::Mint { -// id: id.into(), -// beneficiary: beneficiary.into(), -// amount: Compact(amount), -// })) -// } -// -// /// Reduce the balance of `who` by as much as possible up to `amount` assets of `id`. -// pub(crate) fn burn(id: AssetId, who: impl Into>, amount: Balance) -> Result<()> { -// dispatch(RuntimeCall::Assets(AssetsCall::Burn { -// id: id.into(), -// who: who.into(), -// amount: Compact(amount), -// })) -// } - -/// Move some assets from the sender account to another, keeping the sender account alive. -#[inline] -pub fn transfer_keep_alive(id: AssetId, target: AccountId, amount: Balance) -> Result<()> { - ChainExtensionMethod::build(u32::from_le_bytes([ - V0, - DISPATCH, - ASSETS, - // E.D. is always respected with transferring tokens via the API. - TRANSFER_KEEP_ALIVE, - ])) - .input::<(AssetId, AccountId, Balance)>() - .output::, true>() - .handle_error_code::() - .call(&(id, target, amount)) -} - -// /// Set the metadata for an asset. -// pub(crate) fn set_metadata( -// id: AssetId, -// name: Vec, -// symbol: Vec, -// decimals: u8, -// ) -> Result<()> { -// dispatch(RuntimeCall::Assets(AssetsCall::SetMetadata { id: id.into(), name, symbol, decimals })) -// } - -// /// Clear the metadata for an asset. -// pub(crate) fn clear_metadata(id: AssetId) -> Result<()> { -// dispatch(RuntimeCall::Assets(AssetsCall::ClearMetadata { id: id.into() })) -// } - -/// Approve an amount of asset for transfer by a delegated third-party account. -#[inline] -pub fn approve_transfer(id: AssetId, delegate: AccountId, amount: Balance) -> Result<()> { - ChainExtensionMethod::build(u32::from_le_bytes([V0, DISPATCH, ASSETS, APPROVE_TRANSFER])) - .input::<(AssetId, AccountId, Balance)>() - .output::, true>() - .handle_error_code::() - .call(&(id, delegate, amount)) -} - -/// Cancel all of some asset approved for delegated transfer by a third-party account. -#[inline] -pub fn cancel_approval(id: AssetId, delegate: AccountId) -> Result<()> { - ChainExtensionMethod::build(u32::from_le_bytes([V0, DISPATCH, ASSETS, CANCEL_APPROVAL])) - .input::<(AssetId, AccountId)>() - .output::, true>() - .handle_error_code::() - .call(&(id, delegate)) -} - -/// Transfer some asset balance from a previously delegated account to some third-party -/// account. -#[inline] -pub fn transfer_approved( - id: AssetId, - from: AccountId, - to: AccountId, - amount: Balance, -) -> Result<()> { - ChainExtensionMethod::build(u32::from_le_bytes([V0, DISPATCH, ASSETS, TRANSFER_APPROVED])) - .input::<(AssetId, AccountId, AccountId, Balance)>() - .output::, true>() - .handle_error_code::() - .call(&(id, from, to, amount)) -} - -/// 2. Read state functions: -/// - total_supply -const TOTAL_SUPPLY: u8 = 0; -/// - balance_of -const BALANCE_OF: u8 = 1; -/// - allowance -const ALLOWANCE: u8 = 2; -/// - token_name -const TOKEN_NAME: u8 = 3; -/// - token_symbol -const TOKEN_SYMBOL: u8 = 4; -/// - token_decimals -const TOKEN_DECIMALS: u8 = 5; -/// - asset_exists - -#[inline] -pub fn total_supply(id: AssetId) -> Result { - ChainExtensionMethod::build(u32::from_le_bytes([V0, READ_STATE, ASSETS, TOTAL_SUPPLY])) - .input::() - .output::>, true>() - .handle_error_code::() - .call(&(id)) - .and_then(|v| Balance::decode(&mut &v[..]).map_err(|_e| StatusCode(DECODING_FAILED))) -} - -#[inline] -pub fn balance_of(id: AssetId, owner: AccountId) -> Result { - ChainExtensionMethod::build(u32::from_le_bytes([V0, READ_STATE, ASSETS, BALANCE_OF])) - .input::<(AssetId, AccountId)>() - .output::>, true>() - .handle_error_code::() - .call(&(id, owner)) - .and_then(|v| Balance::decode(&mut &v[..]).map_err(|_e| StatusCode(DECODING_FAILED))) -} - -#[inline] -pub fn allowance(id: AssetId, owner: AccountId, spender: AccountId) -> Result { - ChainExtensionMethod::build(u32::from_le_bytes([V0, READ_STATE, ASSETS, ALLOWANCE])) - .input::<(AssetId, AccountId, AccountId)>() - .output::>, true>() - .handle_error_code::() - .call(&(id, owner, spender)) - .and_then(|v| Balance::decode(&mut &v[..]).map_err(|_e| StatusCode(DECODING_FAILED))) -} - -#[inline] -pub fn token_name(id: AssetId) -> Result> { - ChainExtensionMethod::build(u32::from_le_bytes([V0, READ_STATE, ASSETS, TOKEN_NAME])) - .input::() - .output::>, true>() - .handle_error_code::() - .call(&(id)) - .and_then(|v| >::decode(&mut &v[..]).map_err(|_e| StatusCode(DECODING_FAILED))) -} -// -#[inline] -pub fn token_symbol(id: AssetId) -> Result> { - ChainExtensionMethod::build(u32::from_le_bytes([V0, READ_STATE, ASSETS, TOKEN_SYMBOL])) - .input::() - .output::>, true>() - .handle_error_code::() - .call(&(id)) - .and_then(|v| >::decode(&mut &v[..]).map_err(|_e| StatusCode(DECODING_FAILED))) -} - -#[inline] -pub fn token_decimals(id: AssetId) -> Result { - ChainExtensionMethod::build(u32::from_le_bytes([V0, READ_STATE, ASSETS, TOKEN_DECIMALS])) - .input::() - .output::>, true>() - .handle_error_code::() - .call(&(id)) - .and_then(|v| ::decode(&mut &v[..]).map_err(|_e| StatusCode(DECODING_FAILED))) -} - -// pub(crate) fn asset_exists(id: AssetId) -> Result { -// state::read(RuntimeStateKeys::Assets(AssetsKeys::AssetExists(id))) -// } diff --git a/pop-api/src/v0/balances.rs b/pop-api/src/v0/balances.rs deleted file mode 100644 index bf029178..00000000 --- a/pop-api/src/v0/balances.rs +++ /dev/null @@ -1,88 +0,0 @@ -use crate::{ - dispatch, primitives::MultiAddress, v0::RuntimeCall, AccountId, PopApiError, - PopApiError::UnknownStatusCode, -}; - -type Result = core::result::Result; - -pub fn transfer_keep_alive( - dest: impl Into>, - value: u128, -) -> Result<()> { - Ok(dispatch(RuntimeCall::Balances(BalancesCall::TransferKeepAlive { - dest: dest.into(), - value, - }))?) -} - -#[derive(scale::Encode)] -#[allow(dead_code)] -pub(crate) enum BalancesCall { - #[codec(index = 3)] - TransferKeepAlive { - dest: MultiAddress, - #[codec(compact)] - value: u128, - }, -} - -#[derive(Debug, Copy, Clone, PartialEq, Eq, scale::Encode, scale::Decode)] -#[cfg_attr(feature = "std", derive(scale_info::TypeInfo))] -pub enum Error { - /// Vesting balance too high to send value. - VestingBalance, - /// Account liquidity restrictions prevent withdrawal. - LiquidityRestrictions, - /// Balance too low to send value. - InsufficientBalance, - /// Value too low to create account due to existential deposit. - ExistentialDeposit, - /// Transfer/payment would kill account. - Expendability, - /// A vesting schedule already exists for this account. - ExistingVestingSchedule, - /// Beneficiary account must pre-exist. - DeadAccount, - /// Number of named reserves exceed `MaxReserves`. - TooManyReserves, - /// Number of holds exceed `VariantCountOf`. - TooManyHolds, - /// Number of freezes exceed `MaxFreezes`. - TooManyFreezes, - /// The issuance cannot be modified since it is already deactivated. - IssuanceDeactivated, - /// The delta cannot be zero. - DeltaZero, -} - -impl TryFrom for Error { - type Error = PopApiError; - - fn try_from(status_code: u32) -> core::result::Result { - use Error::*; - match status_code { - 0 => Ok(VestingBalance), - 1 => Ok(LiquidityRestrictions), - 2 => Ok(InsufficientBalance), - 3 => Ok(ExistentialDeposit), - 4 => Ok(Expendability), - 5 => Ok(ExistingVestingSchedule), - 6 => Ok(DeadAccount), - 7 => Ok(TooManyReserves), - 8 => Ok(TooManyHolds), - 9 => Ok(TooManyFreezes), - 10 => Ok(IssuanceDeactivated), - 11 => Ok(DeltaZero), - _ => Err(UnknownStatusCode(status_code)), - } - } -} - -impl From for Error { - fn from(error: PopApiError) -> Self { - match error { - PopApiError::Balances(e) => e, - _ => panic!("expected balances error"), - } - } -} diff --git a/pop-api/src/v0/cross_chain/coretime.rs b/pop-api/src/v0/cross_chain/coretime.rs deleted file mode 100644 index 0039ed20..00000000 --- a/pop-api/src/v0/cross_chain/coretime.rs +++ /dev/null @@ -1,11 +0,0 @@ -use crate::{ - primitives::cross_chain::{CrossChainMessage, OnDemand, RelayChainMessage}, - send_xcm, -}; - -/// Send a cross-chain message to place a sport order for instantaneous coretime. -pub fn place_spot_order(max_amount: u128, para_id: u32) -> crate::cross_chain::Result<()> { - Ok(send_xcm(CrossChainMessage::Relay(RelayChainMessage::OnDemand( - OnDemand::PlaceOrderKeepAlive { max_amount, para_id }, - )))?) -} diff --git a/pop-api/src/v0/cross_chain/mod.rs b/pop-api/src/v0/cross_chain/mod.rs deleted file mode 100644 index 6732c119..00000000 --- a/pop-api/src/v0/cross_chain/mod.rs +++ /dev/null @@ -1,107 +0,0 @@ -pub mod coretime; - -use crate::{PopApiError::UnknownStatusCode, *}; - -type Result = core::result::Result; - -#[derive(Debug, Copy, Clone, PartialEq, Eq, scale::Encode, scale::Decode)] -#[cfg_attr(feature = "std", derive(scale_info::TypeInfo))] -pub enum Error { - /// The desired destination was unreachable, generally because there is a no way of routing - /// to it. - Unreachable, - /// There was some other issue (i.e. not to do with routing) in sending the message. - /// Perhaps a lack of space for buffering the message. - SendFailure, - /// The message execution fails the filter. - Filtered, - /// The message's weight could not be determined. - UnweighableMessage, - /// The destination `Location` provided cannot be inverted. - DestinationNotInvertible, - /// The assets to be sent are empty. - Empty, - /// Could not re-anchor the assets to declare the fees for the destination chain. - CannotReanchor, - /// Too many assets have been attempted for transfer. - TooManyAssets, - /// Origin is invalid for sending. - InvalidOrigin, - /// The version of the `Versioned` value used is not able to be interpreted. - BadVersion, - /// The given location could not be used (e.g. because it cannot be expressed in the - /// desired version of XCM). - BadLocation, - /// The referenced subscription could not be found. - NoSubscription, - /// The location is invalid since it already has a subscription from us. - AlreadySubscribed, - /// Could not check-out the assets for teleportation to the destination chain. - CannotCheckOutTeleport, - /// The owner does not own (all) of the asset that they wish to do the operation on. - LowBalance, - /// The asset owner has too many locks on the asset. - TooManyLocks, - /// The given account is not an identifiable sovereign account for any location. - AccountNotSovereign, - /// The operation required fees to be paid which the initiator could not meet. - FeesNotMet, - /// A remote lock with the corresponding data could not be found. - LockNotFound, - /// The unlock operation cannot succeed because there are still consumers of the lock. - InUse, - /// Invalid non-concrete asset. - InvalidAssetNotConcrete, - /// Invalid asset, reserve chain could not be determined for it. - InvalidAssetUnknownReserve, - /// Invalid asset, do not support remote asset reserves with different fees reserves. - InvalidAssetUnsupportedReserve, - /// Too many assets with different reserve locations have been attempted for transfer. - TooManyReserves, - /// Local XCM execution incomplete. - LocalExecutionIncomplete, -} - -impl TryFrom for Error { - type Error = PopApiError; - - fn try_from(status_code: u32) -> core::result::Result { - use Error::*; - match status_code { - 0 => Ok(Unreachable), - 1 => Ok(SendFailure), - 2 => Ok(Filtered), - 3 => Ok(UnweighableMessage), - 4 => Ok(DestinationNotInvertible), - 5 => Ok(Empty), - 6 => Ok(CannotReanchor), - 7 => Ok(TooManyAssets), - 8 => Ok(InvalidOrigin), - 9 => Ok(BadVersion), - 10 => Ok(BadLocation), - 11 => Ok(NoSubscription), - 12 => Ok(AlreadySubscribed), - 13 => Ok(CannotCheckOutTeleport), - 14 => Ok(LowBalance), - 15 => Ok(TooManyLocks), - 16 => Ok(AccountNotSovereign), - 17 => Ok(FeesNotMet), - 18 => Ok(LockNotFound), - 19 => Ok(InUse), - 20 => Ok(InvalidAssetNotConcrete), - 21 => Ok(InvalidAssetUnknownReserve), - 22 => Ok(InvalidAssetUnsupportedReserve), - 23 => Ok(TooManyReserves), - _ => Err(UnknownStatusCode(status_code)), - } - } -} - -impl From for Error { - fn from(error: PopApiError) -> Self { - match error { - PopApiError::Xcm(e) => e, - _ => panic!("expected xcm error"), - } - } -} diff --git a/pop-api/src/v0/mod.rs b/pop-api/src/v0/mod.rs index f7dab6b4..1c3642e1 100644 --- a/pop-api/src/v0/mod.rs +++ b/pop-api/src/v0/mod.rs @@ -2,12 +2,6 @@ use crate::{primitives::error::Error, StatusCode}; #[cfg(feature = "assets")] pub mod assets; -#[cfg(feature = "balances")] -pub mod balances; -#[cfg(feature = "cross-chain")] -pub mod cross_chain; -#[cfg(feature = "nfts")] -pub mod nfts; pub(crate) const V0: u8 = 0; diff --git a/pop-api/src/v0/nfts.rs b/pop-api/src/v0/nfts.rs deleted file mode 100644 index 63b90a1f..00000000 --- a/pop-api/src/v0/nfts.rs +++ /dev/null @@ -1,883 +0,0 @@ -use super::RuntimeCall; -use crate::{PopApiError::UnknownStatusCode, *}; -use ink::prelude::vec::Vec; -use primitives::{ApprovalsLimit, BoundedBTreeMap, KeyLimit, MultiAddress}; -pub use primitives::{CollectionId, ItemId}; -use scale::Encode; -pub use types::*; - -type StringLimit = u32; -type MaxTips = u32; - -/// Issue a new collection of non-fungible items -pub fn create( - admin: impl Into>, - config: CollectionConfig, -) -> Result<()> { - Ok(dispatch(RuntimeCall::Nfts(NftCalls::Create { admin: admin.into(), config }))?) -} - -/// Destroy a collection of fungible items. -pub fn destroy(collection: CollectionId) -> Result<()> { - Ok(dispatch(RuntimeCall::Nfts(NftCalls::Destroy { collection }))?) -} - -/// Mint an item of a particular collection. -pub fn mint( - collection: CollectionId, - item: ItemId, - mint_to: impl Into>, -) -> Result<()> { - Ok(dispatch(RuntimeCall::Nfts(NftCalls::Mint { - collection, - item, - mint_to: mint_to.into(), - witness_data: None, - }))?) -} - -/// Destroy a single item. -pub fn burn(collection: CollectionId, item: ItemId) -> Result<()> { - Ok(dispatch(RuntimeCall::Nfts(NftCalls::Burn { collection, item }))?) -} - -/// Move an item from the sender account to another. -pub fn transfer( - collection: CollectionId, - item: ItemId, - dest: impl Into>, -) -> Result<()> { - Ok(dispatch(RuntimeCall::Nfts(NftCalls::Transfer { collection, item, dest: dest.into() }))?) -} - -/// Re-evaluate the deposits on some items. -pub fn redeposit(collection: CollectionId, items: Vec) -> Result<()> { - Ok(dispatch(RuntimeCall::Nfts(NftCalls::Redeposit { collection, items }))?) -} - -/// Change the Owner of a collection. -pub fn transfer_ownership( - collection: CollectionId, - new_owner: impl Into>, -) -> Result<()> { - Ok(dispatch(RuntimeCall::Nfts(NftCalls::TransferOwnership { - collection, - new_owner: new_owner.into(), - }))?) -} - -/// Set (or reset) the acceptance of ownership for a particular account. -pub fn set_accept_ownership( - collection: CollectionId, - maybe_collection: Option, -) -> Result<()> { - Ok(dispatch(RuntimeCall::Nfts(NftCalls::SetAcceptOwnership { collection, maybe_collection }))?) -} - -/// Set the maximum number of items a collection could have. -pub fn set_collection_max_supply(collection: CollectionId, max_supply: u32) -> Result<()> { - Ok(dispatch(RuntimeCall::Nfts(NftCalls::SetCollectionMaxSupply { collection, max_supply }))?) -} - -/// Update mint settings. -pub fn update_mint_settings(collection: CollectionId, mint_settings: MintSettings) -> Result<()> { - Ok(dispatch(RuntimeCall::Nfts(NftCalls::UpdateMintSettings { collection, mint_settings }))?) -} - -/// Get the owner of the item, if the item exists. -pub fn owner(collection: CollectionId, item: ItemId) -> Result> { - Ok(state::read(RuntimeStateKeys::Nfts(NftsKeys::Owner(collection, item)))?) -} - -/// Get the owner of the collection, if the collection exists. -pub fn collection_owner(collection: CollectionId) -> Result> { - Ok(state::read(RuntimeStateKeys::Nfts(NftsKeys::CollectionOwner(collection)))?) -} - -/// Get the details of a collection. -pub fn collection(collection: CollectionId) -> Result> { - Ok(state::read(RuntimeStateKeys::Nfts(NftsKeys::Collection(collection)))?) -} - -/// Get the details of an item. -pub fn item(collection: CollectionId, item: ItemId) -> Result> { - Ok(state::read(RuntimeStateKeys::Nfts(NftsKeys::Item(collection, item)))?) -} - -pub mod approvals { - use super::*; - - /// Approve an item to be transferred by a delegated third-party account. - pub fn approve_transfer( - collection: CollectionId, - item: ItemId, - delegate: impl Into>, - maybe_deadline: Option, - ) -> Result<()> { - Ok(dispatch(RuntimeCall::Nfts(NftCalls::ApproveTransfer { - collection, - item, - delegate: delegate.into(), - maybe_deadline, - }))?) - } - - /// Cancel one of the transfer approvals for a specific item. - pub fn cancel_approval( - collection: CollectionId, - item: ItemId, - delegate: impl Into>, - ) -> Result<()> { - Ok(dispatch(RuntimeCall::Nfts(NftCalls::CancelApproval { - collection, - item, - delegate: delegate.into(), - }))?) - } - - /// Cancel all the approvals of a specific item. - pub fn clear_all_transfer_approvals(collection: CollectionId, item: ItemId) -> Result<()> { - Ok(dispatch(RuntimeCall::Nfts(NftCalls::ClearAllTransferApprovals { collection, item }))?) - } -} - -pub mod attributes { - use super::*; - - /// Approve item's attributes to be changed by a delegated third-party account. - pub fn approve_item_attribute( - collection: CollectionId, - item: ItemId, - delegate: impl Into>, - ) -> Result<()> { - Ok(dispatch(RuntimeCall::Nfts(NftCalls::ApproveItemAttributes { - collection, - item, - delegate: delegate.into(), - }))?) - } - - /// Cancel the previously provided approval to change item's attributes. - pub fn cancel_item_attributes_approval( - collection: CollectionId, - item: ItemId, - delegate: impl Into>, - ) -> Result<()> { - Ok(dispatch(RuntimeCall::Nfts(NftCalls::CancelItemAttributesApproval { - collection, - item, - delegate: delegate.into(), - }))?) - } - - /// Set an attribute for a collection or item. - pub fn set_attribute( - collection: CollectionId, - maybe_item: Option, - namespace: AttributeNamespace, - key: BoundedVec, - value: BoundedVec, - ) -> Result<()> { - Ok(dispatch(RuntimeCall::Nfts(NftCalls::SetAttribute { - collection, - maybe_item, - namespace, - key, - value, - }))?) - } - - /// Clear an attribute for a collection or item. - pub fn clear_attribute( - collection: CollectionId, - maybe_item: Option, - namespace: AttributeNamespace, - key: BoundedVec, - ) -> Result<()> { - Ok(dispatch(RuntimeCall::Nfts(NftCalls::ClearAttribute { - collection, - maybe_item, - namespace, - key, - }))?) - } - - /// Get the attribute value of `item` of `collection` corresponding to `key`. - pub fn attribute( - collection: CollectionId, - item: ItemId, - key: BoundedVec, - ) -> Result>> { - Ok(state::read(RuntimeStateKeys::Nfts(NftsKeys::Attribute(collection, item, key)))?) - } - - // /// Get the custom attribute value of `item` of `collection` corresponding to `key`. - // pub fn custom_attribute( - // account: AccountId, - // collection: CollectionId, - // item: ItemId, - // key: BoundedVec, - // ) -> Result>> { - // Ok(state::read(RuntimeStateKeys::Nfts(NftsKeys::CustomAttribute( - // account, collection, item, key, - // )))?) - // } - - /// Get the system attribute value of `item` of `collection` corresponding to `key` if - /// `item` is `Some`. Otherwise, returns the system attribute value of `collection` - /// corresponding to `key`. - pub fn system_attribute( - collection: CollectionId, - item: Option, - key: BoundedVec, - ) -> Result>> { - Ok(state::read(RuntimeStateKeys::Nfts(NftsKeys::SystemAttribute(collection, item, key)))?) - } - - /// Get the attribute value of `item` of `collection` corresponding to `key`. - pub fn collection_attribute( - collection: CollectionId, - key: BoundedVec, - ) -> Result>> { - Ok(state::read(RuntimeStateKeys::Nfts(NftsKeys::CollectionAttribute(collection, key)))?) - } -} - -pub mod locking { - use super::*; - - /// Disallows changing the metadata or attributes of the item. - pub fn lock_item_properties( - collection: CollectionId, - item: ItemId, - lock_metadata: bool, - lock_attributes: bool, - ) -> Result<()> { - Ok(dispatch(RuntimeCall::Nfts(NftCalls::LockItemProperties { - collection, - item, - lock_metadata, - lock_attributes, - }))?) - } - - /// Disallow further unprivileged transfer of an item. - pub fn lock_item_transfer(collection: CollectionId, item: ItemId) -> Result<()> { - Ok(dispatch(RuntimeCall::Nfts(NftCalls::LockItemTransfer { collection, item }))?) - } - - /// Re-allow unprivileged transfer of an item. - pub fn unlock_item_transfer(collection: CollectionId, item: ItemId) -> Result<()> { - Ok(dispatch(RuntimeCall::Nfts(NftCalls::UnlockItemTransfer { collection, item }))?) - } - - /// Disallows specified settings for the whole collection. - pub fn lock_collection( - collection: CollectionId, - lock_settings: CollectionSettings, - ) -> Result<()> { - Ok(dispatch(RuntimeCall::Nfts(NftCalls::LockCollection { collection, lock_settings }))?) - } -} - -pub mod metadata { - use super::*; - - /// Set the metadata for an item. - pub fn set_metadata( - collection: CollectionId, - item: ItemId, - data: BoundedVec, - ) -> Result<()> { - Ok(dispatch(RuntimeCall::Nfts(NftCalls::SetMetadata { collection, item, data }))?) - } - - /// Clear the metadata for an item. - pub fn clear_metadata(collection: CollectionId, item: ItemId) -> Result<()> { - Ok(dispatch(RuntimeCall::Nfts(NftCalls::ClearMetadata { collection, item }))?) - } - - /// Set the metadata for a collection. - pub fn set_collection_metadata( - collection: CollectionId, - data: BoundedVec, - ) -> Result<()> { - Ok(dispatch(RuntimeCall::Nfts(NftCalls::SetCollectionMetadata { collection, data }))?) - } - - /// Clear the metadata for a collection. - pub fn clear_collection_metadata(collection: CollectionId) -> Result<()> { - Ok(dispatch(RuntimeCall::Nfts(NftCalls::ClearCollectionMetadata { collection }))?) - } -} - -pub mod roles { - use super::*; - - /// Change the Issuer, Admin and Freezer of a collection. - pub fn set_team( - collection: CollectionId, - issuer: Option>>, - admin: Option>>, - freezer: Option>>, - ) -> Result<()> { - Ok(dispatch(RuntimeCall::Nfts(NftCalls::SetTeam { - collection, - issuer: issuer.map(|i| i.into()), - admin: admin.map(|i| i.into()), - freezer: freezer.map(|i| i.into()), - }))?) - } -} - -pub mod trading { - use super::*; - - /// Allows to pay the tips. - pub fn pay_tips(tips: BoundedVec) -> Result<()> { - Ok(dispatch(RuntimeCall::Nfts(NftCalls::PayTips { tips }))?) - } - - /// Set (or reset) the price for an item. - pub fn price(collection: CollectionId, item: ItemId, price: Option) -> Result<()> { - Ok(dispatch(RuntimeCall::Nfts(NftCalls::SetPrice { collection, item, price }))?) - } - - /// Allows to buy an item if it's up for sale. - pub fn buy_item(collection: CollectionId, item: ItemId, bid_price: Balance) -> Result<()> { - Ok(dispatch(RuntimeCall::Nfts(NftCalls::BuyItem { collection, item, bid_price }))?) - } - - pub mod swaps { - use super::*; - - /// Register a new atomic swap, declaring an intention to send an `item` in exchange for - /// `desired_item` from origin to target on the current chain. - pub fn create_swap( - offered_collection: CollectionId, - offered_item: ItemId, - desired_collection: CollectionId, - maybe_desired_item: Option, - maybe_price: Option, - duration: BlockNumber, - ) -> Result<()> { - Ok(dispatch(RuntimeCall::Nfts(NftCalls::CreateSwap { - offered_collection, - offered_item, - desired_collection, - maybe_desired_item, - maybe_price, - duration, - }))?) - } - - /// Cancel an atomic swap. - pub fn cancel_swap(offered_collection: CollectionId, offered_item: ItemId) -> Result<()> { - Ok(dispatch(RuntimeCall::Nfts(NftCalls::CancelSwap { - offered_collection, - offered_item, - }))?) - } - - /// Claim an atomic swap. - pub fn claim_swap( - send_collection: CollectionId, - send_item: ItemId, - receive_collection: CollectionId, - receive_item: ItemId, - ) -> Result<()> { - Ok(dispatch(RuntimeCall::Nfts(NftCalls::ClaimSwap { - send_collection, - send_item, - receive_collection, - receive_item, - }))?) - } - } -} - -#[derive(Encode)] -pub(crate) enum NftCalls { - #[codec(index = 0)] - Create { admin: MultiAddress, config: CollectionConfig }, - #[codec(index = 2)] - Destroy { collection: CollectionId }, - #[codec(index = 3)] - Mint { - collection: CollectionId, - item: ItemId, - mint_to: MultiAddress, - witness_data: Option<()>, - }, - #[codec(index = 5)] - Burn { collection: CollectionId, item: ItemId }, - #[codec(index = 6)] - Transfer { collection: CollectionId, item: ItemId, dest: MultiAddress }, - #[codec(index = 7)] - Redeposit { collection: CollectionId, items: Vec }, - #[codec(index = 8)] - LockItemTransfer { collection: CollectionId, item: ItemId }, - #[codec(index = 9)] - UnlockItemTransfer { collection: CollectionId, item: ItemId }, - #[codec(index = 10)] - LockCollection { collection: CollectionId, lock_settings: CollectionSettings }, - #[codec(index = 11)] - TransferOwnership { collection: CollectionId, new_owner: MultiAddress }, - #[codec(index = 12)] - SetTeam { - collection: CollectionId, - issuer: Option>, - admin: Option>, - freezer: Option>, - }, - #[codec(index = 15)] - ApproveTransfer { - collection: CollectionId, - item: ItemId, - delegate: MultiAddress, - maybe_deadline: Option, - }, - #[codec(index = 16)] - CancelApproval { collection: CollectionId, item: ItemId, delegate: MultiAddress }, - #[codec(index = 17)] - ClearAllTransferApprovals { collection: CollectionId, item: ItemId }, - #[codec(index = 18)] - LockItemProperties { - collection: CollectionId, - item: ItemId, - lock_metadata: bool, - lock_attributes: bool, - }, - #[codec(index = 19)] - SetAttribute { - collection: CollectionId, - maybe_item: Option, - namespace: AttributeNamespace, - key: BoundedVec, - value: BoundedVec, - }, - #[codec(index = 21)] - ClearAttribute { - collection: CollectionId, - maybe_item: Option, - namespace: AttributeNamespace, - key: BoundedVec, - }, - #[codec(index = 22)] - ApproveItemAttributes { - collection: CollectionId, - item: ItemId, - delegate: MultiAddress, - }, - #[codec(index = 23)] - CancelItemAttributesApproval { - collection: CollectionId, - item: ItemId, - delegate: MultiAddress, - }, - #[codec(index = 24)] - SetMetadata { collection: CollectionId, item: ItemId, data: BoundedVec }, - #[codec(index = 25)] - ClearMetadata { collection: CollectionId, item: ItemId }, - #[codec(index = 26)] - SetCollectionMetadata { collection: CollectionId, data: BoundedVec }, - #[codec(index = 27)] - ClearCollectionMetadata { collection: CollectionId }, - #[codec(index = 28)] - SetAcceptOwnership { collection: CollectionId, maybe_collection: Option }, - #[codec(index = 29)] - SetCollectionMaxSupply { collection: CollectionId, max_supply: u32 }, - #[codec(index = 30)] - UpdateMintSettings { collection: CollectionId, mint_settings: MintSettings }, - #[codec(index = 31)] - SetPrice { collection: CollectionId, item: ItemId, price: Option }, - #[codec(index = 32)] - BuyItem { collection: CollectionId, item: ItemId, bid_price: Balance }, - #[codec(index = 33)] - PayTips { tips: BoundedVec }, - #[codec(index = 34)] - CreateSwap { - offered_collection: CollectionId, - offered_item: ItemId, - desired_collection: CollectionId, - maybe_desired_item: Option, - maybe_price: Option, - duration: BlockNumber, - }, - #[codec(index = 35)] - CancelSwap { offered_collection: CollectionId, offered_item: ItemId }, - #[codec(index = 36)] - ClaimSwap { - send_collection: CollectionId, - send_item: ItemId, - receive_collection: CollectionId, - receive_item: ItemId, - }, -} - -#[derive(Debug, Copy, Clone, PartialEq, Eq, Encode, scale::Decode)] -#[cfg_attr(feature = "std", derive(scale_info::TypeInfo))] -pub enum Error { - /// The signing account has no permission to do the operation. - NoPermission, - /// The given item ID is unknown. - UnknownCollection, - /// The item ID has already been used for an item. - AlreadyExists, - /// The approval had a deadline that expired, so the approval isn't valid anymore. - ApprovalExpired, - /// The owner turned out to be different to what was expected. - WrongOwner, - /// The witness data given does not match the current state of the chain. - BadWitness, - /// Collection ID is already taken. - CollectionIdInUse, - /// Items within that collection are non-transferable. - ItemsNonTransferable, - /// The provided account is not a delegate. - NotDelegate, - /// The delegate turned out to be different to what was expected. - WrongDelegate, - /// No approval exists that would allow the transfer. - Unapproved, - /// The named owner has not signed ownership acceptance of the collection. - Unaccepted, - /// The item is locked (non-transferable). - ItemLocked, - /// Item's attributes are locked. - LockedItemAttributes, - /// Collection's attributes are locked. - LockedCollectionAttributes, - /// Item's metadata is locked. - LockedItemMetadata, - /// Collection's metadata is locked. - LockedCollectionMetadata, - /// All items have been minted. - MaxSupplyReached, - /// The max supply is locked and can't be changed. - MaxSupplyLocked, - /// The provided max supply is less than the number of items a collection already has. - MaxSupplyTooSmall, - /// The given item ID is unknown. - UnknownItem, - /// Swap doesn't exist. - UnknownSwap, - /// The given item has no metadata set. - MetadataNotFound, - /// The provided attribute can't be found. - AttributeNotFound, - /// Item is not for sale. - NotForSale, - /// The provided bid is too low. - BidTooLow, - /// The item has reached its approval limit. - ReachedApprovalLimit, - /// The deadline has already expired. - DeadlineExpired, - /// The duration provided should be less than or equal to `MaxDeadlineDuration`. - WrongDuration, - /// The method is disabled by system settings. - MethodDisabled, - /// The provided setting can't be set. - WrongSetting, - /// Item's config already exists and should be equal to the provided one. - InconsistentItemConfig, - /// Config for a collection or an item can't be found. - NoConfig, - /// Some roles were not cleared. - RolesNotCleared, - /// Mint has not started yet. - MintNotStarted, - /// Mint has already ended. - MintEnded, - /// The provided Item was already used for claiming. - AlreadyClaimed, - /// The provided data is incorrect. - IncorrectData, - /// The extrinsic was sent by the wrong origin. - WrongOrigin, - /// The provided signature is incorrect. - WrongSignature, - /// The provided metadata might be too long. - IncorrectMetadata, - /// Can't set more attributes per one call. - MaxAttributesLimitReached, - /// The provided namespace isn't supported in this call. - WrongNamespace, - /// Can't delete non-empty collections. - CollectionNotEmpty, - /// The witness data should be provided. - WitnessRequired, -} - -impl TryFrom for Error { - type Error = PopApiError; - - fn try_from(status_code: u32) -> core::result::Result { - use Error::*; - match status_code { - 0 => Ok(NoPermission), - 1 => Ok(UnknownCollection), - 2 => Ok(AlreadyExists), - 3 => Ok(ApprovalExpired), - 4 => Ok(WrongOwner), - 5 => Ok(BadWitness), - 6 => Ok(CollectionIdInUse), - 7 => Ok(ItemsNonTransferable), - 8 => Ok(NotDelegate), - 9 => Ok(WrongDelegate), - 10 => Ok(Unapproved), - 11 => Ok(Unaccepted), - 12 => Ok(ItemLocked), - 13 => Ok(LockedItemAttributes), - 14 => Ok(LockedCollectionAttributes), - 15 => Ok(LockedItemMetadata), - 16 => Ok(LockedCollectionMetadata), - 17 => Ok(MaxSupplyReached), - 18 => Ok(MaxSupplyLocked), - 19 => Ok(MaxSupplyTooSmall), - 20 => Ok(UnknownItem), - 21 => Ok(UnknownSwap), - 22 => Ok(MetadataNotFound), - 23 => Ok(AttributeNotFound), - 24 => Ok(NotForSale), - 25 => Ok(BidTooLow), - 26 => Ok(ReachedApprovalLimit), - 27 => Ok(DeadlineExpired), - 28 => Ok(WrongDuration), - 29 => Ok(MethodDisabled), - 30 => Ok(WrongSetting), - 31 => Ok(InconsistentItemConfig), - 32 => Ok(NoConfig), - 33 => Ok(RolesNotCleared), - 34 => Ok(MintNotStarted), - 35 => Ok(MintEnded), - 36 => Ok(AlreadyClaimed), - 37 => Ok(IncorrectData), - 38 => Ok(WrongOrigin), - 39 => Ok(WrongSignature), - 40 => Ok(IncorrectMetadata), - 41 => Ok(MaxAttributesLimitReached), - 42 => Ok(WrongNamespace), - 43 => Ok(CollectionNotEmpty), - 44 => Ok(WitnessRequired), - _ => Err(UnknownStatusCode(status_code)), - } - } -} - -impl From for Error { - fn from(error: PopApiError) -> Self { - match error { - PopApiError::Nfts(e) => e, - _ => panic!("expected nfts error"), - } - } -} - -// Local implementations of pallet-nfts types -mod types { - use super::*; - use crate::{ - primitives::{CollectionId, ItemId}, - Balance, BlockNumber, - }; - pub use enumflags2::{bitflags, BitFlags}; - use scale::{Decode, EncodeLike, MaxEncodedLen}; - use scale_info::{build::Fields, meta_type, prelude::vec, Path, Type, TypeInfo, TypeParameter}; - - /// Attribute namespaces for non-fungible tokens. - #[derive(Encode)] - pub enum AttributeNamespace { - /// An attribute was set by the pallet. - Pallet, - /// An attribute was set by collection's owner. - CollectionOwner, - /// An attribute was set by item's owner. - ItemOwner, - /// An attribute was set by pre-approved account. - Account(AccountId), - } - - /// Collection's configuration. - #[derive(Encode)] - pub struct CollectionConfig { - /// Collection's settings. - pub settings: CollectionSettings, - /// Collection's max supply. - pub max_supply: Option, - /// Default settings each item will get during the mint. - pub mint_settings: MintSettings, - } - - /// Information about a collection. - #[derive(Decode, Debug, Encode, Eq, PartialEq)] - pub struct CollectionDetails { - /// Collection's owner. - pub owner: AccountId, - /// The total balance deposited by the owner for all the storage data associated with this - /// collection. Used by `destroy`. - pub owner_deposit: Balance, - /// The total number of outstanding items of this collection. - pub items: u32, - /// The total number of outstanding item metadata of this collection. - pub item_metadatas: u32, - /// The total number of outstanding item configs of this collection. - pub item_configs: u32, - /// The total number of attributes for this collection. - pub attributes: u32, - } - - /// Wrapper type for `BitFlags` that implements `Codec`. - pub struct CollectionSettings(pub BitFlags); - - impl_codec_bitflags!(CollectionSettings, u64, CollectionSetting); - - /// Support for up to 64 user-enabled features on a collection. - #[bitflags] - #[repr(u64)] - #[derive(Copy, Clone, Encode, TypeInfo)] - pub enum CollectionSetting { - /// Items in this collection are transferable. - TransferableItems, - /// The metadata of this collection can be modified. - UnlockedMetadata, - /// Attributes of this collection can be modified. - UnlockedAttributes, - /// The supply of this collection can be modified. - UnlockedMaxSupply, - /// When this isn't set then the deposit is required to hold the items of this collection. - DepositRequired, - } - - /// Information concerning the ownership of a single unique item. - #[derive(Decode, Debug, Encode, Eq, PartialEq)] - pub struct ItemDetails { - /// The owner of this item. - pub owner: AccountId, - /// The approved transferrer of this item, if one is set. - pub approvals: BoundedBTreeMap, ApprovalsLimit>, - /// The amount held in the pallet's default account for this item. Free-hold items will - /// have this as zero. - pub deposit: Balance, - } - - /// Support for up to 64 user-enabled features on an item. - #[bitflags] - #[repr(u64)] - #[derive(Copy, Clone, Encode, TypeInfo)] - pub enum ItemSetting { - /// This item is transferable. - Transferable, - /// The metadata of this item can be modified. - UnlockedMetadata, - /// Attributes of this item can be modified. - UnlockedAttributes, - } - - /// Wrapper type for `BitFlags` that implements `Codec`. - pub struct ItemSettings(pub BitFlags); - - impl_codec_bitflags!(ItemSettings, u64, ItemSetting); - - /// Information about the tip. - #[derive(Encode)] - pub struct ItemTip { - /// The collection of the item. - pub(super) collection: CollectionId, - /// An item of which the tip is sent for. - pub(super) item: ItemId, - /// A sender of the tip. - pub(super) receiver: AccountId, - /// An amount the sender is willing to tip. - pub(super) amount: Balance, - } - - /// Holds the information about minting. - #[derive(Encode)] - pub struct MintSettings { - /// Whether anyone can mint or if minters are restricted to some subset. - pub mint_type: MintType, - /// An optional price per mint. - pub price: Option, - /// When the mint starts. - pub start_block: Option, - /// When the mint ends. - pub end_block: Option, - /// Default settings each item will get during the mint. - pub default_item_settings: ItemSettings, - } - - /// Mint type. Can the NFT be created by anyone, or only the creator of the collection, - /// or only by wallets that already hold an NFT from a certain collection? - /// The ownership of a privately minted NFT is still publicly visible. - #[derive(Encode)] - pub enum MintType { - /// Only an `Issuer` could mint items. - Issuer, - /// Anyone could mint items. - Public, - /// Only holders of items in specified collection could mint new items. - HolderOf(CollectionId), - } - - /// Holds the details about the price. - #[derive(Encode)] - pub struct PriceWithDirection { - /// An amount. - pub(super) amount: Balance, - /// A direction (send or receive). - pub(super) direction: PriceDirection, - } - - /// Specifies whether the tokens will be sent or received. - #[derive(Encode)] - pub enum PriceDirection { - /// Tokens will be sent. - Send, - /// Tokens will be received. - Receive, - } - - macro_rules! impl_codec_bitflags { - ($wrapper:ty, $size:ty, $bitflag_enum:ty) => { - impl MaxEncodedLen for $wrapper { - fn max_encoded_len() -> usize { - <$size>::max_encoded_len() - } - } - impl Encode for $wrapper { - fn using_encoded R>(&self, f: F) -> R { - self.0.bits().using_encoded(f) - } - } - impl EncodeLike for $wrapper {} - impl Decode for $wrapper { - fn decode( - input: &mut I, - ) -> core::result::Result { - let field = <$size>::decode(input)?; - Ok(Self(BitFlags::from_bits(field as $size).map_err(|_| "invalid value")?)) - } - } - - impl TypeInfo for $wrapper { - type Identity = Self; - - fn type_info() -> Type { - Type::builder() - .path(Path::new("BitFlags", module_path!())) - .type_params(vec![TypeParameter::new( - "T", - Some(meta_type::<$bitflag_enum>()), - )]) - .composite( - Fields::unnamed() - .field(|f| f.ty::<$size>().type_name(stringify!($bitflag_enum))), - ) - } - } - }; - } - pub(crate) use impl_codec_bitflags; -} diff --git a/primitives/Cargo.toml b/primitives/Cargo.toml index 5cbd6d6c..e7d55ffe 100644 --- a/primitives/Cargo.toml +++ b/primitives/Cargo.toml @@ -1,21 +1,17 @@ [package] name = "pop-primitives" +description = "Primitives crate for Pop" license = "GPL-3.0-only" version = "0.0.0" edition = "2021" [dependencies] -bounded-collections = { version = "0.1", default-features = false } -scale = { package = "parity-scale-codec", version = "3", default-features = false, features = ["derive"] } -scale-info = { version = "2.10", default-features = false, features = ["derive"], optional = true } +codec.workspace = true +scale-info.workspace = true [features] default = ["std"] std = [ - "bounded-collections/std", - "scale/std", + "codec/std", "scale-info/std", -] -assets = [] -cross-chain = [] -nfts = [] +] \ No newline at end of file diff --git a/primitives/README.md b/primitives/README.md new file mode 100644 index 00000000..ded7918a --- /dev/null +++ b/primitives/README.md @@ -0,0 +1 @@ +Reserved crate for pop-primitives. \ No newline at end of file diff --git a/primitives/src/cross_chain.rs b/primitives/src/cross_chain.rs deleted file mode 100644 index 381e6a61..00000000 --- a/primitives/src/cross_chain.rs +++ /dev/null @@ -1,19 +0,0 @@ -use scale::{Decode, Encode, MaxEncodedLen}; - -#[derive(Encode, Decode, Debug, MaxEncodedLen)] -pub enum CrossChainMessage { - Relay(RelayChainMessage), -} - -#[derive(Encode, Decode, Debug, MaxEncodedLen)] -pub enum RelayChainMessage { - // Rococo index: https://github.com/paritytech/polkadot-sdk/blob/629506ce061db76d31d4f7a81f4a497752b27259/polkadot/runtime/rococo/src/lib.rs#L1423 - #[codec(index = 66)] - OnDemand(OnDemand), -} - -#[derive(Encode, Decode, Debug, MaxEncodedLen)] -pub enum OnDemand { - #[codec(index = 1)] - PlaceOrderKeepAlive { max_amount: u128, para_id: u32 }, -} diff --git a/primitives/src/lib.rs b/primitives/src/lib.rs index 376b440d..a51661ea 100644 --- a/primitives/src/lib.rs +++ b/primitives/src/lib.rs @@ -1,37 +1,13 @@ #![cfg_attr(not(feature = "std"), no_std, no_main)] -pub use bounded_collections::{BoundedBTreeMap, BoundedBTreeSet, BoundedVec}; -use scale::{Decode, Encode, MaxEncodedLen}; +use codec::{Decode, Encode}; #[cfg(feature = "std")] use scale_info::TypeInfo; pub use v0::error; -#[cfg(feature = "cross-chain")] -pub mod cross_chain; -pub mod storage_keys; - -/// An opaque 32-byte cryptographic identifier. -#[derive(Encode, Decode, Debug, MaxEncodedLen, Eq, PartialEq)] -#[cfg_attr(feature = "std", derive(TypeInfo))] -pub struct AccountId(pub [u8; 32]); - /// Identifier for the class of asset. pub type AssetId = u32; -#[cfg(feature = "nfts")] -pub mod nfts { - use bounded_collections::ConstU32; - - /// Id used for identifying non-fungible collections. - pub type CollectionId = u32; - /// Id used for identifying non-fungible items. - pub type ItemId = u32; - /// The maximum length of an attribute key. - pub type KeyLimit = ConstU32<64>; - /// The maximum approvals an item could have. - pub type ApprovalsLimit = ConstU32<20>; -} - pub mod v0 { use super::*; pub mod error { @@ -102,7 +78,7 @@ pub mod v0 { } /// Description of what went wrong when trying to complete an operation on a token. - #[derive(Encode, Decode, Clone, Debug, MaxEncodedLen, Eq, PartialEq, Ord, PartialOrd)] + #[derive(Encode, Decode, Debug, Eq, PartialEq)] #[cfg_attr(feature = "std", derive(TypeInfo))] pub enum TokenError { /// Funds are unavailable. diff --git a/primitives/src/storage_keys.rs b/primitives/src/storage_keys.rs deleted file mode 100644 index e42dbca0..00000000 --- a/primitives/src/storage_keys.rs +++ /dev/null @@ -1,56 +0,0 @@ -#[cfg(feature = "nfts")] -use super::nfts::*; -use super::*; - -#[derive(Encode, Decode, Debug, MaxEncodedLen)] -pub enum RuntimeStateKeys { - #[cfg(feature = "cross-chain")] - #[codec(index = 1)] - ParachainSystem(ParachainSystemKeys), - #[cfg(feature = "nfts")] - #[codec(index = 50)] - Nfts(NftsKeys), - #[cfg(feature = "assets")] - #[codec(index = 52)] - Assets(AssetsKeys), -} - -#[cfg(feature = "cross-chain")] -#[derive(Encode, Decode, Debug, MaxEncodedLen)] -pub enum ParachainSystemKeys { - /// Get the last relay chain block number seen by the parachain. - LastRelayChainBlockNumber, -} - -// https://github.com/paritytech/polkadot-sdk/blob/master/substrate/frame/nfts/src/impl_nonfungibles.rs -#[cfg(feature = "nfts")] -#[derive(Encode, Decode, Debug, MaxEncodedLen)] -pub enum NftsKeys { - // Get the details of a collection. - Collection(CollectionId), - /// Get the owner of the collection, if the collection exists. - CollectionOwner(CollectionId), - // Get the details of an item. - Item(CollectionId, ItemId), - /// Get the owner of the item, if the item exists. - Owner(CollectionId, ItemId), - /// Get the attribute value of `item` of `collection` corresponding to `key`. - Attribute(CollectionId, ItemId, BoundedVec), - /// Get the system attribute value of `item` of `collection` corresponding to `key` - SystemAttribute(CollectionId, Option, BoundedVec), - /// Get the attribute value of `item` of `collection` corresponding to `key`. - CollectionAttribute(CollectionId, BoundedVec), -} - -/// The required input for state queries in pallet assets. -#[cfg(feature = "assets")] -#[derive(Encode, Decode, Debug, MaxEncodedLen)] -pub enum AssetsKeys { - TotalSupply(AssetId), - BalanceOf(AssetId, AccountId), - Allowance(AssetId, AccountId, AccountId), - TokenName(AssetId), - TokenSymbol(AssetId), - TokenDecimals(AssetId), - // AssetExists(AssetId), -} diff --git a/runtime/devnet/Cargo.toml b/runtime/devnet/Cargo.toml index 70e6e9c9..455a86fd 100644 --- a/runtime/devnet/Cargo.toml +++ b/runtime/devnet/Cargo.toml @@ -22,8 +22,9 @@ scale-info.workspace = true smallvec.workspace = true # Local -pop-primitives = { workspace = true, features = ["assets", "cross-chain", "nfts"] } -pop-runtime-common = { workspace = true, default-features = false } +pop-primitives.workspace = true +pop-runtime-common.workspace = true +pallet-api.workspace = true # Substrate frame-benchmarking.workspace = true @@ -89,7 +90,6 @@ parachain-info.workspace = true [dev-dependencies] env_logger = "0.11.2" -enumflags2 = "0.7.9" hex = "0.4.3" rand = "0.8.5" @@ -119,6 +119,7 @@ std = [ "pallet-balances/std", "pallet-collator-selection/std", "pallet-contracts/std", + "pallet-api/std", "pallet-message-queue/std", "pallet-multisig/std", "pallet-nft-fractionalization/std", @@ -169,6 +170,7 @@ runtime-benchmarks = [ "frame-system-benchmarking/runtime-benchmarks", "frame-system/runtime-benchmarks", "pallet-assets/runtime-benchmarks", + "pallet-api/runtime-benchmarks", "pallet-balances/runtime-benchmarks", "pallet-collator-selection/runtime-benchmarks", "pallet-contracts/runtime-benchmarks", diff --git a/runtime/devnet/src/config/api.rs b/runtime/devnet/src/config/api.rs new file mode 100644 index 00000000..ae179e4a --- /dev/null +++ b/runtime/devnet/src/config/api.rs @@ -0,0 +1,34 @@ +use crate::{config::assets::TrustBackedAssetsInstance, fungibles, Runtime, RuntimeCall}; +use codec::{Decode, Encode, MaxEncodedLen}; +use frame_support::traits::Contains; + +/// A query of runtime state. +#[derive(Encode, Decode, Debug, MaxEncodedLen)] +#[repr(u8)] +pub enum RuntimeRead { + /// Fungible token queries. + #[codec(index = 150)] + Fungibles(fungibles::Read), +} + +impl fungibles::Config for Runtime { + type AssetsInstance = TrustBackedAssetsInstance; + type WeightInfo = fungibles::weights::SubstrateWeight; +} + +/// A type to identify allowed calls to the Runtime from contracts. Used by Pop API +pub struct AllowedApiCalls; + +impl Contains for AllowedApiCalls { + fn contains(c: &RuntimeCall) -> bool { + use fungibles::Call as FungiblesCall; + matches!( + c, + RuntimeCall::Fungibles( + FungiblesCall::transfer { .. } + | FungiblesCall::approve { .. } + | FungiblesCall::increase_allowance { .. } + ) + ) + } +} diff --git a/runtime/devnet/src/config/assets.rs b/runtime/devnet/src/config/assets.rs index 2c8ea952..78aed8b5 100644 --- a/runtime/devnet/src/config/assets.rs +++ b/runtime/devnet/src/config/assets.rs @@ -1,7 +1,3 @@ -use crate::{ - deposit, AccountId, Assets, Balance, Balances, BlockNumber, Nfts, Runtime, RuntimeEvent, - RuntimeHoldReason, DAYS, EXISTENTIAL_DEPOSIT, UNIT, -}; use frame_support::{ parameter_types, traits::{AsEnsureOriginWithArg, ConstU32}, @@ -12,6 +8,11 @@ use pallet_nfts::PalletFeatures; use parachains_common::{AssetIdForTrustBackedAssets, CollectionId, ItemId, Signature}; use sp_runtime::traits::Verify; +use crate::{ + deposit, AccountId, Assets, Balance, Balances, BlockNumber, Nfts, Runtime, RuntimeEvent, + RuntimeHoldReason, DAYS, EXISTENTIAL_DEPOSIT, UNIT, +}; + /// We allow root to execute privileged asset operations. pub type AssetsForceOrigin = EnsureRoot; diff --git a/runtime/devnet/src/config/mod.rs b/runtime/devnet/src/config/mod.rs index e0aaa3a1..f62ffa76 100644 --- a/runtime/devnet/src/config/mod.rs +++ b/runtime/devnet/src/config/mod.rs @@ -1,3 +1,4 @@ +pub(crate) mod api; pub mod assets; mod contracts; mod proxy; diff --git a/runtime/devnet/src/extensions/mod.rs b/runtime/devnet/src/extensions/mod.rs index d2bd63e7..3aed89df 100644 --- a/runtime/devnet/src/extensions/mod.rs +++ b/runtime/devnet/src/extensions/mod.rs @@ -1,61 +1,42 @@ -use codec::{Compact, Decode, Encode}; -use cumulus_pallet_parachain_system::RelaychainDataProvider; -use frame_support::traits::{Contains, OriginTrait}; +mod v0; + +use crate::{ + config::{ + api::{AllowedApiCalls, RuntimeRead}, + assets::TrustBackedAssetsInstance, + }, + fungibles::{ + self, + Read::{self, *}, + }, + AccountId, RuntimeCall, RuntimeOrigin, +}; +use codec::{Decode, Encode}; use frame_support::{ dispatch::{GetDispatchInfo, RawOrigin}, pallet_prelude::*, - traits::{ - fungibles::{approvals::Inspect as ApprovalInspect, metadata::Inspect as MetadataInspect}, - nonfungibles_v2::Inspect as NonFungiblesInspect, - }, + traits::{Contains, OriginTrait}, }; use pallet_contracts::chain_extension::{ BufInBufOutState, ChainExtension, Environment, Ext, InitState, RetVal, }; +use pop_primitives::AssetId; use sp_core::crypto::UncheckedFrom; -use sp_runtime::{ - traits::{BlockNumberProvider, Dispatchable}, - DispatchError, MultiAddress, -}; -use sp_std::{boxed::Box, vec::Vec}; -use xcm::{ - latest::{prelude::*, OriginKind::SovereignAccount}, - VersionedXcm, -}; - -use crate::{ - config::assets::TrustBackedAssetsInstance, AccountId, AllowedApiCalls, Balance, Runtime, - RuntimeCall, RuntimeOrigin, UNIT, -}; -use pop_primitives::{ - cross_chain::CrossChainMessage, - nfts::{CollectionId, ItemId}, - storage_keys::{ - AssetsKeys::{self, *}, - NftsKeys, ParachainSystemKeys, RuntimeStateKeys, - }, - AssetId, -}; - -mod v0; +use sp_runtime::{traits::Dispatchable, DispatchError}; +use sp_std::vec::Vec; const LOG_TARGET: &str = "pop-api::extension"; -// Versions: -const V0: u8 = 0; type ContractSchedule = ::Schedule; #[derive(Default)] pub struct PopApiExtension; -// TODO: check removal or simplification of trait bounds. impl ChainExtension for PopApiExtension where T: pallet_contracts::Config - + pallet_xcm::Config + pallet_assets::Config - + pallet_nfts::Config - + cumulus_pallet_parachain_system::Config + + fungibles::Config + frame_system::Config< RuntimeOrigin = RuntimeOrigin, AccountId = AccountId, @@ -102,8 +83,6 @@ where FuncId::ReadState => { read_state::(&mut env, version, pallet_index, call_index, params) }, - // TODO - FuncId::SendXcm => send_xcm::(&mut env), } }, Err(e) => Err(e), @@ -121,7 +100,7 @@ fn dispatch( version: u8, pallet_index: u8, call_index: u8, - params: Vec, + mut params: Vec, ) -> Result<(), DispatchError> where T: frame_system::Config, @@ -129,10 +108,19 @@ where E: Ext, { const LOG_PREFIX: &str = " dispatch |"; - let call = construct_call(version, pallet_index, call_index, params)?; + + // Prefix params with version, pallet, index to simplify decoding. + params.insert(0, version); + params.insert(1, pallet_index); + params.insert(2, call_index); + let call = ::decode(&mut ¶ms[..]) + .map_err(|_| DispatchError::Other("DecodingFailed"))?; + // Contract is the origin by default. let origin: RuntimeOrigin = RawOrigin::Signed(env.ext().address().clone()).into(); - dispatch_call::(env, call, origin, LOG_PREFIX) + match call { + VersionedDispatch::V0(call) => dispatch_call::(env, call, origin, LOG_PREFIX), + } } fn dispatch_call( @@ -165,79 +153,33 @@ where } } -fn construct_call( - version: u8, - pallet_index: u8, - call_index: u8, - params: Vec, -) -> Result { - match pallet_index { - index if index == super::Assets::index() as u8 => { - let call = versioned_construct_assets_call(version, call_index, params)?; - Ok(RuntimeCall::Assets(call)) - }, - _ => Err(DispatchError::Other("UnknownFunctionId")), - } -} - -fn construct_key( - version: u8, - pallet_index: u8, - call_index: u8, - params: Vec, -) -> Result { - match pallet_index { - 52 => { - let key = versioned_construct_assets_key(version, call_index, params)?; - Ok(RuntimeStateKeys::Assets(key)) - }, - _ => Err(DispatchError::Other("UnknownFunctionId")), - } -} - -fn versioned_construct_assets_call( - version: u8, - call_index: u8, - params: Vec, -) -> Result, DispatchError> { - match version { - V0 => v0::assets::construct_assets_call(call_index, params), - _ => Err(DispatchError::Other("UnknownFunctionId")), - } -} - -fn versioned_construct_assets_key( - version: u8, - call_index: u8, - params: Vec, -) -> Result { - match version { - V0 => v0::assets::construct_assets_key(call_index, params), - _ => Err(DispatchError::Other("UnknownFunctionId")), - } -} - fn read_state( env: &mut Environment, version: u8, pallet_index: u8, call_index: u8, - params: Vec, + mut params: Vec, ) -> Result<(), DispatchError> where T: pallet_contracts::Config + pallet_assets::Config - + pallet_nfts::Config - + cumulus_pallet_parachain_system::Config + + fungibles::Config + frame_system::Config, E: Ext, { const LOG_PREFIX: &str = " read_state |"; - let key = construct_key(version, pallet_index, call_index, params)?; + + // Prefix params with version, pallet, index to simplify decoding. + params.insert(0, version); + params.insert(1, pallet_index); + params.insert(2, call_index); + let key = >::decode(&mut ¶ms[..]) + .map_err(|_| DispatchError::Other("DecodingFailed"))?; + let result = match key { - RuntimeStateKeys::Nfts(key) => read_nfts_state::(key, env), - RuntimeStateKeys::ParachainSystem(key) => read_parachain_system_state::(key, env), - RuntimeStateKeys::Assets(key) => read_assets_state::(key, env), + VersionedStateRead::V0(key) => match key { + RuntimeRead::Fungibles(key) => read_fungibles_state::(key, env), + }, }? .encode(); log::trace!( @@ -247,48 +189,20 @@ where env.write(&result, false, None) } -fn send_xcm(env: &mut Environment) -> Result<(), DispatchError> -where - T: pallet_contracts::Config - + frame_system::Config< - RuntimeOrigin = RuntimeOrigin, - AccountId = AccountId, - RuntimeCall = RuntimeCall, - >, - E: Ext, -{ - const LOG_PREFIX: &str = " send_xcm |"; - // Read the input as CrossChainMessage. - let xc_call: CrossChainMessage = env.read_as::()?; - // Determine the call to dispatch. - let (dest, message) = match xc_call { - CrossChainMessage::Relay(message) => { - let dest = Location::parent().into_versioned(); - let assets: Asset = (Here, 10 * UNIT).into(); - let beneficiary: Location = - AccountId32 { id: (env.ext().address().clone()).into(), network: None }.into(); - let message = Xcm::builder() - .withdraw_asset(assets.clone().into()) - .buy_execution(assets.clone(), Unlimited) - .transact( - SovereignAccount, - Weight::from_parts(250_000_000, 10_000), - message.encode().into(), - ) - .refund_surplus() - .deposit_asset(assets.into(), beneficiary) - .build(); - (dest, message) - }, - }; - // TODO: revisit to replace with signed contract origin - let origin: RuntimeOrigin = RawOrigin::Root.into(); - // Generate runtime call to dispatch. - let call = RuntimeCall::PolkadotXcm(pallet_xcm::Call::send { - dest: Box::new(dest), - message: Box::new(VersionedXcm::V4(message)), - }); - dispatch_call::(env, call, origin, LOG_PREFIX) +/// Wrapper to enable versioning of runtime state reads. +#[derive(Decode, Debug)] +enum VersionedStateRead { + /// Version zero of state reads. + #[codec(index = 0)] + V0(RuntimeRead), +} + +/// Wrapper to enable versioning of runtime calls. +#[derive(Decode, Debug)] +enum VersionedDispatch { + /// Version zero of dispatch calls. + #[codec(index = 0)] + V0(RuntimeCall), } // Converts a `DispatchError` to a `u32` status code based on the version of the API the contract uses. @@ -331,7 +245,7 @@ pub(crate) fn convert_to_status_code(error: DispatchError, version: u8) -> u32 { // - Represents the second level of nesting in `DOUBLE_NESTED_ERRORS`. // - Byte 3: // - Unused or represents further nested information. - 0 => v0::error::handle_unknown_error(&mut encoded_error), + 0 => v0::handle_unknown_error(&mut encoded_error), _ => encoded_error = [254, 0, 0, 0], } u32::from_le_bytes(encoded_error) @@ -350,7 +264,6 @@ pub(crate) fn convert_to_status_code(error: DispatchError, version: u8) -> u32 { pub enum FuncId { Dispatch, ReadState, - SendXcm, } impl TryFrom for FuncId { @@ -364,7 +277,6 @@ impl TryFrom for FuncId { let id = match func_id { 0 => Self::Dispatch, 1 => Self::ReadState, - 2 => Self::SendXcm, _ => { return Err(DispatchError::Other("UnknownFuncId")); }, @@ -373,122 +285,27 @@ impl TryFrom for FuncId { } } -fn read_parachain_system_state( - key: ParachainSystemKeys, - env: &mut Environment, -) -> Result, DispatchError> -where - T: pallet_contracts::Config + cumulus_pallet_parachain_system::Config, - E: Ext, -{ - match key { - ParachainSystemKeys::LastRelayChainBlockNumber => { - env.charge_weight(T::DbWeight::get().reads(1_u64))?; - Ok(RelaychainDataProvider::::current_block_number().encode()) - }, - } -} - -fn read_nfts_state( - key: NftsKeys, - env: &mut Environment, -) -> Result, DispatchError> -where - T: pallet_contracts::Config + pallet_nfts::Config, - E: Ext, -{ - match key { - NftsKeys::Collection(collection) => { - env.charge_weight(T::DbWeight::get().reads(1_u64))?; - Ok(pallet_nfts::Collection::::get(collection).encode()) - }, - NftsKeys::CollectionOwner(collection) => { - env.charge_weight(T::DbWeight::get().reads(1_u64))?; - Ok(pallet_nfts::Pallet::::collection_owner(collection).encode()) - }, - NftsKeys::Item(collection, item) => { - env.charge_weight(T::DbWeight::get().reads(1_u64))?; - Ok(pallet_nfts::Item::::get(collection, item).encode()) - }, - NftsKeys::Owner(collection, item) => { - env.charge_weight(T::DbWeight::get().reads(1_u64))?; - Ok(pallet_nfts::Pallet::::owner(collection, item).encode()) - }, - NftsKeys::Attribute(collection, item, key) => { - env.charge_weight(T::DbWeight::get().reads(1_u64))?; - Ok(pallet_nfts::Pallet::::attribute(&collection, &item, &key).encode()) - }, - // NftsKeys::CustomAttribute(account, collection, item, key) => { - // env.charge_weight(T::DbWeight::get().reads(1_u64))?; - // Ok(pallet_nfts::Pallet::::custom_attribute(&account, &collection, &item, &key) - // .encode()) - // }, - NftsKeys::SystemAttribute(collection, item, key) => { - env.charge_weight(T::DbWeight::get().reads(1_u64))?; - Ok(pallet_nfts::Pallet::::system_attribute(&collection, item.as_ref(), &key) - .encode()) - }, - NftsKeys::CollectionAttribute(collection, key) => { - env.charge_weight(T::DbWeight::get().reads(1_u64))?; - Ok(pallet_nfts::Pallet::::collection_attribute(&collection, &key).encode()) - }, - } -} - -fn read_assets_state( - key: AssetsKeys, +fn read_fungibles_state( + key: Read, env: &mut Environment, ) -> Result, DispatchError> where T: pallet_contracts::Config - + pallet_assets::Config, + + pallet_assets::Config + + fungibles::Config, E: Ext, T: frame_system::Config, { + env.charge_weight(T::DbWeight::get().reads(1_u64))?; match key { - TotalSupply(id) => { - env.charge_weight(T::DbWeight::get().reads(1_u64))?; - Ok(pallet_assets::Pallet::::total_supply(id).encode()) - }, - BalanceOf(id, owner) => { - env.charge_weight(T::DbWeight::get().reads(1_u64))?; - Ok(pallet_assets::Pallet::::balance(id, &owner.0.into()) - .encode()) - }, - Allowance(id, owner, spender) => { - env.charge_weight(T::DbWeight::get().reads(1_u64))?; - Ok(pallet_assets::Pallet::::allowance( - id, - &owner.0.into(), - &spender.0.into(), - ) - .encode()) - }, - TokenName(id) => { - env.charge_weight(T::DbWeight::get().reads(1_u64))?; - Ok( as MetadataInspect< - AccountId, - >>::name(id) - .encode()) + TotalSupply(id) => Ok(fungibles::Pallet::::total_supply(id).encode()), + BalanceOf { id, owner } => Ok(fungibles::Pallet::::balance_of(id, &owner).encode()), + Allowance { id, owner, spender } => { + Ok(fungibles::Pallet::::allowance(id, &owner, &spender).encode()) }, - TokenSymbol(id) => { - env.charge_weight(T::DbWeight::get().reads(1_u64))?; - Ok( as MetadataInspect< - AccountId, - >>::symbol(id) - .encode()) - }, - TokenDecimals(id) => { - env.charge_weight(T::DbWeight::get().reads(1_u64))?; - Ok( as MetadataInspect< - AccountId, - >>::decimals(id) - .encode()) - }, - // AssetsKeys::AssetExists(id) => { - // env.charge_weight(T::DbWeight::get().reads(1_u64))?; - // Ok(pallet_assets::Pallet::::asset_exists(id).encode()) - // }, + TokenName(id) => Ok(fungibles::Pallet::::token_name(id).encode()), + TokenSymbol(id) => Ok(fungibles::Pallet::::token_symbol(id).encode()), + TokenDecimals(id) => Ok(fungibles::Pallet::::token_decimals(id).encode()), } } @@ -497,6 +314,7 @@ mod tests { use super::*; use crate::{Assets, Runtime, System}; use sp_runtime::BuildStorage; + // Test ensuring `func_id()` and `ext_id()` work as expected, i.e. extracting the first two // bytes and the last two bytes, respectively, from a 4 byte array. #[test] @@ -673,501 +491,3 @@ mod tests { }); } } -// use enumflags2::BitFlags; -// use pallet_nfts::{CollectionConfig, CollectionSetting, CollectionSettings, MintSettings}; -// use parachains_common::CollectionId; -// { -// // NFT helper functions -// fn collection_config_from_disabled_settings( -// settings: BitFlags, -// ) -> CollectionConfig { -// CollectionConfig { -// settings: CollectionSettings::from_disabled(settings), -// max_supply: None, -// mint_settings: MintSettings::default(), -// } -// } -// -// fn default_collection_config() -> CollectionConfig { -// collection_config_from_disabled_settings(CollectionSetting::DepositRequired.into()) -// } -// -// #[test] -// #[ignore] -// fn dispatch_balance_transfer_from_contract_works() { -// new_test_ext().execute_with(|| { -// let _ = env_logger::try_init(); -// -// let (wasm_binary, _) = load_wasm_module::( -// "../../pop-api/examples/balance-transfer/target/ink/balance_transfer.wasm", -// ) -// .unwrap(); -// -// let init_value = 100 * UNIT; -// -// let result = Contracts::bare_instantiate( -// ALICE, -// init_value, -// GAS_LIMIT, -// None, -// Code::Upload(wasm_binary), -// function_selector("new"), -// vec![], -// DEBUG_OUTPUT, -// pallet_contracts::CollectEvents::Skip, -// ) -// .result -// .unwrap(); -// -// assert!(!result.result.did_revert(), "deploying contract reverted {:?}", result); -// -// let addr = result.account_id; -// -// let function = function_selector("transfer_through_runtime"); -// let value_to_send: u128 = 10 * UNIT; -// let params = [function, BOB.encode(), value_to_send.encode()].concat(); -// -// let bob_balance_before = Balances::free_balance(&BOB); -// assert_eq!(bob_balance_before, INITIAL_AMOUNT); -// -// let result = Contracts::bare_call( -// ALICE, -// addr.clone(), -// 0, -// Weight::from_parts(100_000_000_000, 3 * 1024 * 1024), -// None, -// params, -// DEBUG_OUTPUT, -// pallet_contracts::CollectEvents::Skip, -// pallet_contracts::Determinism::Enforced, -// ); -// -// if DEBUG_OUTPUT == pallet_contracts::DebugInfo::UnsafeDebug { -// log::debug!( -// "Contract debug buffer - {:?}", -// String::from_utf8(result.debug_message.clone()) -// ); -// log::debug!("result: {:?}", result); -// } -// -// // check for revert -// assert!(!result.result.unwrap().did_revert(), "Contract reverted!"); -// -// let bob_balance_after = Balances::free_balance(&BOB); -// assert_eq!(bob_balance_before + value_to_send, bob_balance_after); -// }); -// } -// -// // Create a test for tesing create_nft_collection -// #[test] -// #[ignore] -// fn dispatch_nfts_create_nft_collection() { -// new_test_ext().execute_with(|| { -// let _ = env_logger::try_init(); -// -// let (wasm_binary, _) = load_wasm_module::( -// "../../pop-api/examples/nfts/target/ink/pop_api_nft_example.wasm", -// ) -// .unwrap(); -// -// let init_value = 100 * UNIT; -// -// let result = Contracts::bare_instantiate( -// ALICE, -// init_value, -// GAS_LIMIT, -// None, -// Code::Upload(wasm_binary), -// function_selector("new"), -// vec![], -// DEBUG_OUTPUT, -// pallet_contracts::CollectEvents::Skip, -// ) -// .result -// .unwrap(); -// -// assert!(!result.result.did_revert(), "deploying contract reverted {:?}", result); -// -// let addr = result.account_id; -// -// let function = function_selector("create_nft_collection"); -// -// let params = [function].concat(); -// -// let result = Contracts::bare_call( -// ALICE, -// addr.clone(), -// 0, -// Weight::from_parts(100_000_000_000, 3 * 1024 * 1024), -// None, -// params, -// DEBUG_OUTPUT, -// pallet_contracts::CollectEvents::Skip, -// pallet_contracts::Determinism::Enforced, -// ); -// -// if DEBUG_OUTPUT == pallet_contracts::DebugInfo::UnsafeDebug { -// log::debug!( -// "Contract debug buffer - {:?}", -// String::from_utf8(result.debug_message.clone()) -// ); -// log::debug!("result: {:?}", result); -// } -// -// // check that the nft collection was created -// assert_eq!(Nfts::collection_owner(0), Some(addr.clone().into())); -// -// // test reading the collection -// let function = function_selector("read_collection"); -// -// let params = [function, 0.encode()].concat(); -// -// let result = Contracts::bare_call( -// ALICE, -// addr.clone(), -// 0, -// Weight::from_parts(100_000_000_000, 3 * 1024 * 1024), -// None, -// params, -// DEBUG_OUTPUT, -// pallet_contracts::CollectEvents::Skip, -// pallet_contracts::Determinism::Enforced, -// ); -// -// if DEBUG_OUTPUT == pallet_contracts::DebugInfo::UnsafeDebug { -// log::debug!( -// "Contract debug buffer - {:?}", -// String::from_utf8(result.debug_message.clone()) -// ); -// log::debug!("result: {:?}", result); -// } -// -// // assert that the collection was read successfully -// assert_eq!(result.result.clone().unwrap().data, vec![1, 1]); -// }); -// } -// -// #[test] -// #[ignore] -// fn dispatch_nfts_mint_from_contract_works() { -// new_test_ext().execute_with(|| { -// let _ = env_logger::try_init(); -// -// let (wasm_binary, _) = -// load_wasm_module::("../../pop-api/examples/nfts/target/ink/nfts.wasm") -// .unwrap(); -// -// let init_value = 100; -// -// let result = Contracts::bare_instantiate( -// ALICE, -// init_value, -// GAS_LIMIT, -// None, -// Code::Upload(wasm_binary), -// function_selector("new"), -// vec![], -// DEBUG_OUTPUT, -// pallet_contracts::CollectEvents::Skip, -// ) -// .result -// .unwrap(); -// -// assert!(!result.result.did_revert(), "deploying contract reverted {:?}", result); -// -// let addr = result.account_id; -// -// let collection_id: u32 = 0; -// let item_id: u32 = 1; -// -// // create nft collection with contract as owner -// assert_eq!( -// Nfts::force_create( -// RuntimeOrigin::root(), -// addr.clone().into(), -// default_collection_config() -// ), -// Ok(()) -// ); -// -// assert_eq!(Nfts::collection_owner(collection_id), Some(addr.clone().into())); -// // assert that the item does not exist yet -// assert_eq!(Nfts::owner(collection_id, item_id), None); -// -// let function = function_selector("mint_through_runtime"); -// -// let params = -// [function, collection_id.encode(), item_id.encode(), BOB.encode()].concat(); -// -// let result = Contracts::bare_call( -// ALICE, -// addr.clone(), -// 0, -// Weight::from_parts(100_000_000_000, 3 * 1024 * 1024), -// None, -// params, -// DEBUG_OUTPUT, -// pallet_contracts::CollectEvents::Skip, -// pallet_contracts::Determinism::Enforced, -// ); -// -// if DEBUG_OUTPUT == pallet_contracts::DebugInfo::UnsafeDebug { -// log::debug!( -// "Contract debug buffer - {:?}", -// String::from_utf8(result.debug_message.clone()) -// ); -// log::debug!("result: {:?}", result); -// } -// -// // check for revert -// assert!(!result.result.unwrap().did_revert(), "Contract reverted!"); -// -// assert_eq!(Nfts::owner(collection_id, item_id), Some(BOB.into())); -// }); -// } -// -// #[test] -// #[ignore] -// fn nfts_mint_surfaces_error() { -// new_test_ext().execute_with(|| { -// let _ = env_logger::try_init(); -// -// let (wasm_binary, _) = -// load_wasm_module::("../../pop-api/examples/nfts/target/ink/nfts.wasm") -// .unwrap(); -// -// let init_value = 100; -// -// let result = Contracts::bare_instantiate( -// ALICE, -// init_value, -// GAS_LIMIT, -// None, -// Code::Upload(wasm_binary), -// function_selector("new"), -// vec![], -// DEBUG_OUTPUT, -// pallet_contracts::CollectEvents::Skip, -// ) -// .result -// .unwrap(); -// -// assert!(!result.result.did_revert(), "deploying contract reverted {:?}", result); -// -// let addr = result.account_id; -// -// let collection_id: u32 = 0; -// let item_id: u32 = 1; -// -// let function = function_selector("mint_through_runtime"); -// -// let params = -// [function, collection_id.encode(), item_id.encode(), BOB.encode()].concat(); -// -// let result = Contracts::bare_call( -// ALICE, -// addr.clone(), -// 0, -// Weight::from_parts(100_000_000_000, 3 * 1024 * 1024), -// None, -// params, -// DEBUG_OUTPUT, -// pallet_contracts::CollectEvents::Skip, -// pallet_contracts::Determinism::Enforced, -// ); -// -// if DEBUG_OUTPUT == pallet_contracts::DebugInfo::UnsafeDebug { -// log::debug!( -// "Contract debug buffer - {:?}", -// String::from_utf8(result.debug_message.clone()) -// ); -// log::debug!("result: {:?}", result); -// } -// -// // check for revert with expected error -// let result = result.result.unwrap(); -// assert!(result.did_revert()); -// }); -// } -// -// #[test] -// #[ignore] -// fn reading_last_relay_chain_block_number_works() { -// new_test_ext().execute_with(|| { -// let _ = env_logger::try_init(); -// -// let (wasm_binary, _) = load_wasm_module::( -// "../../pop-api/examples/read-runtime-state/target/ink/read_relay_blocknumber.wasm", -// ) -// .unwrap(); -// -// let init_value = 100; -// -// let contract = Contracts::bare_instantiate( -// ALICE, -// init_value, -// GAS_LIMIT, -// None, -// Code::Upload(wasm_binary), -// function_selector("new"), -// vec![], -// DEBUG_OUTPUT, -// pallet_contracts::CollectEvents::Skip, -// ) -// .result -// .unwrap(); -// -// assert!(!contract.result.did_revert(), "deploying contract reverted {:?}", contract); -// -// let addr = contract.account_id; -// -// let function = function_selector("read_relay_block_number"); -// let params = [function].concat(); -// -// let result = Contracts::bare_call( -// ALICE, -// addr.clone(), -// 0, -// Weight::from_parts(100_000_000_000, 3 * 1024 * 1024), -// None, -// params, -// DEBUG_OUTPUT, -// pallet_contracts::CollectEvents::UnsafeCollect, -// pallet_contracts::Determinism::Relaxed, -// ); -// -// if DEBUG_OUTPUT == pallet_contracts::DebugInfo::UnsafeDebug { -// log::debug!( -// "Contract debug buffer - {:?}", -// String::from_utf8(result.debug_message.clone()) -// ); -// log::debug!("result: {:?}", result); -// } -// -// // check for revert -// assert!(!result.result.unwrap().did_revert(), "Contract reverted!"); -// }); -// } -// -// #[test] -// #[ignore] -// fn place_spot_order_from_contract_works() { -// new_test_ext().execute_with(|| { -// let _ = env_logger::try_init(); -// -// let (wasm_binary, _) = load_wasm_module::( -// "../../pop-api/examples/place-spot-order/target/ink/spot_order.wasm", -// ) -// .unwrap(); -// -// let init_value = 100 * UNIT; -// -// let result = Contracts::bare_instantiate( -// ALICE, -// init_value, -// GAS_LIMIT, -// None, -// Code::Upload(wasm_binary), -// function_selector("new"), -// vec![], -// DEBUG_OUTPUT, -// pallet_contracts::CollectEvents::Skip, -// ) -// .result -// .unwrap(); -// -// assert!(!result.result.did_revert(), "deploying contract reverted {:?}", result); -// -// let addr = result.account_id; -// -// let function = function_selector("place_spot_order"); -// -// let max_amount = 1 * UNIT; -// let para_id = 2000; -// -// let params = [function, max_amount.encode(), para_id.encode()].concat(); -// -// let result = Contracts::bare_call( -// ALICE, -// addr.clone(), -// 0, -// Weight::from_parts(100_000_000_000, 3 * 1024 * 1024), -// None, -// params, -// DEBUG_OUTPUT, -// pallet_contracts::CollectEvents::Skip, -// pallet_contracts::Determinism::Enforced, -// ); -// -// if DEBUG_OUTPUT == pallet_contracts::DebugInfo::UnsafeDebug { -// log::debug!( -// "Contract debug buffer - {:?}", -// String::from_utf8(result.debug_message.clone()) -// ); -// log::debug!("result: {:?}", result); -// } -// -// // check for revert -// assert!(!result.result.unwrap().did_revert(), "Contract reverted!"); -// }); -// } -// -// #[test] -// #[ignore] -// fn allow_call_filter_blocks_call() { -// new_test_ext().execute_with(|| { -// let _ = env_logger::try_init(); -// -// let (wasm_binary, _) = load_wasm_module::( -// "../../tests/contracts/filtered-call/target/ink/pop_api_filtered_call.wasm", -// ) -// .unwrap(); -// -// let init_value = 100 * UNIT; -// -// let result = Contracts::bare_instantiate( -// ALICE, -// init_value, -// GAS_LIMIT, -// None, -// Code::Upload(wasm_binary), -// function_selector("new"), -// vec![], -// DEBUG_OUTPUT, -// pallet_contracts::CollectEvents::Skip, -// ) -// .result -// .unwrap(); -// -// assert!(!result.result.did_revert(), "deploying contract reverted {:?}", result); -// -// let addr = result.account_id; -// -// let function = function_selector("get_filtered"); -// let params = [function].concat(); -// -// let result = Contracts::bare_call( -// ALICE, -// addr.clone(), -// 0, -// Weight::from_parts(100_000_000_000, 3 * 1024 * 1024), -// None, -// params, -// DEBUG_OUTPUT, -// pallet_contracts::CollectEvents::Skip, -// pallet_contracts::Determinism::Enforced, -// ); -// -// if DEBUG_OUTPUT == pallet_contracts::DebugInfo::UnsafeDebug { -// log::debug!( -// "Contract debug buffer - {:?}", -// String::from_utf8(result.debug_message.clone()) -// ); -// log::debug!("filtered result: {:?}", result); -// } -// -// // check for revert -// assert!(!result.result.unwrap().did_revert(), "Contract reverted!"); -// }); -// } -// } diff --git a/runtime/devnet/src/extensions/v0/error.rs b/runtime/devnet/src/extensions/v0.rs similarity index 100% rename from runtime/devnet/src/extensions/v0/error.rs rename to runtime/devnet/src/extensions/v0.rs diff --git a/runtime/devnet/src/extensions/v0/assets.rs b/runtime/devnet/src/extensions/v0/assets.rs deleted file mode 100644 index c6b15b4e..00000000 --- a/runtime/devnet/src/extensions/v0/assets.rs +++ /dev/null @@ -1,76 +0,0 @@ -use crate::extensions::{ - AccountId as AccountId32, AssetId, - AssetsKeys::{self, *}, - Balance, Compact, Decode, DispatchError, MultiAddress, Runtime, TrustBackedAssetsInstance, -}; -use pop_primitives::AccountId; -use sp_std::vec::Vec; - -pub(crate) fn construct_assets_key( - call_index: u8, - params: Vec, -) -> Result { - match call_index { - 0 => { - let id = ::decode(&mut ¶ms[..]) - .map_err(|_| DispatchError::Other("DecodingFailed"))?; - Ok(TotalSupply(id)) - }, - 1 => { - let (id, owner) = <(AssetId, AccountId)>::decode(&mut ¶ms[..]) - .map_err(|_| DispatchError::Other("DecodingFailed"))?; - Ok(BalanceOf(id, owner)) - }, - 2 => { - let (id, owner, spender) = <(AssetId, AccountId, AccountId)>::decode(&mut ¶ms[..]) - .map_err(|_| DispatchError::Other("DecodingFailed"))?; - Ok(Allowance(id, owner, spender)) - }, - 3 => { - let id = ::decode(&mut ¶ms[..]) - .map_err(|_| DispatchError::Other("DecodingFailed"))?; - Ok(TokenName(id)) - }, - 4 => { - let id = ::decode(&mut ¶ms[..]) - .map_err(|_| DispatchError::Other("DecodingFailed"))?; - Ok(TokenSymbol(id)) - }, - 5 => { - let id = ::decode(&mut ¶ms[..]) - .map_err(|_| DispatchError::Other("DecodingFailed"))?; - Ok(TokenDecimals(id)) - }, - // other calls - _ => Err(DispatchError::Other("UnknownFunctionId")), - } -} - -pub(crate) fn construct_assets_call( - call_index: u8, - params: Vec, -) -> Result, DispatchError> { - match call_index { - 9 => { - let (id, target, amount) = <(AssetId, AccountId32, Balance)>::decode(&mut ¶ms[..]) - .map_err(|_| DispatchError::Other("DecodingFailed"))?; - Ok(pallet_assets::Call::::transfer_keep_alive { - id: Compact(id), - target: MultiAddress::Id(target), - amount, - }) - }, - 22 => { - let (id, delegate, amount) = - <(AssetId, AccountId32, Balance)>::decode(&mut ¶ms[..]) - .map_err(|_| DispatchError::Other("DecodingFailed"))?; - Ok(pallet_assets::Call::::approve_transfer { - id: Compact(id), - delegate: MultiAddress::Id(delegate), - amount, - }) - }, - // other calls - _ => Err(DispatchError::Other("UnknownFunctionId")), - } -} diff --git a/runtime/devnet/src/extensions/v0/mod.rs b/runtime/devnet/src/extensions/v0/mod.rs deleted file mode 100644 index 6406e08f..00000000 --- a/runtime/devnet/src/extensions/v0/mod.rs +++ /dev/null @@ -1,2 +0,0 @@ -pub(crate) mod assets; -pub(crate) mod error; diff --git a/runtime/devnet/src/lib.rs b/runtime/devnet/src/lib.rs index 9ab64043..23895310 100644 --- a/runtime/devnet/src/lib.rs +++ b/runtime/devnet/src/lib.rs @@ -73,6 +73,8 @@ use weights::{BlockExecutionWeight, ExtrinsicBaseWeight, RocksDbWeight}; // XCM Imports use xcm::latest::prelude::BodyId; +pub(crate) use pallet_api::fungibles; + /// Some way of identifying an account on the chain. We intentionally make it equivalent /// to the public key of our transaction signing scheme. pub type AccountId = <::Signer as IdentifyAccount>::AccountId; @@ -250,82 +252,6 @@ impl Contains for FilteredCalls { } } -/// A type to identify allowed calls to the Runtime from contracts. Used by Pop API -pub struct AllowedApiCalls; -impl Contains for crate::AllowedApiCalls { - fn contains(c: &RuntimeCall) -> bool { - use config::assets::AssetsCall; - use pallet_nfts::Call as NftsCall; - matches!( - c, - RuntimeCall::Balances(BalancesCall::transfer_keep_alive { .. }) - | RuntimeCall::Assets( - AssetsCall::create { .. } - | AssetsCall::start_destroy { .. } - | AssetsCall::destroy_accounts { .. } - | AssetsCall::destroy_approvals { .. } - | AssetsCall::finish_destroy { .. } - | AssetsCall::mint { .. } - | AssetsCall::burn { .. } - | AssetsCall::transfer { .. } - | AssetsCall::transfer_keep_alive { .. } - | AssetsCall::force_transfer { .. } - | AssetsCall::freeze { .. } - | AssetsCall::thaw { .. } - | AssetsCall::freeze_asset { .. } - | AssetsCall::thaw_asset { .. } - | AssetsCall::transfer_ownership { .. } - | AssetsCall::set_team { .. } - | AssetsCall::set_metadata { .. } - | AssetsCall::clear_metadata { .. } - | AssetsCall::approve_transfer { .. } - | AssetsCall::cancel_approval { .. } - | AssetsCall::force_cancel_approval { .. } - | AssetsCall::transfer_approved { .. } - | AssetsCall::touch { .. } - | AssetsCall::refund { .. } - | AssetsCall::set_min_balance { .. } - | AssetsCall::touch_other { .. } - | AssetsCall::refund_other { .. } - | AssetsCall::block { .. } - ) | RuntimeCall::Nfts( - NftsCall::create { .. } - | NftsCall::destroy { .. } - | NftsCall::mint { .. } - | NftsCall::burn { .. } - | NftsCall::transfer { .. } - | NftsCall::redeposit { .. } - | NftsCall::lock_item_transfer { .. } - | NftsCall::unlock_item_transfer { .. } - | NftsCall::lock_collection { .. } - | NftsCall::transfer_ownership { .. } - | NftsCall::set_team { .. } - | NftsCall::approve_transfer { .. } - | NftsCall::cancel_approval { .. } - | NftsCall::clear_all_transfer_approvals { .. } - | NftsCall::lock_item_properties { .. } - | NftsCall::set_attribute { .. } - | NftsCall::clear_attribute { .. } - | NftsCall::approve_item_attributes { .. } - | NftsCall::cancel_item_attributes_approval { .. } - | NftsCall::set_metadata { .. } - | NftsCall::clear_metadata { .. } - | NftsCall::set_collection_metadata { .. } - | NftsCall::clear_collection_metadata { .. } - | NftsCall::set_accept_ownership { .. } - | NftsCall::set_collection_max_supply { .. } - | NftsCall::update_mint_settings { .. } - | NftsCall::set_price { .. } - | NftsCall::buy_item { .. } - | NftsCall::pay_tips { .. } - | NftsCall::create_swap { .. } - | NftsCall::cancel_swap { .. } - | NftsCall::claim_swap { .. } - ) - ) - } -} - /// The default types are being injected by [`derive_impl`](`frame_support::derive_impl`) from /// [`ParaChainDefaultConfig`](`struct@frame_system::config_preludes::ParaChainDefaultConfig`), /// but overridden as needed. @@ -663,6 +589,9 @@ construct_runtime!( Nfts: pallet_nfts = 50, NftFractionalization: pallet_nft_fractionalization = 51, Assets: pallet_assets:: = 52, + + // Pop API + Fungibles: fungibles = 150, } ); @@ -670,6 +599,7 @@ construct_runtime!( mod benches { frame_benchmarking::define_benchmarks!( [frame_system, SystemBench::] + [pallet_api::fungibles, Fungibles] [pallet_balances, Balances] [pallet_session, SessionBench::] [pallet_timestamp, Timestamp] @@ -1030,3 +960,22 @@ cumulus_pallet_parachain_system::register_validate_block! { Runtime = Runtime, BlockExecutor = cumulus_pallet_aura_ext::BlockExecutor::, } + +#[cfg(test)] +mod tests { + use crate::Runtime; + use std::any::TypeId; + + // Ensures that the account id lookup does not perform any state reads. When this changes, + // `pallet_api::fungibles` dispatchables need to be re-evaluated. + #[test] + fn test_lookup_config() { + type ExpectedLookup = sp_runtime::traits::AccountIdLookup; + type ConfigLookup = ::Lookup; + + let expected_type_id = TypeId::of::(); + let config_type_id = TypeId::of::(); + + assert_eq!(config_type_id, expected_type_id); + } +} diff --git a/runtime/testnet/Cargo.toml b/runtime/testnet/Cargo.toml index b04c3102..51cab6d6 100644 --- a/runtime/testnet/Cargo.toml +++ b/runtime/testnet/Cargo.toml @@ -22,8 +22,8 @@ scale-info.workspace = true smallvec.workspace = true # Local -pop-primitives = { workspace = true, features = ["nfts", "cross-chain"] } -pop-runtime-common = { workspace = true, default-features = false } +pop-primitives.workspace = true +pop-runtime-common.workspace = true # Substrate frame-benchmarking.workspace = true @@ -90,7 +90,6 @@ parachain-info.workspace = true [dev-dependencies] env_logger = "0.11.2" hex = "0.4.3" -enumflags2 = "0.7.9" [features] default = ["std"] diff --git a/runtime/testnet/src/extensions.rs b/runtime/testnet/src/extensions.rs index bcb0f835..a6e309f9 100644 --- a/runtime/testnet/src/extensions.rs +++ b/runtime/testnet/src/extensions.rs @@ -1,22 +1,13 @@ -use cumulus_pallet_parachain_system::RelaychainDataProvider; +use frame_support::traits::{Contains, OriginTrait}; use frame_support::{ dispatch::{GetDispatchInfo, RawOrigin}, pallet_prelude::*, - traits::nonfungibles_v2::Inspect, - traits::{Contains, OriginTrait}, }; use pallet_contracts::chain_extension::{ BufInBufOutState, ChainExtension, ChargedAmount, Environment, Ext, InitState, RetVal, }; -use pop_primitives::{ - nfts::{CollectionId, ItemId}, - storage_keys::{NftsKeys, ParachainSystemKeys, RuntimeStateKeys}, -}; use sp_core::crypto::UncheckedFrom; -use sp_runtime::{ - traits::{BlockNumberProvider, Dispatchable}, - DispatchError, -}; +use sp_runtime::{traits::Dispatchable, DispatchError}; use sp_std::vec::Vec; use crate::{AccountId, AllowedApiCalls, RuntimeCall, RuntimeOrigin}; @@ -31,9 +22,6 @@ pub struct PopApiExtension; impl ChainExtension for PopApiExtension where T: pallet_contracts::Config - + pallet_xcm::Config - + pallet_nfts::Config - + cumulus_pallet_parachain_system::Config + frame_system::Config< RuntimeOrigin = RuntimeOrigin, AccountId = AccountId, @@ -44,7 +32,6 @@ where fn call(&mut self, env: Environment) -> Result where E: Ext, - T::AccountId: UncheckedFrom + AsRef<[u8]>, { log::debug!(target:LOG_TARGET, " extension called "); match v0::FuncId::try_from(env.func_id())? { @@ -101,8 +88,6 @@ fn dispatch_call( log_prefix: &str, ) -> Result<(), DispatchError> where - T: frame_system::Config, - RuntimeOrigin: From>, E: Ext, { let charged_dispatch_weight = env.charge_weight(call.get_dispatch_info().weight)?; @@ -157,8 +142,7 @@ where fn dispatch(env: Environment) -> Result<(), DispatchError> where - T: pallet_contracts::Config - + frame_system::Config, + T: pallet_contracts::Config, RuntimeOrigin: From>, E: Ext, { @@ -180,10 +164,7 @@ where fn read_state(env: Environment) -> Result<(), DispatchError> where - T: pallet_contracts::Config - + pallet_nfts::Config - + cumulus_pallet_parachain_system::Config - + frame_system::Config, + T: pallet_contracts::Config, E: Ext, { const LOG_PREFIX: &str = " read_state |"; @@ -199,16 +180,9 @@ where log::debug!(target:LOG_TARGET, "{} charged weight: {:?}", LOG_PREFIX, charged_weight); - let key: RuntimeStateKeys = env.read_as()?; - - let result = match key { - RuntimeStateKeys::Nfts(key) => read_nfts_state::(key, &mut env), - RuntimeStateKeys::ParachainSystem(key) => { - read_parachain_system_state::(key, &mut env) - }, - _ => Ok(Vec::default()), - }? - .encode(); + // TODO: always returning an empty vec. Chainextension will be refactored into one for both + // runtimes before pop api implementation gets merged into main. + let result = Vec::::default().encode(); log::trace!( target:LOG_TARGET, @@ -219,521 +193,3 @@ where DispatchError::Other("unable to write results to contract memory") }) } - -fn read_parachain_system_state( - key: ParachainSystemKeys, - env: &mut Environment, -) -> Result, DispatchError> -where - T: pallet_contracts::Config + cumulus_pallet_parachain_system::Config, - E: Ext, -{ - match key { - ParachainSystemKeys::LastRelayChainBlockNumber => { - env.charge_weight(T::DbWeight::get().reads(1_u64))?; - Ok(RelaychainDataProvider::::current_block_number().encode()) - }, - } -} - -fn read_nfts_state( - key: NftsKeys, - env: &mut Environment, -) -> Result, DispatchError> -where - T: pallet_contracts::Config + pallet_nfts::Config, - E: Ext, -{ - match key { - NftsKeys::Collection(collection) => { - env.charge_weight(T::DbWeight::get().reads(1_u64))?; - Ok(pallet_nfts::Collection::::get(collection).encode()) - }, - NftsKeys::CollectionOwner(collection) => { - env.charge_weight(T::DbWeight::get().reads(1_u64))?; - Ok(pallet_nfts::Pallet::::collection_owner(collection).encode()) - }, - NftsKeys::Item(collection, item) => { - env.charge_weight(T::DbWeight::get().reads(1_u64))?; - Ok(pallet_nfts::Item::::get(collection, item).encode()) - }, - NftsKeys::Owner(collection, item) => { - env.charge_weight(T::DbWeight::get().reads(1_u64))?; - Ok(pallet_nfts::Pallet::::owner(collection, item).encode()) - }, - NftsKeys::Attribute(collection, item, key) => { - env.charge_weight(T::DbWeight::get().reads(1_u64))?; - Ok(pallet_nfts::Pallet::::attribute(&collection, &item, &key).encode()) - }, - // NftsKeys::CustomAttribute(account, collection, item, key) => { - // env.charge_weight(T::DbWeight::get().reads(1_u64))?; - // Ok(pallet_nfts::Pallet::::custom_attribute(&account, &collection, &item, &key) - // .encode()) - // }, - NftsKeys::SystemAttribute(collection, item, key) => { - env.charge_weight(T::DbWeight::get().reads(1_u64))?; - Ok(pallet_nfts::Pallet::::system_attribute(&collection, item.as_ref(), &key) - .encode()) - }, - NftsKeys::CollectionAttribute(collection, key) => { - env.charge_weight(T::DbWeight::get().reads(1_u64))?; - Ok(pallet_nfts::Pallet::::collection_attribute(&collection, &key).encode()) - }, - } -} - -#[cfg(test)] -mod tests { - pub use super::*; - pub use crate::*; - use enumflags2::BitFlags; - pub use pallet_contracts::Code; - use pallet_nfts::{CollectionConfig, CollectionSetting, CollectionSettings, MintSettings}; - use parachains_common::CollectionId; - pub use sp_runtime::{traits::Hash, AccountId32}; - - const DEBUG_OUTPUT: pallet_contracts::DebugInfo = pallet_contracts::DebugInfo::UnsafeDebug; - - const ALICE: AccountId32 = AccountId32::new([1_u8; 32]); - const BOB: AccountId32 = AccountId32::new([2_u8; 32]); - const INITIAL_AMOUNT: u128 = 100_000 * UNIT; - const GAS_LIMIT: Weight = Weight::from_parts(100_000_000_000, 3 * 1024 * 1024); - - fn new_test_ext() -> sp_io::TestExternalities { - let mut t = frame_system::GenesisConfig::::default() - .build_storage() - .expect("Frame system builds valid default genesis config"); - - pallet_balances::GenesisConfig:: { - balances: vec![(ALICE, INITIAL_AMOUNT), (BOB, INITIAL_AMOUNT)], - } - .assimilate_storage(&mut t) - .expect("Pallet balances storage can be assimilated"); - - let mut ext = sp_io::TestExternalities::new(t); - ext.execute_with(|| System::set_block_number(1)); - ext - } - - fn load_wasm_module(path: &str) -> std::io::Result<(Vec, ::Output)> - where - T: frame_system::Config, - { - let wasm_binary = std::fs::read(path)?; - let code_hash = T::Hashing::hash(&wasm_binary); - Ok((wasm_binary, code_hash)) - } - - fn function_selector(name: &str) -> Vec { - let hash = sp_io::hashing::blake2_256(name.as_bytes()); - [hash[0..4].to_vec()].concat() - } - - // NFT helper functions - fn collection_config_from_disabled_settings( - settings: BitFlags, - ) -> CollectionConfig { - CollectionConfig { - settings: CollectionSettings::from_disabled(settings), - max_supply: None, - mint_settings: MintSettings::default(), - } - } - - fn default_collection_config() -> CollectionConfig { - collection_config_from_disabled_settings(CollectionSetting::DepositRequired.into()) - } - - #[test] - #[ignore] - fn dispatch_balance_transfer_from_contract_works() { - new_test_ext().execute_with(|| { - let _ = env_logger::try_init(); - - let (wasm_binary, _) = load_wasm_module::( - "../../pop-api/examples/balance-transfer/target/ink/balance_transfer.wasm", - ) - .unwrap(); - - let init_value = 100 * UNIT; - - let result = Contracts::bare_instantiate( - ALICE, - init_value, - GAS_LIMIT, - None, - Code::Upload(wasm_binary), - function_selector("new"), - vec![], - DEBUG_OUTPUT, - pallet_contracts::CollectEvents::Skip, - ) - .result - .unwrap(); - - assert!(!result.result.did_revert(), "deploying contract reverted {:?}", result); - - let addr = result.account_id; - - let function = function_selector("transfer_through_runtime"); - let value_to_send: u128 = 10 * UNIT; - let params = [function, BOB.encode(), value_to_send.encode()].concat(); - - let bob_balance_before = Balances::free_balance(&BOB); - assert_eq!(bob_balance_before, INITIAL_AMOUNT); - - let result = Contracts::bare_call( - ALICE, - addr.clone(), - 0, - Weight::from_parts(100_000_000_000, 3 * 1024 * 1024), - None, - params, - DEBUG_OUTPUT, - pallet_contracts::CollectEvents::Skip, - pallet_contracts::Determinism::Enforced, - ); - - if DEBUG_OUTPUT == pallet_contracts::DebugInfo::UnsafeDebug { - log::debug!( - "Contract debug buffer - {:?}", - String::from_utf8(result.debug_message.clone()) - ); - log::debug!("result: {:?}", result); - } - - // check for revert - assert!(!result.result.unwrap().did_revert(), "Contract reverted!"); - - let bob_balance_after = Balances::free_balance(&BOB); - assert_eq!(bob_balance_before + value_to_send, bob_balance_after); - }); - } - - #[test] - #[ignore] - fn dispatch_nfts_mint_from_contract_works() { - new_test_ext().execute_with(|| { - let _ = env_logger::try_init(); - - let (wasm_binary, _) = - load_wasm_module::("../../pop-api/examples/nfts/target/ink/nfts.wasm") - .unwrap(); - - let init_value = 100; - - let result = Contracts::bare_instantiate( - ALICE, - init_value, - GAS_LIMIT, - None, - Code::Upload(wasm_binary), - function_selector("new"), - vec![], - DEBUG_OUTPUT, - pallet_contracts::CollectEvents::Skip, - ) - .result - .unwrap(); - - assert!(!result.result.did_revert(), "deploying contract reverted {:?}", result); - - let addr = result.account_id; - - let collection_id: u32 = 0; - let item_id: u32 = 1; - - // create nft collection with contract as owner - assert_eq!( - Nfts::force_create( - RuntimeOrigin::root(), - addr.clone().into(), - default_collection_config() - ), - Ok(()) - ); - - assert_eq!(Nfts::collection_owner(collection_id), Some(addr.clone().into())); - // assert that the item does not exist yet - assert_eq!(Nfts::owner(collection_id, item_id), None); - - let function = function_selector("mint_through_runtime"); - - let params = - [function, collection_id.encode(), item_id.encode(), BOB.encode()].concat(); - - let result = Contracts::bare_call( - ALICE, - addr.clone(), - 0, - Weight::from_parts(100_000_000_000, 3 * 1024 * 1024), - None, - params, - DEBUG_OUTPUT, - pallet_contracts::CollectEvents::Skip, - pallet_contracts::Determinism::Enforced, - ); - - if DEBUG_OUTPUT == pallet_contracts::DebugInfo::UnsafeDebug { - log::debug!( - "Contract debug buffer - {:?}", - String::from_utf8(result.debug_message.clone()) - ); - log::debug!("result: {:?}", result); - } - - // check for revert - assert!(!result.result.unwrap().did_revert(), "Contract reverted!"); - - assert_eq!(Nfts::owner(collection_id, item_id), Some(BOB.into())); - }); - } - - #[test] - #[ignore] - fn nfts_mint_surfaces_error() { - new_test_ext().execute_with(|| { - let _ = env_logger::try_init(); - - let (wasm_binary, _) = - load_wasm_module::("../../pop-api/examples/nfts/target/ink/nfts.wasm") - .unwrap(); - - let init_value = 100; - - let result = Contracts::bare_instantiate( - ALICE, - init_value, - GAS_LIMIT, - None, - Code::Upload(wasm_binary), - function_selector("new"), - vec![], - DEBUG_OUTPUT, - pallet_contracts::CollectEvents::Skip, - ) - .result - .unwrap(); - - assert!(!result.result.did_revert(), "deploying contract reverted {:?}", result); - - let addr = result.account_id; - - let collection_id: u32 = 0; - let item_id: u32 = 1; - - let function = function_selector("mint_through_runtime"); - - let params = - [function, collection_id.encode(), item_id.encode(), BOB.encode()].concat(); - - let result = Contracts::bare_call( - ALICE, - addr.clone(), - 0, - Weight::from_parts(100_000_000_000, 3 * 1024 * 1024), - None, - params, - DEBUG_OUTPUT, - pallet_contracts::CollectEvents::Skip, - pallet_contracts::Determinism::Enforced, - ); - - if DEBUG_OUTPUT == pallet_contracts::DebugInfo::UnsafeDebug { - log::debug!( - "Contract debug buffer - {:?}", - String::from_utf8(result.debug_message.clone()) - ); - log::debug!("result: {:?}", result); - } - - // check for revert with expected error - let result = result.result.unwrap(); - assert!(result.did_revert()); - }); - } - - #[test] - #[ignore] - fn reading_last_relay_chain_block_number_works() { - new_test_ext().execute_with(|| { - let _ = env_logger::try_init(); - - let (wasm_binary, _) = load_wasm_module::( - "../../pop-api/examples/read-runtime-state/target/ink/read_relay_blocknumber.wasm", - ) - .unwrap(); - - let init_value = 100; - - let contract = Contracts::bare_instantiate( - ALICE, - init_value, - GAS_LIMIT, - None, - Code::Upload(wasm_binary), - function_selector("new"), - vec![], - DEBUG_OUTPUT, - pallet_contracts::CollectEvents::Skip, - ) - .result - .unwrap(); - - assert!(!contract.result.did_revert(), "deploying contract reverted {:?}", contract); - - let addr = contract.account_id; - - let function = function_selector("read_relay_block_number"); - let params = [function].concat(); - - let result = Contracts::bare_call( - ALICE, - addr.clone(), - 0, - Weight::from_parts(100_000_000_000, 3 * 1024 * 1024), - None, - params, - DEBUG_OUTPUT, - pallet_contracts::CollectEvents::UnsafeCollect, - pallet_contracts::Determinism::Relaxed, - ); - - if DEBUG_OUTPUT == pallet_contracts::DebugInfo::UnsafeDebug { - log::debug!( - "Contract debug buffer - {:?}", - String::from_utf8(result.debug_message.clone()) - ); - log::debug!("result: {:?}", result); - } - - // check for revert - assert!(!result.result.unwrap().did_revert(), "Contract reverted!"); - }); - } - - #[test] - #[ignore] - fn place_spot_order_from_contract_fails() { - new_test_ext().execute_with(|| { - let _ = env_logger::try_init(); - - let (wasm_binary, _) = load_wasm_module::( - "../../pop-api/examples/place-spot-order/target/ink/spot_order.wasm", - ) - .unwrap(); - - let init_value = 100 * UNIT; - - let result = Contracts::bare_instantiate( - ALICE, - init_value, - GAS_LIMIT, - None, - Code::Upload(wasm_binary), - function_selector("new"), - vec![], - DEBUG_OUTPUT, - pallet_contracts::CollectEvents::Skip, - ) - .result - .unwrap(); - - assert!(!result.result.did_revert(), "deploying contract reverted {:?}", result); - - let addr = result.account_id; - - let function = function_selector("place_spot_order"); - - let max_amount = 1 * UNIT; - let para_id = 2000; - - let params = [function, max_amount.encode(), para_id.encode()].concat(); - - let result = Contracts::bare_call( - ALICE, - addr.clone(), - 0, - Weight::from_parts(100_000_000_000, 3 * 1024 * 1024), - None, - params, - DEBUG_OUTPUT, - pallet_contracts::CollectEvents::Skip, - pallet_contracts::Determinism::Enforced, - ); - - if DEBUG_OUTPUT == pallet_contracts::DebugInfo::UnsafeDebug { - log::debug!( - "Contract debug buffer - {:?}", - String::from_utf8(result.debug_message.clone()) - ); - log::debug!("result: {:?}", result); - } - - // check for revert - assert!( - result.result.is_err(), - "Contract execution should have failed - unimplemented runtime call!" - ); - }); - } - - #[test] - #[ignore] - fn allow_call_filter_blocks_call() { - new_test_ext().execute_with(|| { - let _ = env_logger::try_init(); - - let (wasm_binary, _) = load_wasm_module::( - "../../tests/contracts/filtered-call/target/ink/pop_api_filtered_call.wasm", - ) - .unwrap(); - - let init_value = 100 * UNIT; - - let result = Contracts::bare_instantiate( - ALICE, - init_value, - GAS_LIMIT, - None, - Code::Upload(wasm_binary), - function_selector("new"), - vec![], - DEBUG_OUTPUT, - pallet_contracts::CollectEvents::Skip, - ) - .result - .unwrap(); - - assert!(!result.result.did_revert(), "deploying contract reverted {:?}", result); - - let addr = result.account_id; - - let function = function_selector("get_filtered"); - let params = [function].concat(); - - let result = Contracts::bare_call( - ALICE, - addr.clone(), - 0, - Weight::from_parts(100_000_000_000, 3 * 1024 * 1024), - None, - params, - DEBUG_OUTPUT, - pallet_contracts::CollectEvents::Skip, - pallet_contracts::Determinism::Enforced, - ); - - if DEBUG_OUTPUT == pallet_contracts::DebugInfo::UnsafeDebug { - log::debug!( - "Contract debug buffer - {:?}", - String::from_utf8(result.debug_message.clone()) - ); - log::debug!("filtered result: {:?}", result); - } - - // check for revert - assert!(!result.result.unwrap().did_revert(), "Contract reverted!"); - }); - } -} diff --git a/runtime/testnet/src/lib.rs b/runtime/testnet/src/lib.rs index c4178011..5573ef18 100644 --- a/runtime/testnet/src/lib.rs +++ b/runtime/testnet/src/lib.rs @@ -252,45 +252,8 @@ impl Contains for FilteredCalls { /// A type to identify allowed calls to the Runtime from contracts. Used by Pop API pub struct AllowedApiCalls; impl Contains for AllowedApiCalls { - fn contains(c: &RuntimeCall) -> bool { - use pallet_nfts::Call as NftsCall; - matches!( - c, - RuntimeCall::Balances(BalancesCall::transfer_keep_alive { .. }) - | RuntimeCall::Nfts( - NftsCall::create { .. } - | NftsCall::destroy { .. } - | NftsCall::mint { .. } | NftsCall::burn { .. } - | NftsCall::transfer { .. } - | NftsCall::redeposit { .. } - | NftsCall::lock_item_transfer { .. } - | NftsCall::unlock_item_transfer { .. } - | NftsCall::lock_collection { .. } - | NftsCall::transfer_ownership { .. } - | NftsCall::set_team { .. } - | NftsCall::approve_transfer { .. } - | NftsCall::cancel_approval { .. } - | NftsCall::clear_all_transfer_approvals { .. } - | NftsCall::lock_item_properties { .. } - | NftsCall::set_attribute { .. } - | NftsCall::clear_attribute { .. } - | NftsCall::approve_item_attributes { .. } - | NftsCall::cancel_item_attributes_approval { .. } - | NftsCall::set_metadata { .. } - | NftsCall::clear_metadata { .. } - | NftsCall::set_collection_metadata { .. } - | NftsCall::clear_collection_metadata { .. } - | NftsCall::set_accept_ownership { .. } - | NftsCall::set_collection_max_supply { .. } - | NftsCall::update_mint_settings { .. } - | NftsCall::set_price { .. } - | NftsCall::buy_item { .. } - | NftsCall::pay_tips { .. } - | NftsCall::create_swap { .. } - | NftsCall::cancel_swap { .. } - | NftsCall::claim_swap { .. } - ) - ) + fn contains(_c: &RuntimeCall) -> bool { + false } } diff --git a/scripts/pallet-weights-template.hbs b/scripts/pallet-weights-template.hbs new file mode 100644 index 00000000..9e1e5a46 --- /dev/null +++ b/scripts/pallet-weights-template.hbs @@ -0,0 +1,122 @@ +{{header}} +//! Autogenerated weights for `{{pallet}}` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION {{version}} +//! DATE: {{date}}, STEPS: `{{cmd.steps}}`, REPEAT: `{{cmd.repeat}}`, LOW RANGE: `{{cmd.lowest_range_values}}`, HIGH RANGE: `{{cmd.highest_range_values}}` +//! WORST CASE MAP SIZE: `{{cmd.worst_case_map_values}}` +//! HOSTNAME: `R0GUE`, CPU: `{{cpuname}}` +//! WASM-EXECUTION: `{{cmd.wasm_execution}}`, CHAIN: `{{cmd.chain}}`, DB CACHE: `{{cmd.db_cache}}` + +// Executed Command: +{{#each args as |arg|}} +// {{arg}} +{{/each}} + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; +use core::marker::PhantomData; + +/// Weight functions needed for `{{pallet}}`. +pub trait WeightInfo { + {{#each benchmarks as |benchmark|}} + fn {{benchmark.name~}} + ( + {{~#each benchmark.components as |c| ~}} + {{c.name}}: u32, {{/each~}} + ) -> Weight; + {{/each}} +} + +/// Weights for `{{pallet}}` using the Substrate node and recommended hardware. +pub struct SubstrateWeight(PhantomData); +{{#if (eq pallet "frame_system")}} +impl WeightInfo for SubstrateWeight { +{{else}} +impl WeightInfo for SubstrateWeight { +{{/if}} + {{#each benchmarks as |benchmark|}} + {{#each benchmark.comments as |comment|}} + /// {{comment}} + {{/each}} + {{#each benchmark.component_ranges as |range|}} + /// The range of component `{{range.name}}` is `[{{range.min}}, {{range.max}}]`. + {{/each}} + fn {{benchmark.name~}} + ( + {{~#each benchmark.components as |c| ~}} + {{~#if (not c.is_used)}}_{{/if}}{{c.name}}: u32, {{/each~}} + ) -> Weight { + // Proof Size summary in bytes: + // Measured: `{{benchmark.base_recorded_proof_size}}{{#each benchmark.component_recorded_proof_size as |cp|}} + {{cp.name}} * ({{cp.slope}} ±{{underscore cp.error}}){{/each}}` + // Estimated: `{{benchmark.base_calculated_proof_size}}{{#each benchmark.component_calculated_proof_size as |cp|}} + {{cp.name}} * ({{cp.slope}} ±{{underscore cp.error}}){{/each}}` + // Minimum execution time: {{underscore benchmark.min_execution_time}}_000 picoseconds. + Weight::from_parts({{underscore benchmark.base_weight}}, {{benchmark.base_calculated_proof_size}}) + {{#each benchmark.component_weight as |cw|}} + // Standard Error: {{underscore cw.error}} + .saturating_add(Weight::from_parts({{underscore cw.slope}}, 0).saturating_mul({{cw.name}}.into())) + {{/each}} + {{#if (ne benchmark.base_reads "0")}} + .saturating_add(T::DbWeight::get().reads({{benchmark.base_reads}}_u64)) + {{/if}} + {{#each benchmark.component_reads as |cr|}} + .saturating_add(T::DbWeight::get().reads(({{cr.slope}}_u64).saturating_mul({{cr.name}}.into()))) + {{/each}} + {{#if (ne benchmark.base_writes "0")}} + .saturating_add(T::DbWeight::get().writes({{benchmark.base_writes}}_u64)) + {{/if}} + {{#each benchmark.component_writes as |cw|}} + .saturating_add(T::DbWeight::get().writes(({{cw.slope}}_u64).saturating_mul({{cw.name}}.into()))) + {{/each}} + {{#each benchmark.component_calculated_proof_size as |cp|}} + .saturating_add(Weight::from_parts(0, {{cp.slope}}).saturating_mul({{cp.name}}.into())) + {{/each}} + } + {{/each}} +} + +// For backwards compatibility and tests. +impl WeightInfo for () { + {{#each benchmarks as |benchmark|}} + {{#each benchmark.comments as |comment|}} + /// {{comment}} + {{/each}} + {{#each benchmark.component_ranges as |range|}} + /// The range of component `{{range.name}}` is `[{{range.min}}, {{range.max}}]`. + {{/each}} + fn {{benchmark.name~}} + ( + {{~#each benchmark.components as |c| ~}} + {{~#if (not c.is_used)}}_{{/if}}{{c.name}}: u32, {{/each~}} + ) -> Weight { + // Proof Size summary in bytes: + // Measured: `{{benchmark.base_recorded_proof_size}}{{#each benchmark.component_recorded_proof_size as |cp|}} + {{cp.name}} * ({{cp.slope}} ±{{underscore cp.error}}){{/each}}` + // Estimated: `{{benchmark.base_calculated_proof_size}}{{#each benchmark.component_calculated_proof_size as |cp|}} + {{cp.name}} * ({{cp.slope}} ±{{underscore cp.error}}){{/each}}` + // Minimum execution time: {{underscore benchmark.min_execution_time}}_000 picoseconds. + Weight::from_parts({{underscore benchmark.base_weight}}, {{benchmark.base_calculated_proof_size}}) + {{#each benchmark.component_weight as |cw|}} + // Standard Error: {{underscore cw.error}} + .saturating_add(Weight::from_parts({{underscore cw.slope}}, 0).saturating_mul({{cw.name}}.into())) + {{/each}} + {{#if (ne benchmark.base_reads "0")}} + .saturating_add(RocksDbWeight::get().reads({{benchmark.base_reads}}_u64)) + {{/if}} + {{#each benchmark.component_reads as |cr|}} + .saturating_add(RocksDbWeight::get().reads(({{cr.slope}}_u64).saturating_mul({{cr.name}}.into()))) + {{/each}} + {{#if (ne benchmark.base_writes "0")}} + .saturating_add(RocksDbWeight::get().writes({{benchmark.base_writes}}_u64)) + {{/if}} + {{#each benchmark.component_writes as |cw|}} + .saturating_add(RocksDbWeight::get().writes(({{cw.slope}}_u64).saturating_mul({{cw.name}}.into()))) + {{/each}} + {{#each benchmark.component_calculated_proof_size as |cp|}} + .saturating_add(Weight::from_parts(0, {{cp.slope}}).saturating_mul({{cp.name}}.into())) + {{/each}} + } + {{/each}} +} + From 4e4512ef091a9c6322eb17e697b2180c0e210f22 Mon Sep 17 00:00:00 2001 From: Tin Chung <56880684+chungquantin@users.noreply.github.com> Date: Fri, 26 Jul 2024 17:45:43 +0700 Subject: [PATCH 029/112] refactor: streamline error from the decoded method by returning `Result` (#130) --- .../integration-tests/src/local_fungibles.rs | 65 ++++++++++--------- 1 file changed, 33 insertions(+), 32 deletions(-) diff --git a/pop-api/integration-tests/src/local_fungibles.rs b/pop-api/integration-tests/src/local_fungibles.rs index c62f0713..6de57ca4 100644 --- a/pop-api/integration-tests/src/local_fungibles.rs +++ b/pop-api/integration-tests/src/local_fungibles.rs @@ -8,11 +8,9 @@ use pop_primitives::error::{ const ASSET_ID: AssetId = 1; const CONTRACT: &str = "contracts/fungibles/target/ink/fungibles.wasm"; -fn decoded(result: ExecReturnValue) -> T { - match ::decode(&mut &result.data[2..]) { - Ok(value) => value, - Err(_) => panic!("\nTest failed by trying to decode `{:?}` into `T`\n", result), - } +fn decoded(result: ExecReturnValue) -> Result { + ::decode(&mut &result.data[2..]) + .map_err(|_| format!("\nTest failed by trying to decode `{:?}` into `T`\n", result)) } // Call total_supply contract message. @@ -20,7 +18,7 @@ fn total_supply(addr: AccountId32, asset_id: AssetId) -> Balance { let function = function_selector("total_supply"); let params = [function, asset_id.encode()].concat(); let result = bare_call(addr, params, 0).expect("should work"); - decoded::(result) + decoded::(result).unwrap() } // Call balance_of contract message. @@ -28,7 +26,7 @@ fn balance_of(addr: AccountId32, asset_id: AssetId, owner: AccountId32) -> Balan let function = function_selector("balance_of"); let params = [function, asset_id.encode(), owner.encode()].concat(); let result = bare_call(addr, params, 0).expect("should work"); - decoded::(result) + decoded::(result).unwrap() } // Call allowance contract message. @@ -41,7 +39,7 @@ fn allowance( let function = function_selector("allowance"); let params = [function, asset_id.encode(), owner.encode(), spender.encode()].concat(); let result = bare_call(addr, params, 0).expect("should work"); - decoded::(result) + decoded::(result).unwrap() } // Call token_name contract message. @@ -49,7 +47,7 @@ fn token_name(addr: AccountId32, asset_id: AssetId) -> Vec { let function = function_selector("token_name"); let params = [function, asset_id.encode()].concat(); let result = bare_call(addr, params, 0).expect("should work"); - decoded::>(result) + decoded::>(result).unwrap() } // Call token_symbol contract message. @@ -57,7 +55,7 @@ fn token_symbol(addr: AccountId32, asset_id: AssetId) -> Vec { let function = function_selector("token_symbol"); let params = [function, asset_id.encode()].concat(); let result = bare_call(addr, params, 0).expect("should work"); - decoded::>(result) + decoded::>(result).unwrap() } // Call token_decimals contract message. @@ -65,7 +63,7 @@ fn token_decimals(addr: AccountId32, asset_id: AssetId) -> u8 { let function = function_selector("token_decimals"); let params = [function, asset_id.encode()].concat(); let result = bare_call(addr, params, 0).expect("should work"); - decoded::(result) + decoded::(result).unwrap() } fn transfer( @@ -327,7 +325,7 @@ fn transfer_works() { // Asset does not exist. assert_eq!( decoded::(transfer(addr.clone(), 1, BOB, amount,)), - Module { index: 52, error: 3 }, + Ok(Module { index: 52, error: 3 }), ); // Create asset with Alice as owner and mint `amount` to contract address. let asset = create_asset_and_mint_to(ALICE, 1, addr.clone(), amount); @@ -335,18 +333,18 @@ fn transfer_works() { freeze_asset(ALICE, asset); assert_eq!( decoded::(transfer(addr.clone(), asset, BOB, amount,)), - Module { index: 52, error: 16 }, + Ok(Module { index: 52, error: 16 }), ); thaw_asset(ALICE, asset); // Not enough balance. assert_eq!( decoded::(transfer(addr.clone(), asset, BOB, amount + 1 * UNIT)), - Module { index: 52, error: 0 }, + Ok(Module { index: 52, error: 0 }), ); // Not enough balance due to ED. assert_eq!( decoded::(transfer(addr.clone(), asset, BOB, amount)), - Module { index: 52, error: 0 }, + Ok(Module { index: 52, error: 0 }), ); // Successful transfer. let balance_before_transfer = Assets::balance(asset, &BOB); @@ -357,13 +355,13 @@ fn transfer_works() { // Transfer asset to account that does not exist. assert_eq!( decoded::(transfer(addr.clone(), asset, FERDIE, amount / 4)), - Token(CannotCreate) + Ok(Token(CannotCreate)) ); // Asset is not live, i.e. frozen or being destroyed. start_destroy_asset(ALICE, asset); assert_eq!( decoded::(transfer(addr.clone(), asset, BOB, amount / 4)), - Module { index: 52, error: 16 }, + Ok(Module { index: 52, error: 16 }), ); }); } @@ -377,10 +375,13 @@ fn approve_works() { // Asset does not exist. assert_eq!( decoded::(approve(addr.clone(), 0, BOB, amount)), - Module { index: 52, error: 3 }, + Ok(Module { index: 52, error: 3 }), ); let asset = create_asset_and_mint_to(ALICE, 0, addr.clone(), amount); - assert_eq!(decoded::(approve(addr.clone(), asset, BOB, amount)), ConsumerRemaining); + assert_eq!( + decoded::(approve(addr.clone(), asset, BOB, amount)), + Ok(ConsumerRemaining) + ); let addr = instantiate(CONTRACT, INIT_VALUE, vec![1]); // Create asset with Alice as owner and mint `amount` to contract address. @@ -389,7 +390,7 @@ fn approve_works() { freeze_asset(ALICE, asset); assert_eq!( decoded::(approve(addr.clone(), asset, BOB, amount)), - Module { index: 52, error: 16 }, + Ok(Module { index: 52, error: 16 }), ); thaw_asset(ALICE, asset); // Successful approvals: @@ -403,7 +404,7 @@ fn approve_works() { start_destroy_asset(ALICE, asset); assert_eq!( decoded::(approve(addr.clone(), asset, BOB, amount)), - Module { index: 52, error: 16 }, + Ok(Module { index: 52, error: 16 }), ); }); } @@ -417,12 +418,12 @@ fn increase_allowance_works() { // Asset does not exist. assert_eq!( decoded::(increase_allowance(addr.clone(), 0, BOB, amount)), - Module { index: 52, error: 3 }, + Ok(Module { index: 52, error: 3 }), ); let asset = create_asset_and_mint_to(ALICE, 0, addr.clone(), amount); assert_eq!( decoded::(increase_allowance(addr.clone(), asset, BOB, amount)), - ConsumerRemaining + Ok(ConsumerRemaining) ); let addr = instantiate(CONTRACT, INIT_VALUE, vec![1]); @@ -432,7 +433,7 @@ fn increase_allowance_works() { freeze_asset(ALICE, asset); assert_eq!( decoded::(increase_allowance(addr.clone(), asset, BOB, amount)), - Module { index: 52, error: 16 }, + Ok(Module { index: 52, error: 16 }), ); thaw_asset(ALICE, asset); // Successful approvals: @@ -452,7 +453,7 @@ fn increase_allowance_works() { start_destroy_asset(ALICE, asset); assert_eq!( decoded::(increase_allowance(addr.clone(), asset, BOB, amount)), - Module { index: 52, error: 16 }, + Ok(Module { index: 52, error: 16 }), ); }); } @@ -530,7 +531,7 @@ fn token_metadata_works() { // // Minting can only be done by the owner. // assert_eq!( // decoded::(transfer_from(addr.clone(), asset, None, Some(BOB), amount, &[0u8])), -// Module { index: 52, error: 2 }, +// Ok(Module { index: 52, error: 2 }), // ); // // Minimum balance of an asset can not be zero. // assert_eq!( @@ -542,7 +543,7 @@ fn token_metadata_works() { // freeze_asset(addr.clone(), asset); // assert_eq!( // decoded::(transfer_from(addr.clone(), asset, None, Some(BOB), amount, &[0u8])), -// Module { index: 52, error: 16 }, +// Ok(Module { index: 52, error: 16 }), // ); // thaw_asset(addr.clone(), asset); // // Successful mint. @@ -567,7 +568,7 @@ fn token_metadata_works() { // start_destroy_asset(addr.clone(), asset); // assert_eq!( // decoded::(transfer_from(addr.clone(), asset, None, Some(BOB), amount, &[0u8])), -// Module { index: 52, error: 16 }, +// Ok(Module { index: 52, error: 16 }), // ); // }); // } @@ -582,27 +583,27 @@ fn token_metadata_works() { // // No balance to pay for fees. // assert_eq!( // decoded::(create(addr.clone(), ASSET_ID, addr.clone(), 1)), -// Module { index: 10, error: 2 }, +// Ok(Module { index: 10, error: 2 }), // ); // // Instantiate a contract without balance (relay token). // let addr = instantiate(CONTRACT, 100, vec![2]); // // No balance to pay the deposit. // assert_eq!( // decoded::(create(addr.clone(), ASSET_ID, addr.clone(), 1)), -// Module { index: 10, error: 2 }, +// Ok(Module { index: 10, error: 2 }), // ); // // Instantiate a contract with balance. // let addr = // instantiate(CONTRACT, INIT_VALUE, vec![1]); // assert_eq!( // decoded::(create(addr.clone(), ASSET_ID, BOB, 0)), -// Module { index: 52, error: 7 }, +// Ok(Module { index: 52, error: 7 }), // ); // create_asset(ALICE, ASSET_ID, 1); // // Asset ID is already taken. // assert_eq!( // decoded::(create(addr.clone(), ASSET_ID, BOB, 1)), -// Module { index: 52, error: 5 }, +// Ok(Module { index: 52, error: 5 }), // ); // // The minimal balance for an asset must be non zero. // let new_asset = 2; From 027cb85d9d6c97942500a75f528088f9c2402210 Mon Sep 17 00:00:00 2001 From: Tin Chung <56880684+chungquantin@users.noreply.github.com> Date: Sat, 27 Jul 2024 00:16:18 +0700 Subject: [PATCH 030/112] refactor: build chain extension method (#121) Co-authored-by: Daan van der Plas <93204684+Daanvdplas@users.noreply.github.com> Co-authored-by: Daanvdplas --- pop-api/src/lib.rs | 18 ++++++++++++++ pop-api/src/v0/assets/fungibles.rs | 38 +++++++++++++++++++++--------- pop-api/src/v0/assets/mod.rs | 1 + pop-api/src/v0/mod.rs | 26 +++++++++++++++++++- 4 files changed, 71 insertions(+), 12 deletions(-) diff --git a/pop-api/src/lib.rs b/pop-api/src/lib.rs index a984bb9e..9bf9d50b 100644 --- a/pop-api/src/lib.rs +++ b/pop-api/src/lib.rs @@ -1,5 +1,7 @@ #![cfg_attr(not(feature = "std"), no_std, no_main)] +use ink::env::chain_extension::{ChainExtensionMethod, FromStatusCode}; + use constants::DECODING_FAILED; use ink::env::chain_extension::FromStatusCode; #[cfg(feature = "assets")] @@ -27,6 +29,22 @@ mod constants { pub(crate) const FUNGIBLES: u8 = 150; } +/// Helper method to build `ChainExtensionMethod`. +/// +/// Parameters: +/// - 'version': The version of the chain extension +/// - 'function': The ID of the function +/// - 'module': The index of the runtime module +/// - 'dispatchable': The index of the module dispatchable functions +fn build_extension_method( + version: u8, + function: u8, + module: u8, + dispatchable: u8, +) -> ChainExtensionMethod<(), (), (), false> { + ChainExtensionMethod::build(u32::from_le_bytes([version, function, module, dispatchable])) +} + /// Represents a status code returned by the runtime. /// /// `StatusCode` encapsulates a `u32` value that indicates the status of an operation performed diff --git a/pop-api/src/v0/assets/fungibles.rs b/pop-api/src/v0/assets/fungibles.rs index 42373cd7..68ce76b8 100644 --- a/pop-api/src/v0/assets/fungibles.rs +++ b/pop-api/src/v0/assets/fungibles.rs @@ -9,6 +9,22 @@ use crate::{ use constants::*; pub use metadata::*; +/// Helper method to build a dispatch call `ChainExtensionMethod` for fungibles `v0` +/// +/// Parameters: +/// - 'dispatchable': The index of the module dispatchable functions +fn build_dispatch(dispatchable: u8) -> ChainExtensionMethod<(), (), (), false> { + crate::v0::build_dispatch(FUNGIBLES, dispatchable) +} + +/// Helper method to build a dispatch call `ChainExtensionMethod` for fungibles `v0`` +/// +/// Parameters: +/// - 'state_query': The index of the runtime state query +fn build_read_state(state_query: u8) -> ChainExtensionMethod<(), (), (), false> { + crate::v0::build_read_state(FUNGIBLES, state_query) +} + /// Local Fungibles: /// 1. PSP-22 Interface /// 2. PSP-22 Metadata Interface @@ -60,7 +76,7 @@ mod constants { /// The total supply of the token, or an error if the operation fails. #[inline] pub fn total_supply(id: AssetId) -> Result { - ChainExtensionMethod::build(u32::from_le_bytes([V0, READ_STATE, FUNGIBLES, TOTAL_SUPPLY])) + build_read_state(TOTAL_SUPPLY) .input::() .output::>, true>() .handle_error_code::() @@ -79,7 +95,7 @@ pub fn total_supply(id: AssetId) -> Result { /// The balance of the specified account, or an error if the operation fails. #[inline] pub fn balance_of(id: AssetId, owner: AccountId) -> Result { - ChainExtensionMethod::build(u32::from_le_bytes([V0, READ_STATE, FUNGIBLES, BALANCE_OF])) + build_read_state(BALANCE_OF) .input::<(AssetId, AccountId)>() .output::>, true>() .handle_error_code::() @@ -99,7 +115,7 @@ pub fn balance_of(id: AssetId, owner: AccountId) -> Result { /// The remaining allowance, or an error if the operation fails. #[inline] pub fn allowance(id: AssetId, owner: AccountId, spender: AccountId) -> Result { - ChainExtensionMethod::build(u32::from_le_bytes([V0, READ_STATE, FUNGIBLES, ALLOWANCE])) + build_read_state(ALLOWANCE) .input::<(AssetId, AccountId, AccountId)>() .output::>, true>() .handle_error_code::() @@ -119,7 +135,7 @@ pub fn allowance(id: AssetId, owner: AccountId, spender: AccountId) -> Result Result<()> { - ChainExtensionMethod::build(u32::from_le_bytes([V0, DISPATCH, FUNGIBLES, TRANSFER])) + build_dispatch(TRANSFER) .input::<(AssetId, AccountId, Balance)>() .output::, true>() .handle_error_code::() @@ -140,7 +156,7 @@ pub fn transfer(id: AssetId, target: AccountId, amount: Balance) -> Result<()> { /// Returns `Ok(())` if successful, or an error if the transfer fails. #[inline] pub fn transfer_from(id: AssetId, from: AccountId, to: AccountId, amount: Balance) -> Result<()> { - ChainExtensionMethod::build(u32::from_le_bytes([V0, DISPATCH, FUNGIBLES, TRANSFER_FROM])) + build_dispatch(TRANSFER_FROM) .input::<(AssetId, AccountId, AccountId, Balance)>() .output::, true>() .handle_error_code::() @@ -158,7 +174,7 @@ pub fn transfer_from(id: AssetId, from: AccountId, to: AccountId, amount: Balanc /// Returns `Ok(())` if successful, or an error if the approval fails. #[inline] pub fn approve(id: AssetId, spender: AccountId, amount: Balance) -> Result<()> { - ChainExtensionMethod::build(u32::from_le_bytes([V0, DISPATCH, FUNGIBLES, APPROVE])) + build_dispatch(APPROVE) .input::<(AssetId, AccountId, Balance)>() .output::, true>() .handle_error_code::() @@ -176,7 +192,7 @@ pub fn approve(id: AssetId, spender: AccountId, amount: Balance) -> Result<()> { /// Returns `Ok(())` if successful, or an error if the operation fails. #[inline] pub fn increase_allowance(id: AssetId, spender: AccountId, value: Balance) -> Result<()> { - ChainExtensionMethod::build(u32::from_le_bytes([V0, DISPATCH, FUNGIBLES, INCREASE_ALLOWANCE])) + build_dispatch(INCREASE_ALLOWANCE) .input::<(AssetId, AccountId, Balance)>() .output::, true>() .handle_error_code::() @@ -194,7 +210,7 @@ pub fn increase_allowance(id: AssetId, spender: AccountId, value: Balance) -> Re /// Returns `Ok(())` if successful, or an error if the operation fails. #[inline] pub fn decrease_allowance(id: AssetId, spender: AccountId, value: Balance) -> Result<()> { - ChainExtensionMethod::build(u32::from_le_bytes([V0, DISPATCH, FUNGIBLES, DECREASE_ALLOWANCE])) + build_dispatch(DECREASE_ALLOWANCE) .input::<(AssetId, AccountId, Balance)>() .output::, true>() .handle_error_code::() @@ -212,7 +228,7 @@ pub mod metadata { /// The name of the token as a byte vector, or an error if the operation fails. #[inline] pub fn token_name(id: AssetId) -> Result> { - ChainExtensionMethod::build(u32::from_le_bytes([V0, READ_STATE, FUNGIBLES, TOKEN_NAME])) + build_read_state(TOKEN_NAME) .input::() .output::>, true>() .handle_error_code::() @@ -229,7 +245,7 @@ pub mod metadata { /// The symbol of the token as a byte vector, or an error if the operation fails. #[inline] pub fn token_symbol(id: AssetId) -> Result> { - ChainExtensionMethod::build(u32::from_le_bytes([V0, READ_STATE, FUNGIBLES, TOKEN_SYMBOL])) + build_read_state(TOKEN_SYMBOL) .input::() .output::>, true>() .handle_error_code::() @@ -246,7 +262,7 @@ pub mod metadata { /// The number of decimals of the token as a byte vector, or an error if the operation fails. #[inline] pub fn token_decimals(id: AssetId) -> Result { - ChainExtensionMethod::build(u32::from_le_bytes([V0, READ_STATE, FUNGIBLES, TOKEN_DECIMALS])) + build_read_state(TOKEN_DECIMALS) .input::() .output::>, true>() .handle_error_code::() diff --git a/pop-api/src/v0/assets/mod.rs b/pop-api/src/v0/assets/mod.rs index 197db710..c68c0181 100644 --- a/pop-api/src/v0/assets/mod.rs +++ b/pop-api/src/v0/assets/mod.rs @@ -1,2 +1,3 @@ #[cfg(feature = "fungibles")] pub mod fungibles; + diff --git a/pop-api/src/v0/mod.rs b/pop-api/src/v0/mod.rs index 1c3642e1..0fd06c89 100644 --- a/pop-api/src/v0/mod.rs +++ b/pop-api/src/v0/mod.rs @@ -1,4 +1,10 @@ -use crate::{primitives::error::Error, StatusCode}; +use crate::{ + build_extension_method, + constants::{DISPATCH, READ_STATE}, + primitives::error::Error, + StatusCode, +}; +use ink::env::chain_extension::ChainExtensionMethod; #[cfg(feature = "assets")] pub mod assets; @@ -10,3 +16,21 @@ impl From for Error { value.0.into() } } + +/// Helper method to build a dispatch call `ChainExtensionMethod` +/// +/// Parameters: +/// - 'module': The index of the runtime module +/// - 'dispatchable': The index of the module dispatchable functions +fn build_dispatch(module: u8, dispatchable: u8) -> ChainExtensionMethod<(), (), (), false> { + build_extension_method(V0, DISPATCH, module, dispatchable) +} + +/// Helper method to build a dispatch call `ChainExtensionMethod` +/// +/// Parameters: +/// - 'module': The index of the runtime module +/// - 'state_query': The index of the runtime state query +fn build_read_state(module: u8, state_query: u8) -> ChainExtensionMethod<(), (), (), false> { + build_extension_method(V0, READ_STATE, module, state_query) +} From 30ff91ad13346b6931561a25917e89019dd3373c Mon Sep 17 00:00:00 2001 From: Tin Chung <56880684+chungquantin@users.noreply.github.com> Date: Sat, 27 Jul 2024 08:52:26 +0700 Subject: [PATCH 031/112] fix: clean up imports (#135) --- pop-api/src/lib.rs | 2 +- pop-api/src/v0/assets/fungibles.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pop-api/src/lib.rs b/pop-api/src/lib.rs index 9bf9d50b..efa7ecb2 100644 --- a/pop-api/src/lib.rs +++ b/pop-api/src/lib.rs @@ -1,6 +1,6 @@ #![cfg_attr(not(feature = "std"), no_std, no_main)] -use ink::env::chain_extension::{ChainExtensionMethod, FromStatusCode}; +use ink::env::chain_extension::ChainExtensionMethod; use constants::DECODING_FAILED; use ink::env::chain_extension::FromStatusCode; diff --git a/pop-api/src/v0/assets/fungibles.rs b/pop-api/src/v0/assets/fungibles.rs index 68ce76b8..374b6e88 100644 --- a/pop-api/src/v0/assets/fungibles.rs +++ b/pop-api/src/v0/assets/fungibles.rs @@ -1,7 +1,7 @@ use ink::{env::chain_extension::ChainExtensionMethod, prelude::vec::Vec, scale::Decode}; use crate::{ - constants::{ASSETS, BALANCES, DECODING_FAILED, DISPATCH, FUNGIBLES, READ_STATE}, + constants::{ASSETS, BALANCES, DECODING_FAILED, FUNGIBLES}, primitives::{AccountId, AssetId, Balance}, v0::V0, Result, StatusCode, From 9820e7fc0c8568cf1efad813b7464d09c13e676f Mon Sep 17 00:00:00 2001 From: Daan van der Plas <93204684+Daanvdplas@users.noreply.github.com> Date: Sun, 28 Jul 2024 12:07:55 +0200 Subject: [PATCH 032/112] refactor: remove read state encoding (#122) Co-authored-by: Frank Bell --- pallets/api/src/fungibles/mod.rs | 78 ++++++++----------------- pallets/api/src/fungibles/tests.rs | 20 ++++--- pop-api/src/lib.rs | 4 +- pop-api/src/v0/assets/fungibles.rs | 20 ++----- pop-api/src/v0/assets/mod.rs | 1 - runtime/devnet/src/config/api.rs | 35 ++++++++---- runtime/devnet/src/extensions/mod.rs | 85 ++++++++++++---------------- runtime/devnet/src/extensions/v0.rs | 4 +- 8 files changed, 106 insertions(+), 141 deletions(-) diff --git a/pallets/api/src/fungibles/mod.rs b/pallets/api/src/fungibles/mod.rs index cd34664a..32f9af67 100644 --- a/pallets/api/src/fungibles/mod.rs +++ b/pallets/api/src/fungibles/mod.rs @@ -180,61 +180,33 @@ pub mod pallet { } impl Pallet { - /// Returns the total token supply for a given asset ID. + /// Reads fungible asset state based on the provided value. /// - /// # Parameters - /// * `id` - The ID of the asset. - pub fn total_supply(id: AssetIdOf) -> BalanceOf { - AssetsOf::::total_supply(id) - } - - /// Returns the account balance for the specified `owner` for a given asset ID. Returns `0` if - /// the account is non-existent. + /// This function matches the value to determine the type of state query and returns the + /// encoded result. /// - /// # Parameters - /// * `id` - The ID of the asset. - /// * `owner` - The account whose balance is being queried. - pub fn balance_of(id: AssetIdOf, owner: &AccountIdOf) -> BalanceOf { - AssetsOf::::balance(id, owner) - } - - /// Returns the amount which `spender` is still allowed to withdraw from `owner` for a given - /// asset ID. Returns `0` if no allowance has been set. - /// - /// # Parameters - /// * `id` - The ID of the asset. - /// * `owner` - The account that owns the tokens. - /// * `spender` - The account that is allowed to spend the tokens. - pub fn allowance( - id: AssetIdOf, - owner: &AccountIdOf, - spender: &AccountIdOf, - ) -> BalanceOf { - AssetsOf::::allowance(id, owner, spender) - } - - /// Returns the token name for a given asset ID. - /// - /// # Parameters - /// * `id` - The ID of the asset. - pub fn token_name(id: AssetIdOf) -> Vec { - as MetadataInspect>>::name(id) - } - - /// Returns the token symbol for a given asset ID. - /// - /// # Parameters - /// * `id` - The ID of the asset. - pub fn token_symbol(id: AssetIdOf) -> Vec { - as MetadataInspect>>::symbol(id) - } - - /// Returns the token decimals for a given asset ID. - /// - /// # Parameters - /// * `id` - The ID of the asset. - pub fn token_decimals(id: AssetIdOf) -> u8 { - as MetadataInspect>>::decimals(id) + /// # Parameter + /// * `value` - An instance of `Read`, which specifies the type of state query and + /// the associated parameters. + pub fn read_state(value: Read) -> Vec { + use Read::*; + + match value { + TotalSupply(id) => AssetsOf::::total_supply(id).encode(), + BalanceOf { id, owner } => AssetsOf::::balance(id, owner).encode(), + Allowance { id, owner, spender } => { + AssetsOf::::allowance(id, &owner, &spender).encode() + }, + TokenName(id) => { + as MetadataInspect>>::name(id).encode() + }, + TokenSymbol(id) => { + as MetadataInspect>>::symbol(id).encode() + }, + TokenDecimals(id) => { + as MetadataInspect>>::decimals(id).encode() + }, + } } } } diff --git a/pallets/api/src/fungibles/tests.rs b/pallets/api/src/fungibles/tests.rs index dbfa0b34..c8de1020 100644 --- a/pallets/api/src/fungibles/tests.rs +++ b/pallets/api/src/fungibles/tests.rs @@ -1,4 +1,5 @@ -use crate::mock::*; +use crate::{fungibles::Read::*, mock::*}; +use codec::Encode; use frame_support::{ assert_ok, traits::fungibles::{approvals::Inspect, metadata::Inspect as MetadataInspect}, @@ -60,7 +61,7 @@ fn increase_allowance_works() { fn total_supply_works() { new_test_ext().execute_with(|| { create_asset_and_mint_to(ALICE, ASSET, ALICE, 100); - assert_eq!(Assets::total_supply(ASSET), Fungibles::total_supply(ASSET)); + assert_eq!(Assets::total_supply(ASSET).encode(), Fungibles::read_state(TotalSupply(ASSET))); }); } @@ -68,7 +69,10 @@ fn total_supply_works() { fn balance_of_works() { new_test_ext().execute_with(|| { create_asset_and_mint_to(ALICE, ASSET, ALICE, 100); - assert_eq!(Assets::balance(ASSET, ALICE), Fungibles::balance_of(ASSET, &ALICE)); + assert_eq!( + Assets::balance(ASSET, ALICE).encode(), + Fungibles::read_state(BalanceOf { id: ASSET, owner: ALICE }) + ); }); } @@ -77,8 +81,8 @@ fn allowance_works() { new_test_ext().execute_with(|| { create_asset_mint_and_approve(ALICE, ASSET, BOB, 100, ALICE, 50); assert_eq!( - Assets::allowance(ASSET, &ALICE, &BOB), - Fungibles::allowance(ASSET, &ALICE, &BOB) + Assets::allowance(ASSET, &ALICE, &BOB).encode(), + Fungibles::read_state(Allowance { id: ASSET, owner: ALICE, spender: BOB }) ); }); } @@ -90,9 +94,9 @@ fn token_metadata_works() { let symbol: Vec = vec![21, 22, 23]; let decimals: u8 = 69; create_asset_and_set_metadata(ALICE, ASSET, name.clone(), symbol.clone(), decimals); - assert_eq!(Assets::name(ASSET), Fungibles::token_name(ASSET)); - assert_eq!(Assets::symbol(ASSET), Fungibles::token_symbol(ASSET)); - assert_eq!(Assets::decimals(ASSET), Fungibles::token_decimals(ASSET)); + assert_eq!(Assets::name(ASSET).encode(), Fungibles::read_state(TokenName(ASSET))); + assert_eq!(Assets::symbol(ASSET).encode(), Fungibles::read_state(TokenSymbol(ASSET))); + assert_eq!(Assets::decimals(ASSET).encode(), Fungibles::read_state(TokenDecimals(ASSET))); }); } diff --git a/pop-api/src/lib.rs b/pop-api/src/lib.rs index efa7ecb2..7fcfc85b 100644 --- a/pop-api/src/lib.rs +++ b/pop-api/src/lib.rs @@ -1,9 +1,7 @@ #![cfg_attr(not(feature = "std"), no_std, no_main)] -use ink::env::chain_extension::ChainExtensionMethod; - use constants::DECODING_FAILED; -use ink::env::chain_extension::FromStatusCode; +use ink::env::chain_extension::{ChainExtensionMethod, FromStatusCode}; #[cfg(feature = "assets")] pub use v0::assets; diff --git a/pop-api/src/v0/assets/fungibles.rs b/pop-api/src/v0/assets/fungibles.rs index 374b6e88..0712a80b 100644 --- a/pop-api/src/v0/assets/fungibles.rs +++ b/pop-api/src/v0/assets/fungibles.rs @@ -1,12 +1,10 @@ -use ink::{env::chain_extension::ChainExtensionMethod, prelude::vec::Vec, scale::Decode}; - use crate::{ - constants::{ASSETS, BALANCES, DECODING_FAILED, FUNGIBLES}, + constants::{ASSETS, BALANCES, FUNGIBLES}, primitives::{AccountId, AssetId, Balance}, - v0::V0, Result, StatusCode, }; use constants::*; +use ink::{env::chain_extension::ChainExtensionMethod, prelude::vec::Vec}; pub use metadata::*; /// Helper method to build a dispatch call `ChainExtensionMethod` for fungibles `v0` @@ -78,10 +76,9 @@ mod constants { pub fn total_supply(id: AssetId) -> Result { build_read_state(TOTAL_SUPPLY) .input::() - .output::>, true>() + .output::, true>() .handle_error_code::() .call(&(id)) - .and_then(|v| Balance::decode(&mut &v[..]).map_err(|_e| StatusCode(DECODING_FAILED))) } /// Returns the account balance for the specified `owner` for a given asset ID. Returns `0` if @@ -97,10 +94,9 @@ pub fn total_supply(id: AssetId) -> Result { pub fn balance_of(id: AssetId, owner: AccountId) -> Result { build_read_state(BALANCE_OF) .input::<(AssetId, AccountId)>() - .output::>, true>() + .output::, true>() .handle_error_code::() .call(&(id, owner)) - .and_then(|v| Balance::decode(&mut &v[..]).map_err(|_e| StatusCode(DECODING_FAILED))) } /// Returns the amount which `spender` is still allowed to withdraw from `owner` for a given @@ -117,10 +113,9 @@ pub fn balance_of(id: AssetId, owner: AccountId) -> Result { pub fn allowance(id: AssetId, owner: AccountId, spender: AccountId) -> Result { build_read_state(ALLOWANCE) .input::<(AssetId, AccountId, AccountId)>() - .output::>, true>() + .output::, true>() .handle_error_code::() .call(&(id, owner, spender)) - .and_then(|v| Balance::decode(&mut &v[..]).map_err(|_e| StatusCode(DECODING_FAILED))) } /// Transfers `value` amount of tokens from the caller's account to account `to`, with additional @@ -233,7 +228,6 @@ pub mod metadata { .output::>, true>() .handle_error_code::() .call(&(id)) - .and_then(|v| >::decode(&mut &v[..]).map_err(|_e| StatusCode(DECODING_FAILED))) } /// Returns the token symbol for a given asset ID. @@ -250,7 +244,6 @@ pub mod metadata { .output::>, true>() .handle_error_code::() .call(&(id)) - .and_then(|v| >::decode(&mut &v[..]).map_err(|_e| StatusCode(DECODING_FAILED))) } /// Returns the token decimals for a given asset ID. @@ -264,10 +257,9 @@ pub mod metadata { pub fn token_decimals(id: AssetId) -> Result { build_read_state(TOKEN_DECIMALS) .input::() - .output::>, true>() + .output::, true>() .handle_error_code::() .call(&(id)) - .and_then(|v| ::decode(&mut &v[..]).map_err(|_e| StatusCode(DECODING_FAILED))) } } diff --git a/pop-api/src/v0/assets/mod.rs b/pop-api/src/v0/assets/mod.rs index c68c0181..197db710 100644 --- a/pop-api/src/v0/assets/mod.rs +++ b/pop-api/src/v0/assets/mod.rs @@ -1,3 +1,2 @@ #[cfg(feature = "fungibles")] pub mod fungibles; - diff --git a/runtime/devnet/src/config/api.rs b/runtime/devnet/src/config/api.rs index ae179e4a..884128f2 100644 --- a/runtime/devnet/src/config/api.rs +++ b/runtime/devnet/src/config/api.rs @@ -11,24 +11,37 @@ pub enum RuntimeRead { Fungibles(fungibles::Read), } -impl fungibles::Config for Runtime { - type AssetsInstance = TrustBackedAssetsInstance; - type WeightInfo = fungibles::weights::SubstrateWeight; -} - -/// A type to identify allowed calls to the Runtime from contracts. Used by Pop API +/// A type to identify allowed calls to the Runtime from the API. pub struct AllowedApiCalls; impl Contains for AllowedApiCalls { + /// Allowed runtime calls from the API. fn contains(c: &RuntimeCall) -> bool { - use fungibles::Call as FungiblesCall; + use fungibles::Call::*; + matches!( + c, + RuntimeCall::Fungibles(transfer { .. } | approve { .. } | increase_allowance { .. }) + ) + } +} + +impl Contains> for AllowedApiCalls { + /// Allowed state queries from the API. + fn contains(c: &RuntimeRead) -> bool { + use fungibles::Read::*; matches!( c, - RuntimeCall::Fungibles( - FungiblesCall::transfer { .. } - | FungiblesCall::approve { .. } - | FungiblesCall::increase_allowance { .. } + RuntimeRead::Fungibles( + TotalSupply(..) + | BalanceOf { .. } | Allowance { .. } + | TokenName(..) | TokenSymbol(..) + | TokenDecimals(..) ) ) } } + +impl fungibles::Config for Runtime { + type AssetsInstance = TrustBackedAssetsInstance; + type WeightInfo = fungibles::weights::SubstrateWeight; +} diff --git a/runtime/devnet/src/extensions/mod.rs b/runtime/devnet/src/extensions/mod.rs index 3aed89df..d3bbdd0b 100644 --- a/runtime/devnet/src/extensions/mod.rs +++ b/runtime/devnet/src/extensions/mod.rs @@ -5,10 +5,7 @@ use crate::{ api::{AllowedApiCalls, RuntimeRead}, assets::TrustBackedAssetsInstance, }, - fungibles::{ - self, - Read::{self, *}, - }, + fungibles::{self}, AccountId, RuntimeCall, RuntimeOrigin, }; use codec::{Decode, Encode}; @@ -26,6 +23,14 @@ use sp_runtime::{traits::Dispatchable, DispatchError}; use sp_std::vec::Vec; const LOG_TARGET: &str = "pop-api::extension"; +const DECODING_FAILED_ERROR: DispatchError = DispatchError::Other("DecodingFailed"); +// TODO: issue #93, we can also encode the `pop_primitives::Error::UnknownCall` which means we do use +// `Error` in the runtime and it should stay in primitives. Perhaps issue #91 will also influence +// here. Should be looked at together. +const DECODING_FAILED_ERROR_ENCODED: [u8; 4] = [255u8, 0, 0, 0]; +const UNKNOWN_CALL_ERROR: DispatchError = DispatchError::Other("UnknownCall"); +// TODO: see above. +const UNKNOWN_CALL_ERROR_ENCODED: [u8; 4] = [254u8, 0, 0, 0]; type ContractSchedule = ::Schedule; @@ -113,8 +118,7 @@ where params.insert(0, version); params.insert(1, pallet_index); params.insert(2, call_index); - let call = ::decode(&mut ¶ms[..]) - .map_err(|_| DispatchError::Other("DecodingFailed"))?; + let call = ::decode(&mut ¶ms[..]).map_err(|_| DECODING_FAILED_ERROR)?; // Contract is the origin by default. let origin: RuntimeOrigin = RawOrigin::Signed(env.ext().address().clone()).into(); @@ -169,19 +173,24 @@ where { const LOG_PREFIX: &str = " read_state |"; - // Prefix params with version, pallet, index to simplify decoding. + // Prefix params with version, pallet, index to simplify decoding, and decode parameters for + // reading state. params.insert(0, version); params.insert(1, pallet_index); params.insert(2, call_index); - let key = >::decode(&mut ¶ms[..]) - .map_err(|_| DispatchError::Other("DecodingFailed"))?; + let read = + >::decode(&mut ¶ms[..]).map_err(|_| DECODING_FAILED_ERROR)?; - let result = match key { - VersionedStateRead::V0(key) => match key { - RuntimeRead::Fungibles(key) => read_fungibles_state::(key, env), + // Charge weight for doing one storage read. + env.charge_weight(T::DbWeight::get().reads(1_u64))?; + let result = match read { + VersionedStateRead::V0(read) => { + ensure!(AllowedApiCalls::contains(&read), UNKNOWN_CALL_ERROR); + match read { + RuntimeRead::Fungibles(key) => fungibles::Pallet::::read_state(key), + } }, - }? - .encode(); + }; log::trace!( target:LOG_TARGET, "{} result: {:?}.", LOG_PREFIX, result @@ -218,16 +227,18 @@ enum VersionedDispatch { // - `error`: The `DispatchError` encountered during contract execution. // - `version`: The version of the chain extension, used to determine the known errors. pub(crate) fn convert_to_status_code(error: DispatchError, version: u8) -> u32 { - // "UnknownFunctionId" and "DecodingFailed" are mapped to specific errors in the API and will - // never change. - let mut encoded_error = match error { - DispatchError::Other("UnknownFunctionId") => Vec::from([254u8, 0, 0, 0]), - DispatchError::Other("DecodingFailed") => Vec::from([255u8, 0, 0, 0]), - _ => error.encode(), + let mut encoded_error: [u8; 4] = match error { + // "UnknownCall" and "DecodingFailed" are mapped to specific errors in the API and will + // never change. + UNKNOWN_CALL_ERROR => UNKNOWN_CALL_ERROR_ENCODED, + DECODING_FAILED_ERROR => DECODING_FAILED_ERROR_ENCODED, + _ => { + let mut encoded_error = error.encode(); + // Resize the encoded value to 4 bytes in order to decode the value in a u32 (4 bytes). + encoded_error.resize(4, 0); + encoded_error.try_into().expect("qed, resized to 4 bytes line above") + }, }; - // Resize the encoded value to 4 bytes in order to decode the value in a u32 (4 bytes). - encoded_error.resize(4, 0); - let mut encoded_error = encoded_error.try_into().expect("qed, resized to 4 bytes line above"); match version { // If an unknown variant of the `DispatchError` is detected the error needs to be converted // into the encoded value of `Error::Other`. This conversion is performed by shifting the bytes one @@ -246,7 +257,7 @@ pub(crate) fn convert_to_status_code(error: DispatchError, version: u8) -> u32 { // - Byte 3: // - Unused or represents further nested information. 0 => v0::handle_unknown_error(&mut encoded_error), - _ => encoded_error = [254, 0, 0, 0], + _ => encoded_error = UNKNOWN_CALL_ERROR_ENCODED, } u32::from_le_bytes(encoded_error) } @@ -278,37 +289,13 @@ impl TryFrom for FuncId { 0 => Self::Dispatch, 1 => Self::ReadState, _ => { - return Err(DispatchError::Other("UnknownFuncId")); + return Err(UNKNOWN_CALL_ERROR); }, }; Ok(id) } } -fn read_fungibles_state( - key: Read, - env: &mut Environment, -) -> Result, DispatchError> -where - T: pallet_contracts::Config - + pallet_assets::Config - + fungibles::Config, - E: Ext, - T: frame_system::Config, -{ - env.charge_weight(T::DbWeight::get().reads(1_u64))?; - match key { - TotalSupply(id) => Ok(fungibles::Pallet::::total_supply(id).encode()), - BalanceOf { id, owner } => Ok(fungibles::Pallet::::balance_of(id, &owner).encode()), - Allowance { id, owner, spender } => { - Ok(fungibles::Pallet::::allowance(id, &owner, &spender).encode()) - }, - TokenName(id) => Ok(fungibles::Pallet::::token_name(id).encode()), - TokenSymbol(id) => Ok(fungibles::Pallet::::token_symbol(id).encode()), - TokenDecimals(id) => Ok(fungibles::Pallet::::token_decimals(id).encode()), - } -} - #[cfg(test)] mod tests { use super::*; diff --git a/runtime/devnet/src/extensions/v0.rs b/runtime/devnet/src/extensions/v0.rs index b26668f7..72760323 100644 --- a/runtime/devnet/src/extensions/v0.rs +++ b/runtime/devnet/src/extensions/v0.rs @@ -76,7 +76,7 @@ mod tests { DispatchError::Other(""), (Other { dispatch_error_index: 0, error_index: 0, error: 0 }), ), - (DispatchError::Other("UnknownFunctionId"), UnknownCall), + (DispatchError::Other("UnknownCall"), UnknownCall), (DispatchError::Other("DecodingFailed"), DecodingFailed), (DispatchError::CannotLookup, CannotLookup), (DispatchError::BadOrigin, BadOrigin), @@ -120,7 +120,7 @@ mod tests { DispatchError::Other("Random"), (Other { dispatch_error_index: 0, error_index: 0, error: 0 }), ), - (DispatchError::Other("UnknownFunctionId"), UnknownCall), + (DispatchError::Other("UnknownCall"), UnknownCall), (DispatchError::Other("DecodingFailed"), DecodingFailed), ]; for (dispatch_error, expected) in test_cases { From 5ac5a9a520dea12f8d8c14e1bd7cfeb57a3ec7bd Mon Sep 17 00:00:00 2001 From: Tin Chung <56880684+chungquantin@users.noreply.github.com> Date: Wed, 31 Jul 2024 14:12:25 +0700 Subject: [PATCH 033/112] feat: transfer_from and decrease_allowance (#134) Co-authored-by: Daan van der Plas <93204684+Daanvdplas@users.noreply.github.com> --- pallets/api/src/fungibles/mod.rs | 80 ++++++++++-- pallets/api/src/fungibles/tests.rs | 37 ++++++ pallets/api/src/mock.rs | 3 +- .../integration-tests/src/local_fungibles.rs | 115 +++++++++++++++++- runtime/devnet/src/config/api.rs | 7 +- 5 files changed, 228 insertions(+), 14 deletions(-) diff --git a/pallets/api/src/fungibles/mod.rs b/pallets/api/src/fungibles/mod.rs index 32f9af67..9fb444f8 100644 --- a/pallets/api/src/fungibles/mod.rs +++ b/pallets/api/src/fungibles/mod.rs @@ -110,6 +110,28 @@ pub mod pallet { AssetsOf::::transfer_keep_alive(origin, id.into(), target, amount) } + /// Transfers `value` amount of tokens from the delegated account approved by the `owner` to + /// account `to`, with additional `data` in unspecified format. + /// + /// # Parameters + /// * `id` - The ID of the asset. + /// * `owner` - The account from which the asset balance will be withdrawn. + /// * `to` - The recipient account. + /// * `value` - The number of tokens to transfer. + #[pallet::call_index(4)] + #[pallet::weight(AssetsWeightInfoOf::::transfer_approved())] + pub fn transfer_from( + origin: OriginFor, + id: AssetIdOf, + owner: AccountIdOf, + target: AccountIdOf, + amount: BalanceOf, + ) -> DispatchResult { + let owner = T::Lookup::unlookup(owner); + let target = T::Lookup::unlookup(target); + AssetsOf::::transfer_approved(origin, id.into(), owner, target, amount) + } + /// Approves an account to spend a specified number of tokens on behalf of the caller. /// /// # Parameters @@ -124,17 +146,15 @@ pub mod pallet { spender: AccountIdOf, value: BalanceOf, ) -> DispatchResultWithPostInfo { - let weight = |approve: u32, cancel: u32| -> Weight { - ::WeightInfo::approve(cancel, approve) - }; - let who = ensure_signed(origin.clone()).map_err(|e| e.with_weight(weight(0, 0)))?; + let who = ensure_signed(origin.clone()) + .map_err(|e| e.with_weight(Self::weight_approve(0, 0)))?; let current_allowance = AssetsOf::::allowance(id.clone(), &who, &spender); let spender = T::Lookup::unlookup(spender); let id: AssetIdParameterOf = id.into(); // If the new value is equal to the current allowance, do nothing. let return_weight = if value == current_allowance { - weight(0, 0) + Self::weight_approve(0, 0) } // If the new value is greater than the current allowance, approve the difference // because `approve_transfer` works additively (see `pallet-assets`). @@ -145,17 +165,17 @@ pub mod pallet { spender, value.saturating_sub(current_allowance), ) - .map_err(|e| e.with_weight(weight(1, 0)))?; - weight(1, 0) + .map_err(|e| e.with_weight(Self::weight_approve(1, 0)))?; + Self::weight_approve(1, 0) } else { // If the new value is less than the current allowance, cancel the approval and set the new value AssetsOf::::cancel_approval(origin.clone(), id.clone(), spender.clone()) - .map_err(|e| e.with_weight(weight(0, 1)))?; + .map_err(|e| e.with_weight(Self::weight_approve(0, 1)))?; if value.is_zero() { - return Ok(Some(weight(0, 1)).into()); + return Ok(Some(Self::weight_approve(0, 1)).into()); } AssetsOf::::approve_transfer(origin, id, spender, value)?; - weight(1, 1) + Self::weight_approve(1, 1) }; Ok(Some(return_weight).into()) } @@ -177,6 +197,42 @@ pub mod pallet { let spender = T::Lookup::unlookup(spender); AssetsOf::::approve_transfer(origin, id.into(), spender, value) } + + /// Decreases the allowance of a spender. + /// + /// # Parameters + /// * `id` - The ID of the asset. + /// * `spender` - The account that is allowed to spend the tokens. + /// * `value` - The number of tokens to decrease the allowance by. + #[pallet::call_index(7)] + #[pallet::weight(::WeightInfo::approve(1, 1))] + pub fn decrease_allowance( + origin: OriginFor, + id: AssetIdOf, + spender: AccountIdOf, + value: BalanceOf, + ) -> DispatchResultWithPostInfo { + let who = ensure_signed(origin.clone()) + .map_err(|e| e.with_weight(Self::weight_approve(0, 0)))?; + let mut current_allowance = AssetsOf::::allowance(id.clone(), &who, &spender); + let spender = T::Lookup::unlookup(spender); + let id: AssetIdParameterOf = id.into(); + + if value.is_zero() { + return Ok(Some(Self::weight_approve(0, 0)).into()); + } + + current_allowance.saturating_reduce(value); + // Cancel the aproval and set the new value if `current_allowance` is more than zero. + AssetsOf::::cancel_approval(origin.clone(), id.clone(), spender.clone()) + .map_err(|e| e.with_weight(Self::weight_approve(0, 1)))?; + + if current_allowance.is_zero() { + return Ok(Some(Self::weight_approve(0, 1)).into()); + } + AssetsOf::::approve_transfer(origin, id, spender, current_allowance)?; + Ok(().into()) + } } impl Pallet { @@ -208,5 +264,9 @@ pub mod pallet { }, } } + + pub fn weight_approve(approve: u32, cancel: u32) -> Weight { + ::WeightInfo::approve(cancel, approve) + } } } diff --git a/pallets/api/src/fungibles/tests.rs b/pallets/api/src/fungibles/tests.rs index c8de1020..4377fc83 100644 --- a/pallets/api/src/fungibles/tests.rs +++ b/pallets/api/src/fungibles/tests.rs @@ -19,6 +19,43 @@ fn transfer_works() { }); } +#[test] +fn transfer_from_works() { + new_test_ext().execute_with(|| { + let amount: Balance = 100 * UNIT; + // Approve CHARLIE to transfer up to `amount` to BOB. + create_asset_mint_and_approve(ALICE, ASSET, ALICE, amount * 2, CHARLIE, amount / 2); + let transferred = amount / 2; + // Successfully call transfer from. + let alice_balance_before_transfer = Assets::balance(ASSET, &ALICE); + let balance_before_transfer = Assets::balance(ASSET, &BOB); + assert_ok!(Fungibles::transfer_from(signed(CHARLIE), ASSET, ALICE, BOB, transferred)); + let alice_balance_after_transfer = Assets::balance(ASSET, &ALICE); + let balance_after_transfer = Assets::balance(ASSET, &BOB); + // Check that BOB receives the `amount` and ALICE `amount` is spent successfully by CHARLIE. + assert_eq!(balance_after_transfer, balance_before_transfer + transferred); + assert_eq!(alice_balance_after_transfer, alice_balance_before_transfer - transferred); + }); +} + +#[test] +fn decrease_allowance_works() { + new_test_ext().execute_with(|| { + let amount: Balance = 100 * UNIT; + create_asset_mint_and_approve(ALICE, ASSET, ALICE, amount, BOB, amount); + assert_eq!(Assets::allowance(ASSET, &ALICE, &BOB), amount); + // Owner balance is not changed if decreased by zero. + assert_ok!(Fungibles::decrease_allowance(signed(ALICE), ASSET, BOB, 0)); + assert_eq!(Assets::allowance(ASSET, &ALICE, &BOB), amount); + // Decrease allowance successfully. + assert_ok!(Fungibles::decrease_allowance(signed(ALICE), ASSET, BOB, amount / 2 - 1 * UNIT)); + assert_eq!(Assets::allowance(ASSET, &ALICE, &BOB), amount / 2 + 1 * UNIT); + // Saturating if current allowance is decreased more than the owner balance. + assert_ok!(Fungibles::decrease_allowance(signed(ALICE), ASSET, BOB, amount)); + assert_eq!(Assets::allowance(ASSET, &ALICE, &BOB), 0); + }); +} + // Non-additive, sets new value. #[test] fn approve_works() { diff --git a/pallets/api/src/mock.rs b/pallets/api/src/mock.rs index f5d155ef..b20e2635 100644 --- a/pallets/api/src/mock.rs +++ b/pallets/api/src/mock.rs @@ -103,6 +103,7 @@ impl crate::fungibles::Config for Test { pub(crate) const ALICE: AccountId = 1; pub(crate) const BOB: AccountId = 2; +pub(crate) const CHARLIE: AccountId = 3; pub(crate) const INIT_AMOUNT: Balance = 100_000_000 * UNIT; pub(crate) const UNIT: Balance = 10_000_000_000; @@ -112,7 +113,7 @@ pub(crate) fn new_test_ext() -> sp_io::TestExternalities { .expect("Frame system builds valid default genesis config"); pallet_balances::GenesisConfig:: { - balances: vec![(ALICE, INIT_AMOUNT), (BOB, INIT_AMOUNT)], + balances: vec![(ALICE, INIT_AMOUNT), (BOB, INIT_AMOUNT), (CHARLIE, INIT_AMOUNT)], } .assimilate_storage(&mut t) .expect("Pallet balances storage can be assimilated"); diff --git a/pop-api/integration-tests/src/local_fungibles.rs b/pop-api/integration-tests/src/local_fungibles.rs index 6de57ca4..15a644ad 100644 --- a/pop-api/integration-tests/src/local_fungibles.rs +++ b/pop-api/integration-tests/src/local_fungibles.rs @@ -78,6 +78,22 @@ fn transfer( result } +fn transfer_from( + addr: AccountId32, + asset_id: AssetId, + from: AccountId32, + to: AccountId32, + value: Balance, +) -> ExecReturnValue { + let function = function_selector("transfer_from"); + let data: Vec = vec![]; + let params = + [function, asset_id.encode(), from.encode(), to.encode(), value.encode(), data.encode()] + .concat(); + let result = bare_call(addr, params, 0).expect("should work"); + result +} + fn approve( addr: AccountId32, asset_id: AssetId, @@ -102,6 +118,18 @@ fn increase_allowance( result } +fn decrease_allowance( + addr: AccountId32, + asset_id: AssetId, + spender: AccountId32, + value: Balance, +) -> ExecReturnValue { + let function = function_selector("decrease_allowance"); + let params = [function, asset_id.encode(), spender.encode(), value.encode()].concat(); + let result = bare_call(addr, params, 0).expect("should work"); + result +} + // fn asset_exists(addr: AccountId32, asset_id: AssetId) -> bool { // let function = function_selector("asset_exists"); // let params = [function, asset_id.encode()].concat(); @@ -171,14 +199,15 @@ fn create_asset_mint_and_approve( mint: Balance, spender: AccountId32, approve: Balance, -) { - create_asset_and_mint_to(owner.clone(), asset_id, to.clone(), mint); +) -> AssetId { + let asset = create_asset_and_mint_to(owner.clone(), asset_id, to.clone(), mint); assert_ok!(Assets::approve_transfer( RuntimeOrigin::signed(to.into()), asset_id.into(), spender.into(), approve, )); + asset } // Freeze an asset. @@ -366,6 +395,52 @@ fn transfer_works() { }); } +#[test] +fn transfer_from_works() { + new_test_ext().execute_with(|| { + let _ = env_logger::try_init(); + let addr = instantiate(CONTRACT, INIT_VALUE, vec![]); + let amount: Balance = 100 * UNIT; + + // Asset does not exist. + assert_eq!( + decoded::(transfer_from(addr.clone(), 1, ALICE, BOB, amount / 2)), + Ok(Module { index: 52, error: 3 }), + ); + // Create asset with Alice as owner and mint `amount` to contract address. + let asset = create_asset_and_mint_to(ALICE, 1, ALICE, amount); + // Unapproved transfer. + assert_eq!( + decoded::(transfer_from(addr.clone(), asset, ALICE, BOB, amount / 2)), + Ok(Module { index: 52, error: 10 }) + ); + assert_ok!(Assets::approve_transfer( + RuntimeOrigin::signed(ALICE.into()), + asset.into(), + addr.clone().into(), + amount + 1 * UNIT, + )); + // Asset is not live, i.e. frozen or being destroyed. + freeze_asset(ALICE, asset); + assert_eq!( + decoded::(transfer_from(addr.clone(), asset, ALICE, BOB, amount)), + Ok(Module { index: 52, error: 16 }), + ); + thaw_asset(ALICE, asset); + // Not enough balance. + assert_eq!( + decoded::(transfer_from(addr.clone(), asset, ALICE, BOB, amount + 1 * UNIT,)), + Ok(Module { index: 52, error: 0 }), + ); + // Successful transfer. + let balance_before_transfer = Assets::balance(asset, &BOB); + let result = transfer_from(addr.clone(), asset, ALICE, BOB, amount / 2); + assert!(!result.did_revert(), "Contract reverted!"); + let balance_after_transfer = Assets::balance(asset, &BOB); + assert_eq!(balance_after_transfer, balance_before_transfer + amount / 2); + }); +} + #[test] fn approve_works() { new_test_ext().execute_with(|| { @@ -458,6 +533,42 @@ fn increase_allowance_works() { }); } +#[test] +fn decrease_allowance_works() { + new_test_ext().execute_with(|| { + let _ = env_logger::try_init(); + let addr = instantiate(CONTRACT, INIT_VALUE, vec![]); + let amount: Balance = 100 * UNIT; + // Asset does not exist. + assert_eq!( + decoded::(decrease_allowance(addr.clone(), 0, BOB, amount)), + Ok(Module { index: 52, error: 3 }), + ); + // Create asset and mint to the address contract, delegate Bob to spend the `amount`. + let asset = + create_asset_mint_and_approve(addr.clone(), 0, addr.clone(), amount, BOB, amount); + // Asset is not live, i.e. frozen or being destroyed. + freeze_asset(addr.clone(), asset); + assert_eq!( + decoded::(decrease_allowance(addr.clone(), asset, BOB, amount)), + Ok(Module { index: 52, error: 16 }), + ); + thaw_asset(addr.clone(), asset); + // Successfully decrease allowance. + let bob_allowance_before = Assets::allowance(asset, &addr, &BOB); + let result = decrease_allowance(addr.clone(), 0, BOB, amount / 2 - 1 * UNIT); + assert!(!result.did_revert(), "Contract reverted!"); + let bob_allowance_after = Assets::allowance(asset, &addr, &BOB); + assert_eq!(bob_allowance_before - bob_allowance_after, amount / 2 - 1 * UNIT); + // Asset is not live, i.e. frozen or being destroyed. + start_destroy_asset(addr.clone(), asset); + assert_eq!( + decoded::(decrease_allowance(addr.clone(), asset, BOB, amount)), + Ok(Module { index: 52, error: 16 }), + ); + }); +} + /// 2. PSP-22 Metadata Interface: /// - token_name /// - token_symbol diff --git a/runtime/devnet/src/config/api.rs b/runtime/devnet/src/config/api.rs index 884128f2..b3932a79 100644 --- a/runtime/devnet/src/config/api.rs +++ b/runtime/devnet/src/config/api.rs @@ -20,7 +20,12 @@ impl Contains for AllowedApiCalls { use fungibles::Call::*; matches!( c, - RuntimeCall::Fungibles(transfer { .. } | approve { .. } | increase_allowance { .. }) + RuntimeCall::Fungibles( + transfer { .. } + | transfer_from { .. } + | approve { .. } | increase_allowance { .. } + | decrease_allowance { .. } + ) ) } } From d8ac5bd433b04359c45987ca5c3d0e78855c59a8 Mon Sep 17 00:00:00 2001 From: Daan van der Plas <93204684+Daanvdplas@users.noreply.github.com> Date: Tue, 6 Aug 2024 14:45:07 +0200 Subject: [PATCH 034/112] refactor: api integration tests (#133) Co-authored-by: Frank Bell --- pallets/api/src/fungibles/mod.rs | 222 ++++-- pallets/api/src/fungibles/tests.rs | 129 ++- pop-api/examples/balance-transfer/lib.rs | 3 +- pop-api/examples/nfts/lib.rs | 49 +- pop-api/examples/place-spot-order/lib.rs | 14 +- pop-api/examples/read-runtime-state/lib.rs | 55 +- .../integration-tests/contracts/.gitignore | 9 + .../create_token_in_constructor/Cargo.toml | 21 + .../create_token_in_constructor/lib.rs | 46 ++ .../contracts/fungibles/lib.rs | 100 +-- .../integration-tests/src/fungibles/mod.rs | 546 +++++++++++++ .../integration-tests/src/fungibles/utils.rs | 360 +++++++++ pop-api/integration-tests/src/lib.rs | 2 +- .../integration-tests/src/local_fungibles.rs | 738 ------------------ pop-api/src/lib.rs | 18 +- pop-api/src/v0/assets/fungibles.rs | 344 ++++---- runtime/devnet/src/config/api.rs | 6 +- 17 files changed, 1559 insertions(+), 1103 deletions(-) create mode 100755 pop-api/integration-tests/contracts/.gitignore create mode 100755 pop-api/integration-tests/contracts/create_token_in_constructor/Cargo.toml create mode 100755 pop-api/integration-tests/contracts/create_token_in_constructor/lib.rs create mode 100644 pop-api/integration-tests/src/fungibles/mod.rs create mode 100644 pop-api/integration-tests/src/fungibles/utils.rs delete mode 100644 pop-api/integration-tests/src/local_fungibles.rs diff --git a/pallets/api/src/fungibles/mod.rs b/pallets/api/src/fungibles/mod.rs index 9fb444f8..eefad0e1 100644 --- a/pallets/api/src/fungibles/mod.rs +++ b/pallets/api/src/fungibles/mod.rs @@ -28,6 +28,7 @@ type BalanceOf = > as Inspect< #[frame_support::pallet] pub mod pallet { use super::*; + use core::cmp::Ordering::*; use frame_support::{ dispatch::{DispatchResult, DispatchResultWithPostInfo, WithPostDispatchInfo}, pallet_prelude::*, @@ -75,6 +76,9 @@ pub mod pallet { /// Token decimals for a given asset ID. #[codec(index = 10)] TokenDecimals(AssetIdOf), + /// Check if token with a given asset ID exists. + #[codec(index = 18)] + AssetExists(AssetIdOf), } /// Configure the pallet by specifying the parameters and types on which it depends. @@ -95,49 +99,49 @@ pub mod pallet { /// `data` in unspecified format. /// /// # Parameters - /// * `id` - The ID of the asset. - /// * `to` - The recipient account. - /// * `value` - The number of tokens to transfer. + /// - `id` - The ID of the asset. + /// - `to` - The recipient account. + /// - `value` - The number of tokens to transfer. #[pallet::call_index(3)] #[pallet::weight(AssetsWeightInfoOf::::transfer_keep_alive())] pub fn transfer( origin: OriginFor, id: AssetIdOf, - target: AccountIdOf, - amount: BalanceOf, + to: AccountIdOf, + value: BalanceOf, ) -> DispatchResult { - let target = T::Lookup::unlookup(target); - AssetsOf::::transfer_keep_alive(origin, id.into(), target, amount) + let to = T::Lookup::unlookup(to); + AssetsOf::::transfer_keep_alive(origin, id.into(), to, value) } - /// Transfers `value` amount of tokens from the delegated account approved by the `owner` to - /// account `to`, with additional `data` in unspecified format. + /// Transfers `value` amount tokens on behalf of `from` to account `to` with additional `data` + /// in unspecified format. /// /// # Parameters - /// * `id` - The ID of the asset. - /// * `owner` - The account from which the asset balance will be withdrawn. - /// * `to` - The recipient account. - /// * `value` - The number of tokens to transfer. + /// - `id` - The ID of the asset. + /// - `owner` - The account from which the asset balance will be withdrawn. + /// - `to` - The recipient account. + /// - `value` - The number of tokens to transfer. #[pallet::call_index(4)] #[pallet::weight(AssetsWeightInfoOf::::transfer_approved())] pub fn transfer_from( origin: OriginFor, id: AssetIdOf, - owner: AccountIdOf, - target: AccountIdOf, - amount: BalanceOf, + from: AccountIdOf, + to: AccountIdOf, + value: BalanceOf, ) -> DispatchResult { - let owner = T::Lookup::unlookup(owner); - let target = T::Lookup::unlookup(target); - AssetsOf::::transfer_approved(origin, id.into(), owner, target, amount) + let from = T::Lookup::unlookup(from); + let to = T::Lookup::unlookup(to); + AssetsOf::::transfer_approved(origin, id.into(), from, to, value) } /// Approves an account to spend a specified number of tokens on behalf of the caller. /// /// # Parameters - /// * `id` - The ID of the asset. - /// * `spender` - The account that is allowed to spend the tokens. - /// * `value` - The number of tokens to approve. + /// - `id` - The ID of the asset. + /// - `spender` - The account that is allowed to spend the tokens. + /// - `value` - The number of tokens to approve. #[pallet::call_index(5)] #[pallet::weight(::WeightInfo::approve(1, 1))] pub fn approve( @@ -152,30 +156,32 @@ pub mod pallet { let spender = T::Lookup::unlookup(spender); let id: AssetIdParameterOf = id.into(); - // If the new value is equal to the current allowance, do nothing. - let return_weight = if value == current_allowance { - Self::weight_approve(0, 0) - } - // If the new value is greater than the current allowance, approve the difference - // because `approve_transfer` works additively (see `pallet-assets`). - else if value > current_allowance { - AssetsOf::::approve_transfer( - origin, - id, - spender, - value.saturating_sub(current_allowance), - ) - .map_err(|e| e.with_weight(Self::weight_approve(1, 0)))?; - Self::weight_approve(1, 0) - } else { - // If the new value is less than the current allowance, cancel the approval and set the new value - AssetsOf::::cancel_approval(origin.clone(), id.clone(), spender.clone()) - .map_err(|e| e.with_weight(Self::weight_approve(0, 1)))?; - if value.is_zero() { - return Ok(Some(Self::weight_approve(0, 1)).into()); - } - AssetsOf::::approve_transfer(origin, id, spender, value)?; - Self::weight_approve(1, 1) + let return_weight = match value.cmp(¤t_allowance) { + // If the new value is equal to the current allowance, do nothing. + Equal => Self::weight_approve(0, 0), + // If the new value is greater than the current allowance, approve the difference + // because `approve_transfer` works additively (see `pallet-assets`). + Greater => { + AssetsOf::::approve_transfer( + origin, + id, + spender, + value.saturating_sub(current_allowance), + ) + .map_err(|e| e.with_weight(Self::weight_approve(1, 0)))?; + Self::weight_approve(1, 0) + }, + // If the new value is less than the current allowance, cancel the approval and + // set the new value. + Less => { + AssetsOf::::cancel_approval(origin.clone(), id.clone(), spender.clone()) + .map_err(|e| e.with_weight(Self::weight_approve(0, 1)))?; + if value.is_zero() { + return Ok(Some(Self::weight_approve(0, 1)).into()); + } + AssetsOf::::approve_transfer(origin, id, spender, value)?; + Self::weight_approve(1, 1) + }, }; Ok(Some(return_weight).into()) } @@ -183,9 +189,9 @@ pub mod pallet { /// Increases the allowance of a spender. /// /// # Parameters - /// * `id` - The ID of the asset. - /// * `spender` - The account that is allowed to spend the tokens. - /// * `value` - The number of tokens to increase the allowance by. + /// - `id` - The ID of the asset. + /// - `spender` - The account that is allowed to spend the tokens. + /// - `value` - The number of tokens to increase the allowance by. #[pallet::call_index(6)] #[pallet::weight(AssetsWeightInfoOf::::approve_transfer())] pub fn increase_allowance( @@ -201,9 +207,9 @@ pub mod pallet { /// Decreases the allowance of a spender. /// /// # Parameters - /// * `id` - The ID of the asset. - /// * `spender` - The account that is allowed to spend the tokens. - /// * `value` - The number of tokens to decrease the allowance by. + /// - `id` - The ID of the asset. + /// - `spender` - The account that is allowed to spend the tokens. + /// - `value` - The number of tokens to decrease the allowance by. #[pallet::call_index(7)] #[pallet::weight(::WeightInfo::approve(1, 1))] pub fn decrease_allowance( @@ -214,25 +220,118 @@ pub mod pallet { ) -> DispatchResultWithPostInfo { let who = ensure_signed(origin.clone()) .map_err(|e| e.with_weight(Self::weight_approve(0, 0)))?; - let mut current_allowance = AssetsOf::::allowance(id.clone(), &who, &spender); + let current_allowance = AssetsOf::::allowance(id.clone(), &who, &spender); let spender = T::Lookup::unlookup(spender); let id: AssetIdParameterOf = id.into(); if value.is_zero() { return Ok(Some(Self::weight_approve(0, 0)).into()); } - - current_allowance.saturating_reduce(value); - // Cancel the aproval and set the new value if `current_allowance` is more than zero. + // Cancel the aproval and set the new value if `new_allowance` is more than zero. AssetsOf::::cancel_approval(origin.clone(), id.clone(), spender.clone()) .map_err(|e| e.with_weight(Self::weight_approve(0, 1)))?; - - if current_allowance.is_zero() { + let new_allowance = current_allowance.saturating_sub(value); + if new_allowance.is_zero() { return Ok(Some(Self::weight_approve(0, 1)).into()); } - AssetsOf::::approve_transfer(origin, id, spender, current_allowance)?; + AssetsOf::::approve_transfer(origin, id, spender, new_allowance)?; Ok(().into()) } + + /// Create a new token with a given asset ID. + /// + /// # Parameters + /// - `id` - The ID of the asset. + /// - `admin` - The account that will administer the asset. + /// - `min_balance` - The minimum balance required for accounts holding this asset. + #[pallet::call_index(11)] + #[pallet::weight(AssetsWeightInfoOf::::create())] + pub fn create( + origin: OriginFor, + id: AssetIdOf, + admin: AccountIdOf, + min_balance: BalanceOf, + ) -> DispatchResult { + let admin = T::Lookup::unlookup(admin); + AssetsOf::::create(origin, id.into(), admin, min_balance) + } + + /// Start the process of destroying a token with a given asset ID. + /// + /// # Parameters + /// - `id` - The ID of the asset. + #[pallet::call_index(12)] + #[pallet::weight(AssetsWeightInfoOf::::start_destroy())] + pub fn start_destroy(origin: OriginFor, id: AssetIdOf) -> DispatchResult { + AssetsOf::::start_destroy(origin, id.into()) + } + + /// Set the metadata for a token with a given asset ID. + /// + /// # Parameters + /// - `id`: The identifier of the asset to update. + /// - `name`: The user friendly name of this asset. Limited in length by + /// `pallet_assets::Config::StringLimit`. + /// - `symbol`: The exchange symbol for this asset. Limited in length by + /// `pallet_assets::Config::StringLimit`. + /// - `decimals`: The number of decimals this asset uses to represent one unit. + #[pallet::call_index(16)] + #[pallet::weight(AssetsWeightInfoOf::::set_metadata(name.len() as u32, symbol.len() as u32))] + pub fn set_metadata( + origin: OriginFor, + id: AssetIdOf, + name: Vec, + symbol: Vec, + decimals: u8, + ) -> DispatchResult { + AssetsOf::::set_metadata(origin, id.into(), name, symbol, decimals) + } + + /// Clear the metadata for a token with a given asset ID. + /// + /// # Parameters + /// - `id` - The ID of the asset. + #[pallet::call_index(17)] + #[pallet::weight(AssetsWeightInfoOf::::clear_metadata())] + pub fn clear_metadata(origin: OriginFor, id: AssetIdOf) -> DispatchResult { + AssetsOf::::clear_metadata(origin, id.into()) + } + + /// Creates `value` amount tokens and assigns them to `account`, increasing the total supply. + /// + /// # Parameters + /// - `id` - The ID of the asset. + /// - `account` - The account to be credited with the created tokens. + /// - `value` - The number of tokens to mint. + #[pallet::call_index(19)] + #[pallet::weight(AssetsWeightInfoOf::::mint())] + pub fn mint( + origin: OriginFor, + id: AssetIdOf, + account: AccountIdOf, + value: BalanceOf, + ) -> DispatchResult { + let account = T::Lookup::unlookup(account); + AssetsOf::::mint(origin, id.into(), account, value) + } + + /// Destroys `value` amount tokens from `account`, reducing the total supply. + /// + /// # Parameters + /// - `id` - The ID of the asset. + /// - `account` - The account from which the tokens will be destroyed. + /// - `value` - The number of tokens to destroy. + #[pallet::call_index(20)] + #[pallet::weight(AssetsWeightInfoOf::::burn())] + pub fn burn( + origin: OriginFor, + id: AssetIdOf, + account: AccountIdOf, + value: BalanceOf, + ) -> DispatchResult { + let account = T::Lookup::unlookup(account); + AssetsOf::::burn(origin, id.into(), account, value) + } } impl Pallet { @@ -242,8 +341,8 @@ pub mod pallet { /// encoded result. /// /// # Parameter - /// * `value` - An instance of `Read`, which specifies the type of state query and - /// the associated parameters. + /// - `value` - An instance of `Read`, which specifies the type of state query and + /// the associated parameters. pub fn read_state(value: Read) -> Vec { use Read::*; @@ -262,6 +361,7 @@ pub mod pallet { TokenDecimals(id) => { as MetadataInspect>>::decimals(id).encode() }, + AssetExists(id) => AssetsOf::::asset_exists(id).encode(), } } diff --git a/pallets/api/src/fungibles/tests.rs b/pallets/api/src/fungibles/tests.rs index 4377fc83..d6cc87e0 100644 --- a/pallets/api/src/fungibles/tests.rs +++ b/pallets/api/src/fungibles/tests.rs @@ -2,7 +2,9 @@ use crate::{fungibles::Read::*, mock::*}; use codec::Encode; use frame_support::{ assert_ok, - traits::fungibles::{approvals::Inspect, metadata::Inspect as MetadataInspect}, + traits::fungibles::{ + approvals::Inspect as ApprovalInspect, metadata::Inspect as MetadataInspect, Inspect, + }, }; const ASSET: u32 = 42; @@ -38,24 +40,6 @@ fn transfer_from_works() { }); } -#[test] -fn decrease_allowance_works() { - new_test_ext().execute_with(|| { - let amount: Balance = 100 * UNIT; - create_asset_mint_and_approve(ALICE, ASSET, ALICE, amount, BOB, amount); - assert_eq!(Assets::allowance(ASSET, &ALICE, &BOB), amount); - // Owner balance is not changed if decreased by zero. - assert_ok!(Fungibles::decrease_allowance(signed(ALICE), ASSET, BOB, 0)); - assert_eq!(Assets::allowance(ASSET, &ALICE, &BOB), amount); - // Decrease allowance successfully. - assert_ok!(Fungibles::decrease_allowance(signed(ALICE), ASSET, BOB, amount / 2 - 1 * UNIT)); - assert_eq!(Assets::allowance(ASSET, &ALICE, &BOB), amount / 2 + 1 * UNIT); - // Saturating if current allowance is decreased more than the owner balance. - assert_ok!(Fungibles::decrease_allowance(signed(ALICE), ASSET, BOB, amount)); - assert_eq!(Assets::allowance(ASSET, &ALICE, &BOB), 0); - }); -} - // Non-additive, sets new value. #[test] fn approve_works() { @@ -94,6 +78,99 @@ fn increase_allowance_works() { }); } +#[test] +fn decrease_allowance_works() { + new_test_ext().execute_with(|| { + let amount: Balance = 100 * UNIT; + create_asset_mint_and_approve(ALICE, ASSET, ALICE, amount, BOB, amount); + assert_eq!(Assets::allowance(ASSET, &ALICE, &BOB), amount); + // Owner balance is not changed if decreased by zero. + assert_ok!(Fungibles::decrease_allowance(signed(ALICE), ASSET, BOB, 0)); + assert_eq!(Assets::allowance(ASSET, &ALICE, &BOB), amount); + // Decrease allowance successfully. + assert_ok!(Fungibles::decrease_allowance(signed(ALICE), ASSET, BOB, amount / 2 - 1 * UNIT)); + assert_eq!(Assets::allowance(ASSET, &ALICE, &BOB), amount / 2 + 1 * UNIT); + // Saturating if current allowance is decreased more than the owner balance. + assert_ok!(Fungibles::decrease_allowance(signed(ALICE), ASSET, BOB, amount)); + assert_eq!(Assets::allowance(ASSET, &ALICE, &BOB), 0); + }); +} + +#[test] +fn create_works() { + new_test_ext().execute_with(|| { + assert!(!Assets::asset_exists(ASSET)); + assert_ok!(Fungibles::create(signed(ALICE), ASSET, ALICE, 100)); + assert!(Assets::asset_exists(ASSET)); + }); +} + +#[test] +fn start_destroy_works() { + new_test_ext().execute_with(|| { + create_asset(ALICE, ASSET); + assert_ok!(Fungibles::start_destroy(signed(ALICE), ASSET)); + }); +} + +#[test] +fn set_metadata_works() { + new_test_ext().execute_with(|| { + let name = vec![42]; + let symbol = vec![42]; + let decimals = 42; + create_asset(ALICE, ASSET); + assert_ok!(Fungibles::set_metadata( + signed(ALICE), + ASSET, + name.clone(), + symbol.clone(), + decimals + )); + assert_eq!(Assets::name(ASSET), name); + assert_eq!(Assets::symbol(ASSET), symbol); + assert_eq!(Assets::decimals(ASSET), decimals); + }); +} + +#[test] +fn clear_metadata_works() { + new_test_ext().execute_with(|| { + let name = vec![42]; + let symbol = vec![42]; + let decimals = 42; + create_asset_and_set_metadata(ALICE, ASSET, name, symbol, decimals); + assert_ok!(Fungibles::clear_metadata(signed(ALICE), ASSET)); + assert_eq!(Assets::name(ASSET), Vec::::new()); + assert_eq!(Assets::symbol(ASSET), Vec::::new()); + assert_eq!(Assets::decimals(ASSET), 0u8); + }); +} + +#[test] +fn mint_works() { + new_test_ext().execute_with(|| { + let amount: Balance = 100 * UNIT; + create_asset(ALICE, ASSET); + let balance_before_mint = Assets::balance(ASSET, &BOB); + assert_ok!(Fungibles::mint(signed(ALICE), ASSET, BOB, amount)); + let balance_after_mint = Assets::balance(ASSET, &BOB); + assert_eq!(balance_after_mint, balance_before_mint + amount); + }); +} + +#[test] +fn burn_works() { + new_test_ext().execute_with(|| { + let amount: Balance = 100 * UNIT; + create_asset_and_mint_to(ALICE, ASSET, BOB, amount); + let balance_before_burn = Assets::balance(ASSET, &BOB); + assert_ok!(Fungibles::burn(signed(ALICE), ASSET, BOB, amount)); + let balance_after_burn = Assets::balance(ASSET, &BOB); + assert_eq!(balance_after_burn, balance_before_burn - amount); + }); +} + #[test] fn total_supply_works() { new_test_ext().execute_with(|| { @@ -137,12 +214,20 @@ fn token_metadata_works() { }); } +#[test] +fn asset_exists_works() { + new_test_ext().execute_with(|| { + create_asset(ALICE, ASSET); + assert_eq!(Assets::asset_exists(ASSET).encode(), Fungibles::read_state(AssetExists(ASSET))); + }); +} + fn signed(account: AccountId) -> RuntimeOrigin { RuntimeOrigin::signed(account) } -fn create_asset(owner: AccountId, asset_id: AssetId, min_balance: Balance) { - assert_ok!(Assets::create(signed(owner), asset_id, owner, min_balance)); +fn create_asset(owner: AccountId, asset_id: AssetId) { + assert_ok!(Assets::create(signed(owner), asset_id, owner, 1)); } fn mint_asset(owner: AccountId, asset_id: AssetId, to: AccountId, value: Balance) { @@ -150,7 +235,7 @@ fn mint_asset(owner: AccountId, asset_id: AssetId, to: AccountId, value: Balance } fn create_asset_and_mint_to(owner: AccountId, asset_id: AssetId, to: AccountId, value: Balance) { - create_asset(owner, asset_id, 1); + create_asset(owner, asset_id); mint_asset(owner, asset_id, to, value) } diff --git a/pop-api/examples/balance-transfer/lib.rs b/pop-api/examples/balance-transfer/lib.rs index 328a818b..d36dfa53 100755 --- a/pop-api/examples/balance-transfer/lib.rs +++ b/pop-api/examples/balance-transfer/lib.rs @@ -1,3 +1,4 @@ +// DEPRECATED #![cfg_attr(not(feature = "std"), no_std, no_main)] use pop_api::balances::*; @@ -131,4 +132,4 @@ mod balance_transfer { Ok(()) } } -} \ No newline at end of file +} diff --git a/pop-api/examples/nfts/lib.rs b/pop-api/examples/nfts/lib.rs index d47140e7..7920c179 100755 --- a/pop-api/examples/nfts/lib.rs +++ b/pop-api/examples/nfts/lib.rs @@ -1,3 +1,4 @@ +// DEPRECATED #![cfg_attr(not(feature = "std"), no_std, no_main)] use pop_api::nfts::*; @@ -33,27 +34,29 @@ mod nfts { } #[ink(message)] - pub fn create_nft_collection( &self ) -> Result<(), ContractError>{ + pub fn create_nft_collection(&self) -> Result<(), ContractError> { ink::env::debug_println!("Nfts::create_nft_collection: collection creation started."); - let admin = Self::env().caller(); - let item_settings = ItemSettings(BitFlags::from(ItemSetting::Transferable)); - - let mint_settings = MintSettings { - mint_type: MintType::Issuer, - price: Some(0), - start_block: Some(0), - end_block: Some(0), - default_item_settings: item_settings, - }; - - let config = CollectionConfig { - settings: CollectionSettings(BitFlags::from(CollectionSetting::TransferableItems)), - max_supply: None, - mint_settings, - }; - pop_api::nfts::create(admin, config)?; - ink::env::debug_println!("Nfts::create_nft_collection: collection created successfully."); - Ok(()) + let admin = Self::env().caller(); + let item_settings = ItemSettings(BitFlags::from(ItemSetting::Transferable)); + + let mint_settings = MintSettings { + mint_type: MintType::Issuer, + price: Some(0), + start_block: Some(0), + end_block: Some(0), + default_item_settings: item_settings, + }; + + let config = CollectionConfig { + settings: CollectionSettings(BitFlags::from(CollectionSetting::TransferableItems)), + max_supply: None, + mint_settings, + }; + pop_api::nfts::create(admin, config)?; + ink::env::debug_println!( + "Nfts::create_nft_collection: collection created successfully." + ); + Ok(()) } #[ink(message)] @@ -82,9 +85,7 @@ mod nfts { // check owner match owner(collection_id, item_id)? { Some(owner) if owner == receiver => { - ink::env::debug_println!( - "Nfts::mint success: minted item belongs to receiver" - ); + ink::env::debug_println!("Nfts::mint success: minted item belongs to receiver"); }, _ => { return Err(ContractError::NotOwner); @@ -113,4 +114,4 @@ mod nfts { Nfts::new(); } } -} \ No newline at end of file +} diff --git a/pop-api/examples/place-spot-order/lib.rs b/pop-api/examples/place-spot-order/lib.rs index f5e34f7f..669b9190 100755 --- a/pop-api/examples/place-spot-order/lib.rs +++ b/pop-api/examples/place-spot-order/lib.rs @@ -1,3 +1,4 @@ +// DEPRECATED #![cfg_attr(not(feature = "std"), no_std, no_main)] #[ink::contract(env = pop_api::Environment)] @@ -15,11 +16,7 @@ mod spot_order { } #[ink(message)] - pub fn place_spot_order( - &mut self, - max_amount: Balance, - para_id: u32, - ) { + pub fn place_spot_order(&mut self, max_amount: Balance, para_id: u32) { ink::env::debug_println!( "SpotOrder::place_spot_order: max_amount {:?} para_id: {:?} ", max_amount, @@ -28,10 +25,7 @@ mod spot_order { #[allow(unused_variables)] let res = pop_api::cross_chain::coretime::place_spot_order(max_amount, para_id); - ink::env::debug_println!( - "SpotOrder::place_spot_order: res {:?} ", - res, - ); + ink::env::debug_println!("SpotOrder::place_spot_order: res {:?} ", res,); ink::env::debug_println!("SpotOrder::place_spot_order end"); } @@ -46,4 +40,4 @@ mod spot_order { SpotOrder::new(); } } -} \ No newline at end of file +} diff --git a/pop-api/examples/read-runtime-state/lib.rs b/pop-api/examples/read-runtime-state/lib.rs index 05a44108..60ef70f0 100755 --- a/pop-api/examples/read-runtime-state/lib.rs +++ b/pop-api/examples/read-runtime-state/lib.rs @@ -1,35 +1,36 @@ +// DEPRECATED #![cfg_attr(not(feature = "std"), no_std, no_main)] #[ink::contract(env = pop_api::Environment)] mod read_relay_blocknumber { - use pop_api::primitives::storage_keys::{ - ParachainSystemKeys::LastRelayChainBlockNumber, RuntimeStateKeys::ParachainSystem, - }; + use pop_api::primitives::storage_keys::{ + ParachainSystemKeys::LastRelayChainBlockNumber, RuntimeStateKeys::ParachainSystem, + }; - #[ink(event)] - pub struct RelayBlockNumberRead { - value: BlockNumber, - } + #[ink(event)] + pub struct RelayBlockNumberRead { + value: BlockNumber, + } - #[ink(storage)] - #[derive(Default)] - pub struct ReadRelayBlockNumber; + #[ink(storage)] + #[derive(Default)] + pub struct ReadRelayBlockNumber; - impl ReadRelayBlockNumber { - #[ink(constructor, payable)] - pub fn new() -> Self { - ink::env::debug_println!("ReadRelayBlockNumber::new"); - Default::default() - } + impl ReadRelayBlockNumber { + #[ink(constructor, payable)] + pub fn new() -> Self { + ink::env::debug_println!("ReadRelayBlockNumber::new"); + Default::default() + } - #[ink(message)] - pub fn read_relay_block_number(&self) { - let result = - pop_api::state::read::(ParachainSystem(LastRelayChainBlockNumber)); - ink::env::debug_println!("Last relay block number read by contract: {:?}", result); - self.env().emit_event(RelayBlockNumberRead { - value: result.expect("Failed to read relay block number."), - }); - } - } -} \ No newline at end of file + #[ink(message)] + pub fn read_relay_block_number(&self) { + let result = + pop_api::state::read::(ParachainSystem(LastRelayChainBlockNumber)); + ink::env::debug_println!("Last relay block number read by contract: {:?}", result); + self.env().emit_event(RelayBlockNumberRead { + value: result.expect("Failed to read relay block number."), + }); + } + } +} diff --git a/pop-api/integration-tests/contracts/.gitignore b/pop-api/integration-tests/contracts/.gitignore new file mode 100755 index 00000000..d60800c8 --- /dev/null +++ b/pop-api/integration-tests/contracts/.gitignore @@ -0,0 +1,9 @@ +# Ignore build artifacts from the local tests sub-crate. +**/target/ + +# Ignore backup files creates by cargo fmt. +**/*.rs.bk + +# Remove Cargo.lock when creating an executable, leave it for libraries +# More information here http://doc.crates.io/guide.html#cargotoml-vs-cargolock +**/Cargo.lock diff --git a/pop-api/integration-tests/contracts/create_token_in_constructor/Cargo.toml b/pop-api/integration-tests/contracts/create_token_in_constructor/Cargo.toml new file mode 100755 index 00000000..2c202715 --- /dev/null +++ b/pop-api/integration-tests/contracts/create_token_in_constructor/Cargo.toml @@ -0,0 +1,21 @@ +[package] +name = "create_token_in_constructor" +version = "0.1.0" +authors = ["[your_name] <[your_email]>"] +edition = "2021" + +[dependencies] +ink = { version = "5.0.0", default-features = false } +pop-api = { path = "../../..", default-features = false, features = ["fungibles"] } + +[lib] +path = "lib.rs" + +[features] +default = ["std"] +std = [ + "ink/std", + "pop-api/std", +] +ink-as-dependency = [] +e2e-tests = [] diff --git a/pop-api/integration-tests/contracts/create_token_in_constructor/lib.rs b/pop-api/integration-tests/contracts/create_token_in_constructor/lib.rs new file mode 100755 index 00000000..e9e5d127 --- /dev/null +++ b/pop-api/integration-tests/contracts/create_token_in_constructor/lib.rs @@ -0,0 +1,46 @@ +#![cfg_attr(not(feature = "std"), no_std, no_main)] + +use ink::prelude::vec::Vec; +use pop_api::{ + assets::fungibles::{self as api}, + primitives::AssetId, + StatusCode, +}; + +pub type Result = core::result::Result; + +#[ink::contract] +mod create_token_in_constructor { + use super::*; + + #[ink(storage)] + pub struct Fungible { + id: AssetId, + } + + impl Fungible { + #[ink(constructor, payable)] + pub fn new(id: AssetId, min_balance: Balance) -> Result { + let contract = Self { id }; + // AccountId of the contract which will be set to the owner of the fungible token. + let owner = contract.env().account_id(); + api::create(id, owner, min_balance)?; + Ok(contract) + } + + #[ink(message)] + pub fn asset_exists(&self) -> Result { + api::asset_exists(self.id) + } + } + + #[cfg(test)] + mod tests { + use super::*; + + #[ink::test] + fn default_works() { + PopApiFungiblesExample::new(); + } + } +} diff --git a/pop-api/integration-tests/contracts/fungibles/lib.rs b/pop-api/integration-tests/contracts/fungibles/lib.rs index 1b42fec4..239d3a2d 100755 --- a/pop-api/integration-tests/contracts/fungibles/lib.rs +++ b/pop-api/integration-tests/contracts/fungibles/lib.rs @@ -122,55 +122,57 @@ mod fungibles { api::token_decimals(id) } - // 3. Asset Management: - // - create - // - start_destroy - // - destroy_accounts - // - destroy_approvals - // - finish_destroy - // - set_metadata - // - clear_metadata - - // #[ink(message)] - // pub fn create(&self, id: AssetId, admin: AccountId, min_balance: Balance) -> Result<()> { - // ink::env::debug_println!( - // "PopApiFungiblesExample::create: id: {:?} admin: {:?} min_balance: {:?}", - // id, - // admin, - // min_balance, - // ); - // let result = api::create(id, admin, min_balance); - // ink::env::debug_println!("Result: {:?}", result); - // result.map_err(|e| e.into()) - // result - // } - - // #[ink(message)] - // pub fn set_metadata( - // &self, - // id: AssetId, - // name: Vec, - // symbol: Vec, - // decimals: u8, - // ) -> Result<()> { - // ink::env::debug_println!( - // "PopApiFungiblesExample::set_metadata: id: {:?} name: {:?} symbol: {:?}, decimals: {:?}", - // id, - // name, - // symbol, - // decimals, - // ); - // let result = api::set_metadata(id, name, symbol, decimals); - // ink::env::debug_println!("Result: {:?}", result); - // // result.map_err(|e| e.into()) - // result - // } - // - // #[ink(message)] - // pub fn asset_exists(&self, id: AssetId) -> Result { - // // api::asset_exists(id).map_err(|e| e.into()) - // api::asset_exists(id) - // } + /// 3. Asset Management: + /// - create + /// - start_destroy + /// - set_metadata + /// - clear_metadata + /// - asset_exists + + #[ink(message)] + pub fn create(&self, id: AssetId, admin: AccountId, min_balance: Balance) -> Result<()> { + api::create(id, admin, min_balance) + } + + #[ink(message)] + pub fn start_destroy(&self, id: AssetId) -> Result<()> { + api::start_destroy(id) + } + + #[ink(message)] + pub fn set_metadata( + &self, + id: AssetId, + name: Vec, + symbol: Vec, + decimals: u8, + ) -> Result<()> { + api::set_metadata(id, name, symbol, decimals) + } + + #[ink(message)] + pub fn clear_metadata(&self, id: AssetId) -> Result<()> { + api::clear_metadata(id) + } + + #[ink(message)] + pub fn asset_exists(&self, id: AssetId) -> Result { + api::asset_exists(id) + } + + /// 4. PSP-22 Mintable & Burnable Interface: + /// - mint + /// - burn + + #[ink(message)] + pub fn mint(&self, id: AssetId, account: AccountId, amount: Balance) -> Result<()> { + api::mint(id, account, amount) + } + + #[ink(message)] + pub fn burn(&self, id: AssetId, account: AccountId, amount: Balance) -> Result<()> { + api::burn(id, account, amount) + } } #[cfg(test)] diff --git a/pop-api/integration-tests/src/fungibles/mod.rs b/pop-api/integration-tests/src/fungibles/mod.rs new file mode 100644 index 00000000..0ca7d4f9 --- /dev/null +++ b/pop-api/integration-tests/src/fungibles/mod.rs @@ -0,0 +1,546 @@ +use super::*; +use pop_primitives::error::{ + ArithmeticError::*, + Error::{self, *}, + TokenError::*, +}; +use utils::*; + +mod utils; + +const ASSET_ID: AssetId = 1; +const CONTRACT: &str = "contracts/fungibles/target/ink/fungibles.wasm"; + +/// 1. PSP-22 Interface: +/// - total_supply +/// - balance_of +/// - allowance +/// - transfer +/// - transfer_from +/// - approve +/// - increase_allowance +/// - decrease_allowance + +#[test] +fn total_supply_works() { + new_test_ext().execute_with(|| { + let _ = env_logger::try_init(); + let addr = instantiate(CONTRACT, INIT_VALUE, vec![]); + + // No tokens in circulation. + assert_eq!(total_supply(addr.clone(), ASSET_ID), Ok(Assets::total_supply(ASSET_ID))); + assert_eq!(total_supply(addr.clone(), ASSET_ID), Ok(0)); + + // Tokens in circulation. + create_asset_and_mint_to(addr.clone(), ASSET_ID, BOB, 100); + assert_eq!(total_supply(addr.clone(), ASSET_ID), Ok(Assets::total_supply(ASSET_ID))); + assert_eq!(total_supply(addr, ASSET_ID), Ok(100)); + }); +} + +#[test] +fn balance_of_works() { + new_test_ext().execute_with(|| { + let _ = env_logger::try_init(); + let addr = instantiate(CONTRACT, INIT_VALUE, vec![]); + + // No tokens in circulation. + assert_eq!(balance_of(addr.clone(), ASSET_ID, BOB), Ok(Assets::balance(ASSET_ID, BOB))); + assert_eq!(balance_of(addr.clone(), ASSET_ID, BOB), Ok(0)); + + // Tokens in circulation. + create_asset_and_mint_to(addr.clone(), ASSET_ID, BOB, 100); + assert_eq!(balance_of(addr.clone(), ASSET_ID, BOB), Ok(Assets::balance(ASSET_ID, BOB))); + assert_eq!(balance_of(addr, ASSET_ID, BOB), Ok(100)); + }); +} + +#[test] +fn allowance_works() { + new_test_ext().execute_with(|| { + let _ = env_logger::try_init(); + let addr = instantiate(CONTRACT, INIT_VALUE, vec![]); + + // No tokens in circulation. + assert_eq!( + allowance(addr.clone(), ASSET_ID, BOB, ALICE), + Ok(Assets::allowance(ASSET_ID, &BOB, &ALICE)) + ); + assert_eq!(allowance(addr.clone(), ASSET_ID, BOB, ALICE), Ok(0)); + + // Tokens in circulation. + create_asset_mint_and_approve(addr.clone(), ASSET_ID, BOB, 100, ALICE, 50); + assert_eq!( + allowance(addr.clone(), ASSET_ID, BOB, ALICE), + Ok(Assets::allowance(ASSET_ID, &BOB, &ALICE)) + ); + assert_eq!(allowance(addr, ASSET_ID, BOB, ALICE), Ok(50)); + }); +} + +#[test] +fn transfer_works() { + new_test_ext().execute_with(|| { + let _ = env_logger::try_init(); + let addr = instantiate(CONTRACT, INIT_VALUE, vec![]); + let amount: Balance = 100 * UNIT; + + // Asset does not exist. + assert_eq!(transfer(addr.clone(), 1, BOB, amount), Err(Module { index: 52, error: 3 })); + // Create asset with Alice as owner and mint `amount` to contract address. + let asset = create_asset_and_mint_to(ALICE, 1, addr.clone(), amount); + // Asset is not live, i.e. frozen or being destroyed. + freeze_asset(ALICE, asset); + assert_eq!( + transfer(addr.clone(), asset, BOB, amount), + Err(Module { index: 52, error: 16 }) + ); + thaw_asset(ALICE, asset); + // Not enough balance. + assert_eq!( + transfer(addr.clone(), asset, BOB, amount + 1 * UNIT), + Err(Module { index: 52, error: 0 }) + ); + // Not enough balance due to ED. + assert_eq!(transfer(addr.clone(), asset, BOB, amount), Err(Module { index: 52, error: 0 })); + // Successful transfer. + let balance_before_transfer = Assets::balance(asset, &BOB); + assert_ok!(transfer(addr.clone(), asset, BOB, amount / 2)); + let balance_after_transfer = Assets::balance(asset, &BOB); + assert_eq!(balance_after_transfer, balance_before_transfer + amount / 2); + // Transfer asset to account that does not exist. + assert_eq!(transfer(addr.clone(), asset, FERDIE, amount / 4), Err(Token(CannotCreate))); + // Asset is not live, i.e. frozen or being destroyed. + start_destroy_asset(ALICE, asset); + assert_eq!( + transfer(addr.clone(), asset, BOB, amount / 4), + Err(Module { index: 52, error: 16 }) + ); + }); +} + +#[test] +fn transfer_from_works() { + new_test_ext().execute_with(|| { + let _ = env_logger::try_init(); + let addr = instantiate(CONTRACT, INIT_VALUE, vec![]); + let amount: Balance = 100 * UNIT; + + // Asset does not exist. + assert_eq!( + transfer_from(addr.clone(), 1, ALICE, BOB, amount / 2), + Err(Module { index: 52, error: 3 }), + ); + // Create asset with Alice as owner and mint `amount` to contract address. + let asset = create_asset_and_mint_to(ALICE, 1, ALICE, amount); + // Unapproved transfer. + assert_eq!( + transfer_from(addr.clone(), asset, ALICE, BOB, amount / 2), + Err(Module { index: 52, error: 10 }) + ); + assert_ok!(Assets::approve_transfer( + RuntimeOrigin::signed(ALICE.into()), + asset.into(), + addr.clone().into(), + amount + 1 * UNIT, + )); + // Asset is not live, i.e. frozen or being destroyed. + freeze_asset(ALICE, asset); + assert_eq!( + transfer_from(addr.clone(), asset, ALICE, BOB, amount), + Err(Module { index: 52, error: 16 }), + ); + thaw_asset(ALICE, asset); + // Not enough balance. + assert_eq!( + transfer_from(addr.clone(), asset, ALICE, BOB, amount + 1 * UNIT), + Err(Module { index: 52, error: 0 }), + ); + // Successful transfer. + let balance_before_transfer = Assets::balance(asset, &BOB); + assert_ok!(transfer_from(addr.clone(), asset, ALICE, BOB, amount / 2)); + let balance_after_transfer = Assets::balance(asset, &BOB); + assert_eq!(balance_after_transfer, balance_before_transfer + amount / 2); + }); +} + +#[test] +fn approve_works() { + new_test_ext().execute_with(|| { + let _ = env_logger::try_init(); + let addr = instantiate(CONTRACT, 0, vec![]); + let amount: Balance = 100 * UNIT; + + // Asset does not exist. + assert_eq!(approve(addr.clone(), 0, BOB, amount), Err(Module { index: 52, error: 3 })); + let asset = create_asset_and_mint_to(ALICE, 0, addr.clone(), amount); + assert_eq!(approve(addr.clone(), asset, BOB, amount), Err(ConsumerRemaining)); + let addr = instantiate(CONTRACT, INIT_VALUE, vec![1]); + // Create asset with Alice as owner and mint `amount` to contract address. + let asset = create_asset_and_mint_to(ALICE, 1, addr.clone(), amount); + // Asset is not live, i.e. frozen or being destroyed. + freeze_asset(ALICE, asset); + assert_eq!(approve(addr.clone(), asset, BOB, amount), Err(Module { index: 52, error: 16 })); + thaw_asset(ALICE, asset); + // Successful approvals: + assert_eq!(0, Assets::allowance(asset, &addr, &BOB)); + assert_ok!(approve(addr.clone(), asset, BOB, amount)); + assert_eq!(Assets::allowance(asset, &addr, &BOB), amount); + // Non-additive, sets new value. + assert_ok!(approve(addr.clone(), asset, BOB, amount / 2)); + assert_eq!(Assets::allowance(asset, &addr, &BOB), amount / 2); + // Asset is not live, i.e. frozen or being destroyed. + start_destroy_asset(ALICE, asset); + assert_eq!(approve(addr.clone(), asset, BOB, amount), Err(Module { index: 52, error: 16 })); + }); +} + +#[test] +fn increase_allowance_works() { + new_test_ext().execute_with(|| { + let _ = env_logger::try_init(); + let amount: Balance = 100 * UNIT; + // Instantiate a contract without balance - test `ConsumerRemaining. + let addr = instantiate(CONTRACT, 0, vec![]); + // Asset does not exist. + assert_eq!( + increase_allowance(addr.clone(), 0, BOB, amount), + Err(Module { index: 52, error: 3 }) + ); + let asset = create_asset_and_mint_to(ALICE, 0, addr.clone(), amount); + assert_eq!(increase_allowance(addr.clone(), asset, BOB, amount), Err(ConsumerRemaining)); + + // Instantiate a contract with balance. + let addr = instantiate(CONTRACT, INIT_VALUE, vec![1]); + // Create asset with Alice as owner and mint `amount` to contract address. + let asset = create_asset_and_mint_to(ALICE, 1, addr.clone(), amount); + // Asset is not live, i.e. frozen or being destroyed. + freeze_asset(ALICE, asset); + assert_eq!( + increase_allowance(addr.clone(), asset, BOB, amount), + Err(Module { index: 52, error: 16 }) + ); + thaw_asset(ALICE, asset); + // Successful approvals: + assert_eq!(0, Assets::allowance(asset, &addr, &BOB)); + assert_ok!(increase_allowance(addr.clone(), asset, BOB, amount)); + assert_eq!(Assets::allowance(asset, &addr, &BOB), amount); + // Additive. + assert_ok!(increase_allowance(addr.clone(), asset, BOB, amount)); + assert_eq!(Assets::allowance(asset, &addr, &BOB), amount * 2); + // Asset is not live, i.e. frozen or being destroyed. + start_destroy_asset(ALICE, asset); + assert_eq!( + increase_allowance(addr.clone(), asset, BOB, amount), + Err(Module { index: 52, error: 16 }) + ); + }); +} + +#[test] +fn decrease_allowance_works() { + new_test_ext().execute_with(|| { + let _ = env_logger::try_init(); + let addr = instantiate(CONTRACT, INIT_VALUE, vec![]); + let amount: Balance = 100 * UNIT; + + // Asset does not exist. + assert_eq!( + decrease_allowance(addr.clone(), 0, BOB, amount), + Err(Module { index: 52, error: 3 }), + ); + // Create asset and mint `amount` to contract address, then approve Bob to spend `amount`. + let asset = + create_asset_mint_and_approve(addr.clone(), 0, addr.clone(), amount, BOB, amount); + // Asset is not live, i.e. frozen or being destroyed. + freeze_asset(addr.clone(), asset); + assert_eq!( + decrease_allowance(addr.clone(), asset, BOB, amount), + Err(Module { index: 52, error: 16 }), + ); + thaw_asset(addr.clone(), asset); + // Successfully decrease allowance. + let allowance_before = Assets::allowance(asset, &addr, &BOB); + assert_ok!(decrease_allowance(addr.clone(), 0, BOB, amount / 2 - 1 * UNIT)); + let allowance_after = Assets::allowance(asset, &addr, &BOB); + assert_eq!(allowance_before - allowance_after, amount / 2 - 1 * UNIT); + // Asset is not live, i.e. frozen or being destroyed. + start_destroy_asset(addr.clone(), asset); + assert_eq!( + decrease_allowance(addr.clone(), asset, BOB, amount), + Err(Module { index: 52, error: 16 }), + ); + }); +} + +/// 2. PSP-22 Metadata Interface: +/// - token_name +/// - token_symbol +/// - token_decimals + +#[test] +fn token_metadata_works() { + new_test_ext().execute_with(|| { + let _ = env_logger::try_init(); + let addr = instantiate(CONTRACT, INIT_VALUE, vec![]); + let name: Vec = vec![11, 12, 13]; + let symbol: Vec = vec![21, 22, 23]; + let decimals: u8 = 69; + + // Token does not exist. + assert_eq!(token_name(addr.clone(), ASSET_ID), Ok(token_name_asset(ASSET_ID))); + assert_eq!(token_name(addr.clone(), ASSET_ID), Ok(Vec::::new())); + assert_eq!(token_symbol(addr.clone(), ASSET_ID), Ok(token_symbol_asset(ASSET_ID))); + assert_eq!(token_symbol(addr.clone(), ASSET_ID), Ok(Vec::::new())); + assert_eq!(token_decimals(addr.clone(), ASSET_ID), Ok(token_decimals_asset(ASSET_ID))); + assert_eq!(token_decimals(addr.clone(), ASSET_ID), Ok(0)); + // Create Token. + create_asset_and_set_metadata( + addr.clone(), + ASSET_ID, + name.clone(), + symbol.clone(), + decimals, + ); + assert_eq!(token_name(addr.clone(), ASSET_ID), Ok(token_name_asset(ASSET_ID))); + assert_eq!(token_name(addr.clone(), ASSET_ID), Ok(name)); + assert_eq!(token_symbol(addr.clone(), ASSET_ID), Ok(token_symbol_asset(ASSET_ID))); + assert_eq!(token_symbol(addr.clone(), ASSET_ID), Ok(symbol)); + assert_eq!(token_decimals(addr.clone(), ASSET_ID), Ok(token_decimals_asset(ASSET_ID))); + assert_eq!(token_decimals(addr.clone(), ASSET_ID), Ok(decimals)); + }); +} + +/// 3. Asset Management: +/// - create +/// - start_destroy +/// - set_metadata +/// - clear_metadata +/// - asset_exists + +#[test] +fn create_works() { + new_test_ext().execute_with(|| { + let _ = env_logger::try_init(); + // Instantiate a contract without balance for fees. + let addr = instantiate(CONTRACT, 0, vec![0]); + // No balance to pay for fees. + assert_eq!( + create(addr.clone(), ASSET_ID, addr.clone(), 1), + Err(Module { index: 10, error: 2 }), + ); + + // Instantiate a contract without balance for deposit. + let addr = instantiate(CONTRACT, 100, vec![1]); + // No balance to pay the deposit. + assert_eq!( + create(addr.clone(), ASSET_ID, addr.clone(), 1), + Err(Module { index: 10, error: 2 }), + ); + + // Instantiate a contract with enough balance. + let addr = instantiate(CONTRACT, INIT_VALUE, vec![2]); + assert_eq!(create(addr.clone(), ASSET_ID, BOB, 0), Err(Module { index: 52, error: 7 }),); + // The minimal balance for an asset must be non zero. + assert_eq!(create(addr.clone(), ASSET_ID, BOB, 0), Err(Module { index: 52, error: 7 }),); + // Create asset successfully. + assert_ok!(create(addr.clone(), ASSET_ID, BOB, 1)); + // Asset ID is already taken. + assert_eq!(create(addr.clone(), ASSET_ID, BOB, 1), Err(Module { index: 52, error: 5 }),); + }); +} + +// Testing a contract that creates an asset in the constructor. +#[test] +fn instantiate_and_create_fungible_works() { + new_test_ext().execute_with(|| { + let _ = env_logger::try_init(); + let contract = + "contracts/create_token_in_constructor/target/ink/create_token_in_constructor.wasm"; + // Asset already exists. + create_asset(ALICE, 0, 1); + assert_eq!( + instantiate_and_create_fungible(contract, 0, 1), + Err(Module { index: 52, error: 5 }) + ); + // Successfully create an asset when instantiating the contract. + assert_ok!(instantiate_and_create_fungible(contract, ASSET_ID, 1)); + assert!(Assets::asset_exists(ASSET_ID)); + }); +} + +#[test] +fn start_destroy_works() { + new_test_ext().execute_with(|| { + let _ = env_logger::try_init(); + let addr = instantiate(CONTRACT, INIT_VALUE, vec![2]); + + // Asset does not exist. + assert_eq!(start_destroy(addr.clone(), ASSET_ID), Err(Module { index: 52, error: 3 }),); + // Create assets where contract is not the owner. + let asset = create_asset(ALICE, 0, 1); + // No Permission. + assert_eq!(start_destroy(addr.clone(), asset), Err(Module { index: 52, error: 2 }),); + let asset = create_asset(addr.clone(), ASSET_ID, 1); + assert_ok!(start_destroy(addr.clone(), asset)); + }); +} + +#[test] +fn set_metadata_works() { + new_test_ext().execute_with(|| { + let _ = env_logger::try_init(); + let name = vec![42]; + let symbol = vec![42]; + let decimals = 42u8; + let addr = instantiate(CONTRACT, INIT_VALUE, vec![]); + + // Asset does not exist. + assert_eq!( + set_metadata(addr.clone(), ASSET_ID, vec![0], vec![0], 0u8), + Err(Module { index: 52, error: 3 }), + ); + // Create assets where contract is not the owner. + let asset = create_asset(ALICE, 0, 1); + // No Permission. + assert_eq!( + set_metadata(addr.clone(), asset, vec![0], vec![0], 0u8), + Err(Module { index: 52, error: 2 }), + ); + let asset = create_asset(addr.clone(), ASSET_ID, 1); + // Asset is not live, i.e. frozen or being destroyed. + freeze_asset(addr.clone(), asset); + assert_eq!( + set_metadata(addr.clone(), ASSET_ID, vec![0], vec![0], 0u8), + Err(Module { index: 52, error: 16 }), + ); + thaw_asset(addr.clone(), asset); + // TODO: calling the below with a vector of length `100_000` errors in pallet contracts + // `OutputBufferTooSmall. Added to security analysis issue #131 to revisit. + // Set bad metadata - too large values. + assert_eq!( + set_metadata(addr.clone(), ASSET_ID, vec![0; 1000], vec![0; 1000], 0u8), + Err(Module { index: 52, error: 9 }), + ); + // Set metadata successfully. + assert_ok!(set_metadata(addr.clone(), ASSET_ID, name, symbol, decimals)); + // Asset is not live, i.e. frozen or being destroyed. + start_destroy_asset(addr.clone(), asset); + assert_eq!( + set_metadata(addr.clone(), ASSET_ID, vec![0], vec![0], 0), + Err(Module { index: 52, error: 16 }), + ); + }); +} + +#[test] +fn clear_metadata_works() { + new_test_ext().execute_with(|| { + let _ = env_logger::try_init(); + let name = vec![42]; + let symbol = vec![42]; + let decimals = 42u8; + let addr = instantiate(CONTRACT, INIT_VALUE, vec![]); + + // Asset does not exist. + assert_eq!(clear_metadata(addr.clone(), 0), Err(Module { index: 52, error: 3 }),); + // Create assets where contract is not the owner. + let asset = create_asset_and_set_metadata(ALICE, 0, vec![0], vec![0], 0); + // No Permission. + assert_eq!(clear_metadata(addr.clone(), asset), Err(Module { index: 52, error: 2 }),); + let asset = create_asset(addr.clone(), ASSET_ID, 1); + // Asset is not live, i.e. frozen or being destroyed. + freeze_asset(addr.clone(), asset); + assert_eq!(clear_metadata(addr.clone(), asset), Err(Module { index: 52, error: 16 }),); + thaw_asset(addr.clone(), asset); + // No metadata set. + assert_eq!(clear_metadata(addr.clone(), asset), Err(Module { index: 52, error: 3 }),); + set_metadata_asset(addr.clone(), asset, name, symbol, decimals); + // Clear metadata successfully. + assert_ok!(clear_metadata(addr.clone(), ASSET_ID)); + // Asset is not live, i.e. frozen or being destroyed. + start_destroy_asset(addr.clone(), asset); + assert_eq!( + set_metadata(addr.clone(), ASSET_ID, vec![0], vec![0], decimals), + Err(Module { index: 52, error: 16 }), + ); + }); +} + +#[test] +fn asset_exists_works() { + new_test_ext().execute_with(|| { + let _ = env_logger::try_init(); + let addr = instantiate(CONTRACT, INIT_VALUE, vec![]); + + // No tokens in circulation. + assert_eq!(asset_exists(addr.clone(), ASSET_ID), Ok(Assets::asset_exists(ASSET_ID))); + + // Tokens in circulation. + create_asset(addr.clone(), ASSET_ID, 1); + assert_eq!(asset_exists(addr.clone(), ASSET_ID), Ok(Assets::asset_exists(ASSET_ID))); + }); +} + +#[test] +fn mint_works() { + new_test_ext().execute_with(|| { + let _ = env_logger::try_init(); + let addr = instantiate(CONTRACT, INIT_VALUE, vec![]); + let amount: Balance = 100 * UNIT; + + // Asset does not exist. + assert_eq!(mint(addr.clone(), 1, BOB, amount), Err(Token(UnknownAsset))); + let asset = create_asset(ALICE, 1, 1); + // Minting can only be done by the owner. + assert_eq!(mint(addr.clone(), asset, BOB, 1), Err(Module { index: 52, error: 2 })); + let asset = create_asset(addr.clone(), 2, 2); + // Minimum balance of an asset can not be zero. + assert_eq!(mint(addr.clone(), asset, BOB, 1), Err(Token(BelowMinimum))); + // Asset is not live, i.e. frozen or being destroyed. + freeze_asset(addr.clone(), asset); + assert_eq!(mint(addr.clone(), asset, BOB, amount), Err(Module { index: 52, error: 16 })); + thaw_asset(addr.clone(), asset); + // Successful mint. + let balance_before_mint = Assets::balance(asset, &BOB); + assert_ok!(mint(addr.clone(), asset, BOB, amount)); + let balance_after_mint = Assets::balance(asset, &BOB); + assert_eq!(balance_after_mint, balance_before_mint + amount); + // Account can not hold more tokens than Balance::MAX. + assert_eq!(mint(addr.clone(), asset, BOB, Balance::MAX,), Err(Arithmetic(Overflow))); + // Asset is not live, i.e. frozen or being destroyed. + start_destroy_asset(addr.clone(), asset); + assert_eq!(mint(addr.clone(), asset, BOB, amount), Err(Module { index: 52, error: 16 })); + }); +} + +#[test] +fn burn_works() { + new_test_ext().execute_with(|| { + let _ = env_logger::try_init(); + let addr = instantiate(CONTRACT, INIT_VALUE, vec![]); + let amount: Balance = 100 * UNIT; + + // Asset does not exist. + assert_eq!(burn(addr.clone(), 1, BOB, amount), Err(Module { index: 52, error: 3 })); + let asset = create_asset(ALICE, 1, 1); + // Bob has no tokens and thus pallet assets doesn't know the account. + assert_eq!(burn(addr.clone(), asset, BOB, 1), Err(Module { index: 52, error: 1 })); + // Burning can only be done by the manager. + mint_asset(ALICE, asset, BOB, amount); + assert_eq!(burn(addr.clone(), asset, BOB, 1), Err(Module { index: 52, error: 2 })); + let asset = create_asset_and_mint_to(addr.clone(), 2, BOB, amount); + // Asset is not live, i.e. frozen or being destroyed. + freeze_asset(addr.clone(), asset); + assert_eq!(burn(addr.clone(), asset, BOB, amount), Err(Module { index: 52, error: 16 })); + thaw_asset(addr.clone(), asset); + // Successful mint. + let balance_before_burn = Assets::balance(asset, &BOB); + assert_ok!(burn(addr.clone(), asset, BOB, amount)); + let balance_after_burn = Assets::balance(asset, &BOB); + assert_eq!(balance_after_burn, balance_before_burn - amount); + // Asset is not live, i.e. frozen or being destroyed. + start_destroy_asset(addr.clone(), asset); + assert_eq!(burn(addr.clone(), asset, BOB, amount), Err(Module { index: 52, error: 16 })); + }); +} diff --git a/pop-api/integration-tests/src/fungibles/utils.rs b/pop-api/integration-tests/src/fungibles/utils.rs new file mode 100644 index 00000000..2f9be65c --- /dev/null +++ b/pop-api/integration-tests/src/fungibles/utils.rs @@ -0,0 +1,360 @@ +use super::*; + +pub(super) fn decoded(result: ExecReturnValue) -> Result { + ::decode(&mut &result.data[1..]).map_err(|_| result) +} + +pub(super) fn total_supply(addr: AccountId32, asset_id: AssetId) -> Result { + let function = function_selector("total_supply"); + let params = [function, asset_id.encode()].concat(); + let result = bare_call(addr, params, 0).expect("should work"); + decoded::>(result.clone()) + .unwrap_or_else(|_| panic!("Contract reverted: {:?}", result)) +} + +pub(super) fn balance_of( + addr: AccountId32, + asset_id: AssetId, + owner: AccountId32, +) -> Result { + let function = function_selector("balance_of"); + let params = [function, asset_id.encode(), owner.encode()].concat(); + let result = bare_call(addr, params, 0).expect("should work"); + decoded::>(result.clone()) + .unwrap_or_else(|_| panic!("Contract reverted: {:?}", result)) +} + +pub(super) fn allowance( + addr: AccountId32, + asset_id: AssetId, + owner: AccountId32, + spender: AccountId32, +) -> Result { + let function = function_selector("allowance"); + let params = [function, asset_id.encode(), owner.encode(), spender.encode()].concat(); + let result = bare_call(addr, params, 0).expect("should work"); + decoded::>(result.clone()) + .unwrap_or_else(|_| panic!("Contract reverted: {:?}", result)) +} + +pub(super) fn token_name(addr: AccountId32, asset_id: AssetId) -> Result, Error> { + let function = function_selector("token_name"); + let params = [function, asset_id.encode()].concat(); + let result = bare_call(addr, params, 0).expect("should work"); + decoded::, Error>>(result.clone()) + .unwrap_or_else(|_| panic!("Contract reverted: {:?}", result)) +} + +pub(super) fn token_symbol(addr: AccountId32, asset_id: AssetId) -> Result, Error> { + let function = function_selector("token_symbol"); + let params = [function, asset_id.encode()].concat(); + let result = bare_call(addr, params, 0).expect("should work"); + decoded::, Error>>(result.clone()) + .unwrap_or_else(|_| panic!("Contract reverted: {:?}", result)) +} + +pub(super) fn token_decimals(addr: AccountId32, asset_id: AssetId) -> Result { + let function = function_selector("token_decimals"); + let params = [function, asset_id.encode()].concat(); + let result = bare_call(addr, params, 0).expect("should work"); + decoded::>(result.clone()) + .unwrap_or_else(|_| panic!("Contract reverted: {:?}", result)) +} + +pub(super) fn asset_exists(addr: AccountId32, asset_id: AssetId) -> Result { + let function = function_selector("asset_exists"); + let params = [function, asset_id.encode()].concat(); + let result = bare_call(addr, params, 0).expect("should work"); + decoded::>(result.clone()) + .unwrap_or_else(|_| panic!("Contract reverted: {:?}", result)) +} + +pub(super) fn transfer( + addr: AccountId32, + asset_id: AssetId, + to: AccountId32, + value: Balance, +) -> Result<(), Error> { + let function = function_selector("transfer"); + let params = [function, asset_id.encode(), to.encode(), value.encode()].concat(); + let result = bare_call(addr, params, 0).expect("should work"); + decoded::>(result.clone()) + .unwrap_or_else(|_| panic!("Contract reverted: {:?}", result)) +} + +pub(super) fn transfer_from( + addr: AccountId32, + asset_id: AssetId, + from: AccountId32, + to: AccountId32, + value: Balance, +) -> Result<(), Error> { + let function = function_selector("transfer_from"); + let data: Vec = vec![]; + let params = + [function, asset_id.encode(), from.encode(), to.encode(), value.encode(), data.encode()] + .concat(); + let result = bare_call(addr, params, 0).expect("should work"); + decoded::>(result.clone()) + .unwrap_or_else(|_| panic!("Contract reverted: {:?}", result)) +} + +pub(super) fn approve( + addr: AccountId32, + asset_id: AssetId, + spender: AccountId32, + value: Balance, +) -> Result<(), Error> { + let function = function_selector("approve"); + let params = [function, asset_id.encode(), spender.encode(), value.encode()].concat(); + let result = bare_call(addr, params, 0).expect("should work"); + decoded::>(result.clone()) + .unwrap_or_else(|_| panic!("Contract reverted: {:?}", result)) +} + +pub(super) fn increase_allowance( + addr: AccountId32, + asset_id: AssetId, + spender: AccountId32, + value: Balance, +) -> Result<(), Error> { + let function = function_selector("increase_allowance"); + let params = [function, asset_id.encode(), spender.encode(), value.encode()].concat(); + let result = bare_call(addr, params, 0).expect("should work"); + decoded::>(result.clone()) + .unwrap_or_else(|_| panic!("Contract reverted: {:?}", result)) +} + +pub(super) fn decrease_allowance( + addr: AccountId32, + asset_id: AssetId, + spender: AccountId32, + value: Balance, +) -> Result<(), Error> { + let function = function_selector("decrease_allowance"); + let params = [function, asset_id.encode(), spender.encode(), value.encode()].concat(); + let result = bare_call(addr, params, 0).expect("should work"); + decoded::>(result.clone()) + .unwrap_or_else(|_| panic!("Contract reverted: {:?}", result)) +} + +pub(super) fn create( + addr: AccountId32, + asset_id: AssetId, + admin: AccountId32, + min_balance: Balance, +) -> Result<(), Error> { + let function = function_selector("create"); + let params = [function, asset_id.encode(), admin.encode(), min_balance.encode()].concat(); + let result = bare_call(addr, params, 0).expect("should work"); + decoded::>(result.clone()) + .unwrap_or_else(|_| panic!("Contract reverted: {:?}", result)) +} + +pub(super) fn start_destroy(addr: AccountId32, asset_id: AssetId) -> Result<(), Error> { + let function = function_selector("start_destroy"); + let params = [function, asset_id.encode()].concat(); + let result = bare_call(addr, params, 0).expect("should work"); + match decoded::>(result) { + Ok(x) => x, + Err(result) => panic!("Contract reverted: {:?}", result), + } +} + +pub(super) fn set_metadata( + addr: AccountId32, + asset_id: AssetId, + name: Vec, + symbol: Vec, + decimals: u8, +) -> Result<(), Error> { + let function = function_selector("set_metadata"); + let params = + [function, asset_id.encode(), name.encode(), symbol.encode(), decimals.encode()].concat(); + let result = bare_call(addr, params, 0).expect("should work"); + decoded::>(result.clone()) + .unwrap_or_else(|_| panic!("Contract reverted: {:?}", result)) +} + +pub(super) fn clear_metadata(addr: AccountId32, asset_id: AssetId) -> Result<(), Error> { + let function = function_selector("clear_metadata"); + let params = [function, asset_id.encode()].concat(); + let result = bare_call(addr, params, 0).expect("should work"); + decoded::>(result.clone()) + .unwrap_or_else(|_| panic!("Contract reverted: {:?}", result)) +} + +pub(super) fn mint( + addr: AccountId32, + asset_id: AssetId, + account: AccountId32, + amount: Balance, +) -> Result<(), Error> { + let function = function_selector("mint"); + let params = [function, asset_id.encode(), account.encode(), amount.encode()].concat(); + let result = bare_call(addr, params, 0).expect("should work"); + decoded::>(result.clone()) + .unwrap_or_else(|_| panic!("Contract reverted: {:?}", result)) +} + +pub(super) fn burn( + addr: AccountId32, + asset_id: AssetId, + account: AccountId32, + amount: Balance, +) -> Result<(), Error> { + let function = function_selector("burn"); + let params = [function, asset_id.encode(), account.encode(), amount.encode()].concat(); + let result = bare_call(addr, params, 0).expect("should work"); + decoded::>(result.clone()) + .unwrap_or_else(|_| panic!("Contract reverted: {:?}", result)) +} + +pub(super) fn create_asset(owner: AccountId32, asset_id: AssetId, min_balance: Balance) -> AssetId { + assert_ok!(Assets::create( + RuntimeOrigin::signed(owner.clone()), + asset_id.into(), + owner.into(), + min_balance + )); + asset_id +} + +pub(super) fn mint_asset( + owner: AccountId32, + asset_id: AssetId, + to: AccountId32, + value: Balance, +) -> AssetId { + assert_ok!(Assets::mint( + RuntimeOrigin::signed(owner.clone()), + asset_id.into(), + to.into(), + value + )); + asset_id +} + +pub(super) fn create_asset_and_mint_to( + owner: AccountId32, + asset_id: AssetId, + to: AccountId32, + value: Balance, +) -> AssetId { + create_asset(owner.clone(), asset_id, 1); + mint_asset(owner, asset_id, to, value) +} + +// Create an asset, mints to, and approves spender. +pub(super) fn create_asset_mint_and_approve( + owner: AccountId32, + asset_id: AssetId, + to: AccountId32, + mint: Balance, + spender: AccountId32, + approve: Balance, +) -> AssetId { + create_asset_and_mint_to(owner.clone(), asset_id, to.clone(), mint); + assert_ok!(Assets::approve_transfer( + RuntimeOrigin::signed(to.into()), + asset_id.into(), + spender.into(), + approve, + )); + asset_id +} + +// Freeze an asset. +pub(super) fn freeze_asset(owner: AccountId32, asset_id: AssetId) { + assert_ok!(Assets::freeze_asset(RuntimeOrigin::signed(owner.into()), asset_id.into())); +} + +// Thaw an asset. +pub(super) fn thaw_asset(owner: AccountId32, asset_id: AssetId) { + assert_ok!(Assets::thaw_asset(RuntimeOrigin::signed(owner.into()), asset_id.into())); +} + +// Start destroying an asset. +pub(super) fn start_destroy_asset(owner: AccountId32, asset_id: AssetId) { + assert_ok!(Assets::start_destroy(RuntimeOrigin::signed(owner.into()), asset_id.into())); +} + +// Create an asset and set metadata. +pub(super) fn create_asset_and_set_metadata( + owner: AccountId32, + asset_id: AssetId, + name: Vec, + symbol: Vec, + decimals: u8, +) -> AssetId { + assert_ok!(Assets::create( + RuntimeOrigin::signed(owner.clone()), + asset_id.into(), + owner.clone().into(), + 100 + )); + set_metadata_asset(owner, asset_id, name, symbol, decimals); + asset_id +} + +// Set metadata of an asset. +pub(super) fn set_metadata_asset( + owner: AccountId32, + asset_id: AssetId, + name: Vec, + symbol: Vec, + decimals: u8, +) { + assert_ok!(Assets::set_metadata( + RuntimeOrigin::signed(owner.into()), + asset_id.into(), + name, + symbol, + decimals + )); +} + +pub(super) fn token_name_asset(asset_id: AssetId) -> Vec { + as MetadataInspect>::name( + asset_id, + ) +} + +pub(super) fn token_symbol_asset(asset_id: AssetId) -> Vec { + as MetadataInspect>::symbol( + asset_id, + ) +} + +pub(super) fn token_decimals_asset(asset_id: AssetId) -> u8 { + as MetadataInspect>::decimals( + asset_id, + ) +} + +pub(super) fn instantiate_and_create_fungible( + contract: &str, + asset_id: AssetId, + min_balance: Balance, +) -> Result<(), Error> { + let function = function_selector("new"); + let input = [function, asset_id.encode(), min_balance.encode()].concat(); + let (wasm_binary, _) = + load_wasm_module::(contract).expect("could not read .wasm file"); + let result = Contracts::bare_instantiate( + ALICE, + INIT_VALUE, + GAS_LIMIT, + None, + Code::Upload(wasm_binary), + input, + vec![], + DEBUG_OUTPUT, + CollectEvents::Skip, + ) + .result + .expect("should work") + .result; + decoded::>(result.clone()) + .unwrap_or_else(|_| panic!("Contract reverted: {:?}", result)) +} diff --git a/pop-api/integration-tests/src/lib.rs b/pop-api/integration-tests/src/lib.rs index ea5ccb05..b728fca6 100644 --- a/pop-api/integration-tests/src/lib.rs +++ b/pop-api/integration-tests/src/lib.rs @@ -16,7 +16,7 @@ use pop_runtime_devnet::{ UNIT, }; -mod local_fungibles; +mod fungibles; type AssetId = u32; type Balance = u128; diff --git a/pop-api/integration-tests/src/local_fungibles.rs b/pop-api/integration-tests/src/local_fungibles.rs deleted file mode 100644 index 15a644ad..00000000 --- a/pop-api/integration-tests/src/local_fungibles.rs +++ /dev/null @@ -1,738 +0,0 @@ -use super::*; -use pop_primitives::error::{ - ArithmeticError::*, - Error::{self, *}, - TokenError::*, -}; - -const ASSET_ID: AssetId = 1; -const CONTRACT: &str = "contracts/fungibles/target/ink/fungibles.wasm"; - -fn decoded(result: ExecReturnValue) -> Result { - ::decode(&mut &result.data[2..]) - .map_err(|_| format!("\nTest failed by trying to decode `{:?}` into `T`\n", result)) -} - -// Call total_supply contract message. -fn total_supply(addr: AccountId32, asset_id: AssetId) -> Balance { - let function = function_selector("total_supply"); - let params = [function, asset_id.encode()].concat(); - let result = bare_call(addr, params, 0).expect("should work"); - decoded::(result).unwrap() -} - -// Call balance_of contract message. -fn balance_of(addr: AccountId32, asset_id: AssetId, owner: AccountId32) -> Balance { - let function = function_selector("balance_of"); - let params = [function, asset_id.encode(), owner.encode()].concat(); - let result = bare_call(addr, params, 0).expect("should work"); - decoded::(result).unwrap() -} - -// Call allowance contract message. -fn allowance( - addr: AccountId32, - asset_id: AssetId, - owner: AccountId32, - spender: AccountId32, -) -> Balance { - let function = function_selector("allowance"); - let params = [function, asset_id.encode(), owner.encode(), spender.encode()].concat(); - let result = bare_call(addr, params, 0).expect("should work"); - decoded::(result).unwrap() -} - -// Call token_name contract message. -fn token_name(addr: AccountId32, asset_id: AssetId) -> Vec { - let function = function_selector("token_name"); - let params = [function, asset_id.encode()].concat(); - let result = bare_call(addr, params, 0).expect("should work"); - decoded::>(result).unwrap() -} - -// Call token_symbol contract message. -fn token_symbol(addr: AccountId32, asset_id: AssetId) -> Vec { - let function = function_selector("token_symbol"); - let params = [function, asset_id.encode()].concat(); - let result = bare_call(addr, params, 0).expect("should work"); - decoded::>(result).unwrap() -} - -// Call token_decimals contract message. -fn token_decimals(addr: AccountId32, asset_id: AssetId) -> u8 { - let function = function_selector("token_decimals"); - let params = [function, asset_id.encode()].concat(); - let result = bare_call(addr, params, 0).expect("should work"); - decoded::(result).unwrap() -} - -fn transfer( - addr: AccountId32, - asset_id: AssetId, - to: AccountId32, - value: Balance, -) -> ExecReturnValue { - let function = function_selector("transfer"); - let params = [function, asset_id.encode(), to.encode(), value.encode()].concat(); - let result = bare_call(addr, params, 0).expect("should work"); - result -} - -fn transfer_from( - addr: AccountId32, - asset_id: AssetId, - from: AccountId32, - to: AccountId32, - value: Balance, -) -> ExecReturnValue { - let function = function_selector("transfer_from"); - let data: Vec = vec![]; - let params = - [function, asset_id.encode(), from.encode(), to.encode(), value.encode(), data.encode()] - .concat(); - let result = bare_call(addr, params, 0).expect("should work"); - result -} - -fn approve( - addr: AccountId32, - asset_id: AssetId, - spender: AccountId32, - value: Balance, -) -> ExecReturnValue { - let function = function_selector("approve"); - let params = [function, asset_id.encode(), spender.encode(), value.encode()].concat(); - let result = bare_call(addr, params, 0).expect("should work"); - result -} - -fn increase_allowance( - addr: AccountId32, - asset_id: AssetId, - spender: AccountId32, - value: Balance, -) -> ExecReturnValue { - let function = function_selector("increase_allowance"); - let params = [function, asset_id.encode(), spender.encode(), value.encode()].concat(); - let result = bare_call(addr, params, 0).expect("should work"); - result -} - -fn decrease_allowance( - addr: AccountId32, - asset_id: AssetId, - spender: AccountId32, - value: Balance, -) -> ExecReturnValue { - let function = function_selector("decrease_allowance"); - let params = [function, asset_id.encode(), spender.encode(), value.encode()].concat(); - let result = bare_call(addr, params, 0).expect("should work"); - result -} - -// fn asset_exists(addr: AccountId32, asset_id: AssetId) -> bool { -// let function = function_selector("asset_exists"); -// let params = [function, asset_id.encode()].concat(); -// let result = bare_call(addr, params, 0).expect("should work"); -// decoded::(result) -// } -// -// fn create( -// addr: AccountId32, -// asset_id: AssetId, -// admin: AccountId32, -// min_balance: Balance, -// ) -> ExecReturnValue { -// let function = function_selector("create"); -// let params = [function, asset_id.encode(), admin.encode(), min_balance.encode()].concat(); -// bare_call(addr, params, 0).expect("should work") -// } -// -// fn set_metadata( -// addr: AccountId32, -// asset_id: AssetId, -// name: Vec, -// symbol: Vec, -// decimals: u8, -// ) -> ExecReturnValue { -// let function = function_selector("set_metadata"); -// let params = -// [function, asset_id.encode(), name.encode(), symbol.encode(), decimals.encode()].concat(); -// bare_call(addr, params, 0).expect("should work") -// } - -fn create_asset(owner: AccountId32, asset_id: AssetId, min_balance: Balance) -> AssetId { - assert_ok!(Assets::create( - RuntimeOrigin::signed(owner.clone()), - asset_id.into(), - owner.into(), - min_balance - )); - asset_id -} - -fn mint_asset(owner: AccountId32, asset_id: AssetId, to: AccountId32, value: Balance) -> AssetId { - assert_ok!(Assets::mint( - RuntimeOrigin::signed(owner.clone()), - asset_id.into(), - to.into(), - value - )); - asset_id -} - -fn create_asset_and_mint_to( - owner: AccountId32, - asset_id: AssetId, - to: AccountId32, - value: Balance, -) -> AssetId { - create_asset(owner.clone(), asset_id, 1); - mint_asset(owner, asset_id, to, value) -} - -// Create an asset, mints to, and approves spender. -fn create_asset_mint_and_approve( - owner: AccountId32, - asset_id: AssetId, - to: AccountId32, - mint: Balance, - spender: AccountId32, - approve: Balance, -) -> AssetId { - let asset = create_asset_and_mint_to(owner.clone(), asset_id, to.clone(), mint); - assert_ok!(Assets::approve_transfer( - RuntimeOrigin::signed(to.into()), - asset_id.into(), - spender.into(), - approve, - )); - asset -} - -// Freeze an asset. -fn freeze_asset(owner: AccountId32, asset_id: AssetId) { - assert_ok!(Assets::freeze_asset(RuntimeOrigin::signed(owner.into()), asset_id.into())); -} - -// Thaw an asset. -fn thaw_asset(owner: AccountId32, asset_id: AssetId) { - assert_ok!(Assets::thaw_asset(RuntimeOrigin::signed(owner.into()), asset_id.into())); -} - -// Start destroying an asset. -fn start_destroy_asset(owner: AccountId32, asset_id: AssetId) { - assert_ok!(Assets::start_destroy(RuntimeOrigin::signed(owner.into()), asset_id.into())); -} - -// Create an asset and set metadata. -fn create_asset_and_set_metadata( - owner: AccountId32, - asset_id: AssetId, - name: Vec, - symbol: Vec, - decimals: u8, -) { - assert_ok!(Assets::create( - RuntimeOrigin::signed(owner.clone()), - asset_id.into(), - owner.clone().into(), - 100 - )); - set_metadata_asset(owner, asset_id, name, symbol, decimals); -} - -// Set metadata of an asset. -fn set_metadata_asset( - owner: AccountId32, - asset_id: AssetId, - name: Vec, - symbol: Vec, - decimals: u8, -) { - assert_ok!(Assets::set_metadata( - RuntimeOrigin::signed(owner.into()), - asset_id.into(), - name, - symbol, - decimals - )); -} - -fn token_name_asset(asset_id: AssetId) -> Vec { - as MetadataInspect>::name( - asset_id, - ) -} - -fn token_symbol_asset(asset_id: AssetId) -> Vec { - as MetadataInspect>::symbol( - asset_id, - ) -} - -fn token_decimals_asset(asset_id: AssetId) -> u8 { - as MetadataInspect>::decimals( - asset_id, - ) -} - -/// 1. PSP-22 Interface: -/// - total_supply -/// - balance_of -/// - allowance -/// - transfer -/// - transfer_from -/// - approve -/// - increase_allowance -/// - decrease_allowance - -#[test] -fn total_supply_works() { - new_test_ext().execute_with(|| { - let _ = env_logger::try_init(); - let addr = instantiate(CONTRACT, INIT_VALUE, vec![]); - - // No tokens in circulation. - assert_eq!(Assets::total_supply(ASSET_ID), total_supply(addr.clone(), ASSET_ID)); - assert_eq!(0, total_supply(addr.clone(), ASSET_ID)); - - // Tokens in circulation. - create_asset_and_mint_to(addr.clone(), ASSET_ID, BOB, 100); - assert_eq!(Assets::total_supply(ASSET_ID), total_supply(addr.clone(), ASSET_ID)); - assert_eq!(100, total_supply(addr, ASSET_ID)); - }); -} - -#[test] -fn balance_of_works() { - new_test_ext().execute_with(|| { - let _ = env_logger::try_init(); - let addr = instantiate(CONTRACT, INIT_VALUE, vec![]); - - // No tokens in circulation. - assert_eq!(Assets::balance(ASSET_ID, BOB), balance_of(addr.clone(), ASSET_ID, BOB)); - assert_eq!(0, balance_of(addr.clone(), ASSET_ID, BOB)); - - // Tokens in circulation. - create_asset_and_mint_to(addr.clone(), ASSET_ID, BOB, 100); - assert_eq!(Assets::balance(ASSET_ID, BOB), balance_of(addr.clone(), ASSET_ID, BOB)); - assert_eq!(100, balance_of(addr, ASSET_ID, BOB)); - }); -} - -#[test] -fn allowance_works() { - new_test_ext().execute_with(|| { - let _ = env_logger::try_init(); - let addr = instantiate(CONTRACT, INIT_VALUE, vec![]); - - // No tokens in circulation. - assert_eq!( - Assets::allowance(ASSET_ID, &BOB, &ALICE), - allowance(addr.clone(), ASSET_ID, BOB, ALICE) - ); - assert_eq!(0, allowance(addr.clone(), ASSET_ID, BOB, ALICE)); - - // Tokens in circulation. - create_asset_mint_and_approve(addr.clone(), ASSET_ID, BOB, 100, ALICE, 50); - assert_eq!( - Assets::allowance(ASSET_ID, &BOB, &ALICE), - allowance(addr.clone(), ASSET_ID, BOB, ALICE) - ); - assert_eq!(50, allowance(addr, ASSET_ID, BOB, ALICE)); - }); -} - -#[test] -fn transfer_works() { - new_test_ext().execute_with(|| { - let _ = env_logger::try_init(); - let addr = instantiate(CONTRACT, INIT_VALUE, vec![]); - let amount: Balance = 100 * UNIT; - - // Asset does not exist. - assert_eq!( - decoded::(transfer(addr.clone(), 1, BOB, amount,)), - Ok(Module { index: 52, error: 3 }), - ); - // Create asset with Alice as owner and mint `amount` to contract address. - let asset = create_asset_and_mint_to(ALICE, 1, addr.clone(), amount); - // Asset is not live, i.e. frozen or being destroyed. - freeze_asset(ALICE, asset); - assert_eq!( - decoded::(transfer(addr.clone(), asset, BOB, amount,)), - Ok(Module { index: 52, error: 16 }), - ); - thaw_asset(ALICE, asset); - // Not enough balance. - assert_eq!( - decoded::(transfer(addr.clone(), asset, BOB, amount + 1 * UNIT)), - Ok(Module { index: 52, error: 0 }), - ); - // Not enough balance due to ED. - assert_eq!( - decoded::(transfer(addr.clone(), asset, BOB, amount)), - Ok(Module { index: 52, error: 0 }), - ); - // Successful transfer. - let balance_before_transfer = Assets::balance(asset, &BOB); - let result = transfer(addr.clone(), asset, BOB, amount / 2); - assert!(!result.did_revert(), "Contract reverted!"); - let balance_after_transfer = Assets::balance(asset, &BOB); - assert_eq!(balance_after_transfer, balance_before_transfer + amount / 2); - // Transfer asset to account that does not exist. - assert_eq!( - decoded::(transfer(addr.clone(), asset, FERDIE, amount / 4)), - Ok(Token(CannotCreate)) - ); - // Asset is not live, i.e. frozen or being destroyed. - start_destroy_asset(ALICE, asset); - assert_eq!( - decoded::(transfer(addr.clone(), asset, BOB, amount / 4)), - Ok(Module { index: 52, error: 16 }), - ); - }); -} - -#[test] -fn transfer_from_works() { - new_test_ext().execute_with(|| { - let _ = env_logger::try_init(); - let addr = instantiate(CONTRACT, INIT_VALUE, vec![]); - let amount: Balance = 100 * UNIT; - - // Asset does not exist. - assert_eq!( - decoded::(transfer_from(addr.clone(), 1, ALICE, BOB, amount / 2)), - Ok(Module { index: 52, error: 3 }), - ); - // Create asset with Alice as owner and mint `amount` to contract address. - let asset = create_asset_and_mint_to(ALICE, 1, ALICE, amount); - // Unapproved transfer. - assert_eq!( - decoded::(transfer_from(addr.clone(), asset, ALICE, BOB, amount / 2)), - Ok(Module { index: 52, error: 10 }) - ); - assert_ok!(Assets::approve_transfer( - RuntimeOrigin::signed(ALICE.into()), - asset.into(), - addr.clone().into(), - amount + 1 * UNIT, - )); - // Asset is not live, i.e. frozen or being destroyed. - freeze_asset(ALICE, asset); - assert_eq!( - decoded::(transfer_from(addr.clone(), asset, ALICE, BOB, amount)), - Ok(Module { index: 52, error: 16 }), - ); - thaw_asset(ALICE, asset); - // Not enough balance. - assert_eq!( - decoded::(transfer_from(addr.clone(), asset, ALICE, BOB, amount + 1 * UNIT,)), - Ok(Module { index: 52, error: 0 }), - ); - // Successful transfer. - let balance_before_transfer = Assets::balance(asset, &BOB); - let result = transfer_from(addr.clone(), asset, ALICE, BOB, amount / 2); - assert!(!result.did_revert(), "Contract reverted!"); - let balance_after_transfer = Assets::balance(asset, &BOB); - assert_eq!(balance_after_transfer, balance_before_transfer + amount / 2); - }); -} - -#[test] -fn approve_works() { - new_test_ext().execute_with(|| { - let _ = env_logger::try_init(); - let addr = instantiate(CONTRACT, 0, vec![]); - let amount: Balance = 100 * UNIT; - // Asset does not exist. - assert_eq!( - decoded::(approve(addr.clone(), 0, BOB, amount)), - Ok(Module { index: 52, error: 3 }), - ); - let asset = create_asset_and_mint_to(ALICE, 0, addr.clone(), amount); - assert_eq!( - decoded::(approve(addr.clone(), asset, BOB, amount)), - Ok(ConsumerRemaining) - ); - - let addr = instantiate(CONTRACT, INIT_VALUE, vec![1]); - // Create asset with Alice as owner and mint `amount` to contract address. - let asset = create_asset_and_mint_to(ALICE, 1, addr.clone(), amount); - // Asset is not live, i.e. frozen or being destroyed. - freeze_asset(ALICE, asset); - assert_eq!( - decoded::(approve(addr.clone(), asset, BOB, amount)), - Ok(Module { index: 52, error: 16 }), - ); - thaw_asset(ALICE, asset); - // Successful approvals: - assert_eq!(0, Assets::allowance(asset, &addr, &BOB)); - assert!(!approve(addr.clone(), asset, BOB, amount).did_revert(), "Contract reverted!"); - assert_eq!(Assets::allowance(asset, &addr, &BOB), amount); - // Non-additive, sets new value. - assert!(!approve(addr.clone(), asset, BOB, amount / 2).did_revert(), "Contract reverted!"); - assert_eq!(Assets::allowance(asset, &addr, &BOB), amount / 2); - // Asset is not live, i.e. frozen or being destroyed. - start_destroy_asset(ALICE, asset); - assert_eq!( - decoded::(approve(addr.clone(), asset, BOB, amount)), - Ok(Module { index: 52, error: 16 }), - ); - }); -} - -#[test] -fn increase_allowance_works() { - new_test_ext().execute_with(|| { - let _ = env_logger::try_init(); - let addr = instantiate(CONTRACT, 0, vec![]); - let amount: Balance = 100 * UNIT; - // Asset does not exist. - assert_eq!( - decoded::(increase_allowance(addr.clone(), 0, BOB, amount)), - Ok(Module { index: 52, error: 3 }), - ); - let asset = create_asset_and_mint_to(ALICE, 0, addr.clone(), amount); - assert_eq!( - decoded::(increase_allowance(addr.clone(), asset, BOB, amount)), - Ok(ConsumerRemaining) - ); - - let addr = instantiate(CONTRACT, INIT_VALUE, vec![1]); - // Create asset with Alice as owner and mint `amount` to contract address. - let asset = create_asset_and_mint_to(ALICE, 1, addr.clone(), amount); - // Asset is not live, i.e. frozen or being destroyed. - freeze_asset(ALICE, asset); - assert_eq!( - decoded::(increase_allowance(addr.clone(), asset, BOB, amount)), - Ok(Module { index: 52, error: 16 }), - ); - thaw_asset(ALICE, asset); - // Successful approvals: - assert_eq!(0, Assets::allowance(asset, &addr, &BOB)); - assert!( - !increase_allowance(addr.clone(), asset, BOB, amount).did_revert(), - "Contract reverted!" - ); - assert_eq!(Assets::allowance(asset, &addr, &BOB), amount); - // Additive. - assert!( - !increase_allowance(addr.clone(), asset, BOB, amount).did_revert(), - "Contract reverted!" - ); - assert_eq!(Assets::allowance(asset, &addr, &BOB), amount * 2); - // Asset is not live, i.e. frozen or being destroyed. - start_destroy_asset(ALICE, asset); - assert_eq!( - decoded::(increase_allowance(addr.clone(), asset, BOB, amount)), - Ok(Module { index: 52, error: 16 }), - ); - }); -} - -#[test] -fn decrease_allowance_works() { - new_test_ext().execute_with(|| { - let _ = env_logger::try_init(); - let addr = instantiate(CONTRACT, INIT_VALUE, vec![]); - let amount: Balance = 100 * UNIT; - // Asset does not exist. - assert_eq!( - decoded::(decrease_allowance(addr.clone(), 0, BOB, amount)), - Ok(Module { index: 52, error: 3 }), - ); - // Create asset and mint to the address contract, delegate Bob to spend the `amount`. - let asset = - create_asset_mint_and_approve(addr.clone(), 0, addr.clone(), amount, BOB, amount); - // Asset is not live, i.e. frozen or being destroyed. - freeze_asset(addr.clone(), asset); - assert_eq!( - decoded::(decrease_allowance(addr.clone(), asset, BOB, amount)), - Ok(Module { index: 52, error: 16 }), - ); - thaw_asset(addr.clone(), asset); - // Successfully decrease allowance. - let bob_allowance_before = Assets::allowance(asset, &addr, &BOB); - let result = decrease_allowance(addr.clone(), 0, BOB, amount / 2 - 1 * UNIT); - assert!(!result.did_revert(), "Contract reverted!"); - let bob_allowance_after = Assets::allowance(asset, &addr, &BOB); - assert_eq!(bob_allowance_before - bob_allowance_after, amount / 2 - 1 * UNIT); - // Asset is not live, i.e. frozen or being destroyed. - start_destroy_asset(addr.clone(), asset); - assert_eq!( - decoded::(decrease_allowance(addr.clone(), asset, BOB, amount)), - Ok(Module { index: 52, error: 16 }), - ); - }); -} - -/// 2. PSP-22 Metadata Interface: -/// - token_name -/// - token_symbol -/// - token_decimals - -#[test] -fn token_metadata_works() { - new_test_ext().execute_with(|| { - let _ = env_logger::try_init(); - let addr = instantiate(CONTRACT, INIT_VALUE, vec![]); - - let name: Vec = vec![11, 12, 13]; - let symbol: Vec = vec![21, 22, 23]; - let decimals: u8 = 69; - // Token does not exist. - assert_eq!(token_name_asset(ASSET_ID), token_name(addr.clone(), ASSET_ID)); - assert_eq!(Vec::::new(), token_name(addr.clone(), ASSET_ID)); - assert_eq!(token_symbol_asset(ASSET_ID), token_symbol(addr.clone(), ASSET_ID)); - assert_eq!(Vec::::new(), token_symbol(addr.clone(), ASSET_ID)); - assert_eq!(token_decimals_asset(ASSET_ID), token_decimals(addr.clone(), ASSET_ID)); - assert_eq!(0, token_decimals(addr.clone(), ASSET_ID)); - - create_asset_and_set_metadata( - addr.clone(), - ASSET_ID, - name.clone(), - symbol.clone(), - decimals, - ); - assert_eq!(token_name_asset(ASSET_ID), token_name(addr.clone(), ASSET_ID)); - assert_eq!(name, token_name(addr.clone(), ASSET_ID)); - assert_eq!(token_symbol_asset(ASSET_ID), token_symbol(addr.clone(), ASSET_ID)); - assert_eq!(symbol, token_symbol(addr.clone(), ASSET_ID)); - assert_eq!(token_decimals_asset(ASSET_ID), token_decimals(addr.clone(), ASSET_ID)); - assert_eq!(decimals, token_decimals(addr.clone(), ASSET_ID)); - }); -} - -// #[test] -// #[ignore] -// fn asset_exists_works() { -// new_test_ext().execute_with(|| { -// let _ = env_logger::try_init(); -// let addr = -// instantiate(CONTRACT, INIT_VALUE, vec![]); -// -// // No tokens in circulation. -// assert_eq!(Assets::asset_exists(ASSET_ID), asset_exists(addr.clone(), ASSET_ID)); -// -// // Tokens in circulation. -// create_asset(addr.clone(), ASSET_ID, 1); -// assert_eq!(Assets::asset_exists(ASSET_ID), asset_exists(addr, ASSET_ID)); -// }); -// } - -// #[test] -// #[ignore] -// fn mint_works() { -// new_test_ext().execute_with(|| { -// let _ = env_logger::try_init(); -// let addr = -// instantiate(CONTRACT, INIT_VALUE, vec![]); -// let amount: Balance = 100 * UNIT; -// -// // Asset does not exist. -// assert_eq!( -// decoded::(transfer_from(addr.clone(), 1, None, Some(BOB), amount, &[0u8])), -// Token(UnknownAsset) -// ); -// let asset = create_asset(ALICE, 1, 2); -// // Minting can only be done by the owner. -// assert_eq!( -// decoded::(transfer_from(addr.clone(), asset, None, Some(BOB), amount, &[0u8])), -// Ok(Module { index: 52, error: 2 }), -// ); -// // Minimum balance of an asset can not be zero. -// assert_eq!( -// decoded::(transfer_from(addr.clone(), asset, None, Some(BOB), 1, &[0u8])), -// Token(BelowMinimum) -// ); -// let asset = create_asset(addr.clone(), 2, 2); -// // Asset is not live, i.e. frozen or being destroyed. -// freeze_asset(addr.clone(), asset); -// assert_eq!( -// decoded::(transfer_from(addr.clone(), asset, None, Some(BOB), amount, &[0u8])), -// Ok(Module { index: 52, error: 16 }), -// ); -// thaw_asset(addr.clone(), asset); -// // Successful mint. -// let balance_before_mint = Assets::balance(asset, &BOB); -// let result = transfer_from(addr.clone(), asset, None, Some(BOB), amount, &[0u8]); -// assert!(!result.did_revert(), "Contract reverted!"); -// let balance_after_mint = Assets::balance(asset, &BOB); -// assert_eq!(balance_after_mint, balance_before_mint + amount); -// // Can not mint more tokens than Balance::MAX. -// assert_eq!( -// decoded::(transfer_from( -// addr.clone(), -// asset, -// None, -// Some(BOB), -// Balance::MAX, -// &[0u8] -// )), -// Arithmetic(Overflow) -// ); -// // Asset is not live, i.e. frozen or being destroyed. -// start_destroy_asset(addr.clone(), asset); -// assert_eq!( -// decoded::(transfer_from(addr.clone(), asset, None, Some(BOB), amount, &[0u8])), -// Ok(Module { index: 52, error: 16 }), -// ); -// }); -// } - -// #[test] -// #[ignore] -// fn create_works() { -// new_test_ext().execute_with(|| { -// let _ = env_logger::try_init(); -// // Instantiate a contract without balance (relay token). -// let addr = instantiate(CONTRACT, 0, vec![0]); -// // No balance to pay for fees. -// assert_eq!( -// decoded::(create(addr.clone(), ASSET_ID, addr.clone(), 1)), -// Ok(Module { index: 10, error: 2 }), -// ); -// // Instantiate a contract without balance (relay token). -// let addr = instantiate(CONTRACT, 100, vec![2]); -// // No balance to pay the deposit. -// assert_eq!( -// decoded::(create(addr.clone(), ASSET_ID, addr.clone(), 1)), -// Ok(Module { index: 10, error: 2 }), -// ); -// // Instantiate a contract with balance. -// let addr = -// instantiate(CONTRACT, INIT_VALUE, vec![1]); -// assert_eq!( -// decoded::(create(addr.clone(), ASSET_ID, BOB, 0)), -// Ok(Module { index: 52, error: 7 }), -// ); -// create_asset(ALICE, ASSET_ID, 1); -// // Asset ID is already taken. -// assert_eq!( -// decoded::(create(addr.clone(), ASSET_ID, BOB, 1)), -// Ok(Module { index: 52, error: 5 }), -// ); -// // The minimal balance for an asset must be non zero. -// let new_asset = 2; -// let result = create(addr.clone(), new_asset, BOB, 1); -// assert!(!result.did_revert(), "Contract reverted!"); -// }); -// } - -// #[test] -// #[ignore] -// fn set_metadata_works() { -// new_test_ext().execute_with(|| { -// let _ = env_logger::try_init(); -// let addr = -// instantiate(CONTRACT, INIT_VALUE, vec![]); -// -// create_asset(addr.clone(), ASSET_ID, 1); -// let result = set_metadata(addr.clone(), ASSET_ID, vec![12], vec![12], 12); -// assert!(!result.did_revert(), "Contract reverted!"); -// }); -// } diff --git a/pop-api/src/lib.rs b/pop-api/src/lib.rs index 7fcfc85b..78a79f80 100644 --- a/pop-api/src/lib.rs +++ b/pop-api/src/lib.rs @@ -30,10 +30,10 @@ mod constants { /// Helper method to build `ChainExtensionMethod`. /// /// Parameters: -/// - 'version': The version of the chain extension -/// - 'function': The ID of the function -/// - 'module': The index of the runtime module -/// - 'dispatchable': The index of the module dispatchable functions +/// - 'version': The version of the chain extension. +/// - 'function': The ID of the function. +/// - 'module': The index of the runtime module. +/// - 'dispatchable': The index of the module dispatchable functions. fn build_extension_method( version: u8, function: u8, @@ -45,13 +45,13 @@ fn build_extension_method( /// Represents a status code returned by the runtime. /// -/// `StatusCode` encapsulates a `u32` value that indicates the status of an operation performed -/// by the runtime. It helps to communicate the success or failure of a Pop API call to the contract, +/// `StatusCode` encapsulates a `u32` value that indicates the status of an operation performed by +/// the runtime. It helps to communicate the success or failure of a Pop API call to the contract, /// providing a standardized way to handle errors. /// -/// This status code can be used to determine if an operation succeeded or if it encountered -/// an error. A `StatusCode` of `0` typically indicates success, while any other value represents -/// an error. +/// This status code can be used to determine if an operation succeeded or if it encountered an +/// error. A `StatusCode` of `0` typically indicates success, while any other value represents an +/// error. #[derive(Debug, Copy, Clone, PartialEq, Eq)] #[ink::scale_derive(Encode, Decode, TypeInfo)] pub struct StatusCode(pub u32); diff --git a/pop-api/src/v0/assets/fungibles.rs b/pop-api/src/v0/assets/fungibles.rs index 0712a80b..8600c439 100644 --- a/pop-api/src/v0/assets/fungibles.rs +++ b/pop-api/src/v0/assets/fungibles.rs @@ -3,22 +3,23 @@ use crate::{ primitives::{AccountId, AssetId, Balance}, Result, StatusCode, }; +pub use asset_management::*; use constants::*; use ink::{env::chain_extension::ChainExtensionMethod, prelude::vec::Vec}; pub use metadata::*; -/// Helper method to build a dispatch call `ChainExtensionMethod` for fungibles `v0` +/// Helper method to build a dispatch call `ChainExtensionMethod` for fungibles `v0`. /// /// Parameters: -/// - 'dispatchable': The index of the module dispatchable functions +/// - 'dispatchable': The index of the module dispatchable functions. fn build_dispatch(dispatchable: u8) -> ChainExtensionMethod<(), (), (), false> { crate::v0::build_dispatch(FUNGIBLES, dispatchable) } -/// Helper method to build a dispatch call `ChainExtensionMethod` for fungibles `v0`` +/// Helper method to build a dispatch call `ChainExtensionMethod` for fungibles `v0`. /// /// Parameters: -/// - 'state_query': The index of the runtime state query +/// - 'state_query': The index of the runtime state query. fn build_read_state(state_query: u8) -> ChainExtensionMethod<(), (), (), false> { crate::v0::build_read_state(FUNGIBLES, state_query) } @@ -27,48 +28,40 @@ fn build_read_state(state_query: u8) -> ChainExtensionMethod<(), (), (), false> /// 1. PSP-22 Interface /// 2. PSP-22 Metadata Interface /// 3. Asset Management +/// 4. PSP-22 Mintable & Burnable Interface mod constants { /// 1. PSP-22 Interface: - /// - total_supply - pub const TOTAL_SUPPLY: u8 = 0; - /// - balance_of - pub const BALANCE_OF: u8 = 1; - /// - allowance - pub const ALLOWANCE: u8 = 2; - /// - transfer + pub(super) const TOTAL_SUPPLY: u8 = 0; + pub(super) const BALANCE_OF: u8 = 1; + pub(super) const ALLOWANCE: u8 = 2; pub(super) const TRANSFER: u8 = 3; - /// - transfer_from pub(super) const TRANSFER_FROM: u8 = 4; - /// - approve pub(super) const APPROVE: u8 = 5; - /// - increase_allowance pub(super) const INCREASE_ALLOWANCE: u8 = 6; - /// - decrease_allowance pub(super) const DECREASE_ALLOWANCE: u8 = 7; /// 2. PSP-22 Metadata Interface: - /// - token_name - pub const TOKEN_NAME: u8 = 8; - /// - token_symbol - pub const TOKEN_SYMBOL: u8 = 9; - /// - token_decimals - pub const TOKEN_DECIMALS: u8 = 10; - - // 3. Asset Management: - // - create - // - start_destroy - // - destroy_accounts - // - destroy_approvals - // - finish_destroy - // - set_metadata - // - clear_metadata + pub(super) const TOKEN_NAME: u8 = 8; + pub(super) const TOKEN_SYMBOL: u8 = 9; + pub(super) const TOKEN_DECIMALS: u8 = 10; + + /// 3. Asset Management: + pub(super) const CREATE: u8 = 11; + pub(super) const START_DESTROY: u8 = 12; + pub(super) const SET_METADATA: u8 = 16; + pub(super) const CLEAR_METADATA: u8 = 17; + pub(super) const ASSET_EXISTS: u8 = 18; + + /// 4. PSP-22 Mintable & Burnable interface: + pub(super) const MINT: u8 = 19; + pub(super) const BURN: u8 = 20; } /// Returns the total token supply for a given asset ID. /// -/// # Arguments -/// * `id` - The ID of the asset. +/// # Parameters +/// - `id` - The ID of the asset. /// /// # Returns /// The total supply of the token, or an error if the operation fails. @@ -84,9 +77,9 @@ pub fn total_supply(id: AssetId) -> Result { /// Returns the account balance for the specified `owner` for a given asset ID. Returns `0` if /// the account is non-existent. /// -/// # Arguments -/// * `id` - The ID of the asset. -/// * `owner` - The account whose balance is being queried. +/// # Parameters +/// - `id` - The ID of the asset. +/// - `owner` - The account whose balance is being queried. /// /// # Returns /// The balance of the specified account, or an error if the operation fails. @@ -102,10 +95,10 @@ pub fn balance_of(id: AssetId, owner: AccountId) -> Result { /// Returns the amount which `spender` is still allowed to withdraw from `owner` for a given /// asset ID. Returns `0` if no allowance has been set. /// -/// # Arguments -/// * `id` - The ID of the asset. -/// * `owner` - The account that owns the tokens. -/// * `spender` - The account that is allowed to spend the tokens. +/// # Parameters +/// - `id` - The ID of the asset. +/// - `owner` - The account that owns the tokens. +/// - `spender` - The account that is allowed to spend the tokens. /// /// # Returns /// The remaining allowance, or an error if the operation fails. @@ -121,67 +114,66 @@ pub fn allowance(id: AssetId, owner: AccountId, spender: AccountId) -> Result Result<()> { +pub fn transfer(id: AssetId, to: AccountId, value: Balance) -> Result<()> { build_dispatch(TRANSFER) .input::<(AssetId, AccountId, Balance)>() .output::, true>() .handle_error_code::() - .call(&(id, target, amount)) + .call(&(id, to, value)) } -/// Transfers `value` tokens on behalf of `from` to account `to` with additional `data` -/// in unspecified format. If `from` is equal to `None`, tokens will be minted to account `to`. If -/// `to` is equal to `None`, tokens will be burned from account `from`. +/// Transfers `value` amount tokens on behalf of `from` to account `to` with additional `data` +/// in unspecified format. /// -/// # Arguments -/// * `id` - The ID of the asset. -/// * `from` - The account from which the tokens are transferred. -/// * `to` - The recipient account. -/// * `value` - The number of tokens to transfer. +/// # Parameters +/// - `id` - The ID of the asset. +/// - `from` - The account from which the tokens are transferred. +/// - `to` - The recipient account. +/// - `value` - The number of tokens to transfer. /// /// # Returns /// Returns `Ok(())` if successful, or an error if the transfer fails. #[inline] -pub fn transfer_from(id: AssetId, from: AccountId, to: AccountId, amount: Balance) -> Result<()> { +pub fn transfer_from(id: AssetId, from: AccountId, to: AccountId, value: Balance) -> Result<()> { build_dispatch(TRANSFER_FROM) .input::<(AssetId, AccountId, AccountId, Balance)>() .output::, true>() .handle_error_code::() - .call(&(id, from, to, amount)) + .call(&(id, from, to, value)) } /// Approves an account to spend a specified number of tokens on behalf of the caller. /// -/// # Arguments -/// * `id` - The ID of the asset. -/// * `spender` - The account that is allowed to spend the tokens. -/// * `value` - The number of tokens to approve. +/// # Parameters +/// - `id` - The ID of the asset. +/// - `spender` - The account that is allowed to spend the tokens. +/// - `value` - The number of tokens to approve. /// /// # Returns /// Returns `Ok(())` if successful, or an error if the approval fails. #[inline] -pub fn approve(id: AssetId, spender: AccountId, amount: Balance) -> Result<()> { +pub fn approve(id: AssetId, spender: AccountId, value: Balance) -> Result<()> { build_dispatch(APPROVE) .input::<(AssetId, AccountId, Balance)>() .output::, true>() .handle_error_code::() - .call(&(id, spender, amount)) + .call(&(id, spender, value)) } /// Increases the allowance of a spender. /// -/// # Arguments -/// * `id` - The ID of the asset. -/// * `spender` - The account that is allowed to spend the tokens. -/// * `value` - The number of tokens to increase the allowance by. +/// # Parameters +/// - `id` - The ID of the asset. +/// - `spender` - The account that is allowed to spend the tokens. +/// - `value` - The number of tokens to increase the allowance by. /// /// # Returns /// Returns `Ok(())` if successful, or an error if the operation fails. @@ -196,10 +188,10 @@ pub fn increase_allowance(id: AssetId, spender: AccountId, value: Balance) -> Re /// Decreases the allowance of a spender. /// -/// # Arguments -/// * `id` - The ID of the asset. -/// * `spender` - The account that is allowed to spend the tokens. -/// * `value` - The number of tokens to decrease the allowance by. +/// # Parameters +/// - `id` - The ID of the asset. +/// - `spender` - The account that is allowed to spend the tokens. +/// - `value` - The number of tokens to decrease the allowance by. /// /// # Returns /// Returns `Ok(())` if successful, or an error if the operation fails. @@ -212,12 +204,47 @@ pub fn decrease_allowance(id: AssetId, spender: AccountId, value: Balance) -> Re .call(&(id, spender, value)) } +/// Creates `value` amount tokens and assigns them to `account`, increasing the total supply. +/// +/// # Parameters +/// - `id` - The ID of the asset. +/// - `account` - The account to be credited with the created tokens. +/// - `value` - The number of tokens to mint. +/// +/// # Returns +/// Returns `Ok(())` if successful, or an error if the operation fails. +pub fn mint(id: AssetId, account: AccountId, value: Balance) -> Result<()> { + build_dispatch(MINT) + .input::<(AssetId, AccountId, Balance)>() + .output::, true>() + .handle_error_code::() + .call(&(id, account, value)) +} + +/// Destroys `value` amount tokens from `account`, reducing the total supply. +/// +/// # Parameters +/// - `id` - The ID of the asset. +/// - `account` - The account from which the tokens will be destroyed. +/// - `value` - The number of tokens to destroy. +/// +/// # Returns +/// Returns `Ok(())` if successful, or an error if the operation fails. +pub fn burn(id: AssetId, account: AccountId, value: Balance) -> Result<()> { + build_dispatch(BURN) + .input::<(AssetId, AccountId, Balance)>() + .output::, true>() + .handle_error_code::() + .call(&(id, account, value)) +} + pub mod metadata { use super::*; + /// Returns the token name for a given asset ID. /// - /// # Arguments - /// * `id` - The ID of the asset. + /// # Parameters + /// - `id` - The ID of the asset. /// /// # Returns /// The name of the token as a byte vector, or an error if the operation fails. @@ -232,8 +259,8 @@ pub mod metadata { /// Returns the token symbol for a given asset ID. /// - /// # Arguments - /// * `id` - The ID of the asset. + /// # Parameters + /// - `id` - The ID of the asset. /// /// # Returns /// The symbol of the token as a byte vector, or an error if the operation fails. @@ -248,11 +275,11 @@ pub mod metadata { /// Returns the token decimals for a given asset ID. /// - /// # Arguments - /// * `id` - The ID of the asset. + /// # Parameters + /// - `id` - The ID of the asset. /// /// # Returns - /// The number of decimals of the token as a byte vector, or an error if the operation fails. + /// The number of decimals of the token, or an error if the operation fails. #[inline] pub fn token_decimals(id: AssetId) -> Result { build_read_state(TOKEN_DECIMALS) @@ -263,90 +290,87 @@ pub mod metadata { } } -// pub asset_management { -// /// Create a new token with a given asset ID. -// /// -// /// # Arguments -// /// * `id` - The ID of the asset. -// /// * `admin` - The account that will administer the asset. -// /// * `min_balance` - The minimum balance required for accounts holding this asset. -// /// -// /// # Returns -// /// Returns `Ok(())` if successful, or an error if the creation fails. -// pub fn create(id: AssetId, admin: impl Into>, min_balance: Balance) -> Result<()> { -// Ok(()) -// } -// -// /// Start the process of destroying a token with a given asset ID. -// /// -// /// # Arguments -// /// * `id` - The ID of the asset. -// /// -// /// # Returns -// /// Returns `Ok(())` if successful, or an error if the operation fails. -// fn start_destroy(id: AssetId) -> Result<()> { -// Ok(()) -// } -// -// /// Destroy all accounts associated with a token with a given asset ID. -// /// -// /// # Arguments -// /// * `id` - The ID of the asset. -// /// -// /// # Returns -// /// Returns `Ok(())` if successful, or an error if the operation fails. -// fn destroy_accounts(id: AssetId) -> Result<()> { -// Ok(()) -// } -// -// /// Destroy all approvals associated with a token with a given asset ID. -// /// -// /// # Arguments -// /// * `id` - The ID of the asset. -// /// -// /// # Returns -// /// Returns `Ok(())` if successful, or an error if the operation fails. -// fn destroy_approvals(id: AssetId) -> Result<()> { -// Ok(()) -// } -// -// /// Complete the process of destroying a token with a given asset ID. -// /// -// /// # Arguments -// /// * `id` - The ID of the asset. -// /// -// /// # Returns -// /// Returns `Ok(())` if successful, or an error if the operation fails. -// fn finish_destroy(id: AssetId) -> Result<()> { -// Ok(()) -// } -// -// /// Set the metadata for a token with a given asset ID. -// /// -// /// # Arguments -// /// * `id` - The ID of the asset. -// /// -// /// # Returns -// /// Returns `Ok(())` if successful, or an error if the operation fails. -// pub fn set_metadata(id: AssetId, name: Vec, symbol: Vec, decimals: u8) -> Result<()> { -// Ok(()) -// } -// -// /// Clear the metadata for a token with a given asset ID. -// /// -// /// # Arguments -// /// * `id` - The ID of the asset. -// /// -// /// # Returns -// /// Returns `Ok(())` if successful, or an error if the operation fails. -// fn clear_metadata(id: AssetId) -> Result<()> { -// Ok(()) -// } -// } -// -// pub fn asset_exists(id: AssetId) -> Result { -// assets::asset_exists(id) -// } +pub mod asset_management { + use super::*; + + /// Create a new token with a given asset ID. + /// + /// # Parameters + /// - `id` - The ID of the asset. + /// - `admin` - The account that will administer the asset. + /// - `min_balance` - The minimum balance required for accounts holding this asset. + /// + /// # Returns + /// Returns `Ok(())` if successful, or an error if the creation fails. + pub fn create(id: AssetId, admin: AccountId, min_balance: Balance) -> Result<()> { + build_dispatch(CREATE) + .input::<(AssetId, AccountId, Balance)>() + .output::, true>() + .handle_error_code::() + .call(&(id, admin, min_balance)) + } + + /// Start the process of destroying a token with a given asset ID. + /// + /// # Parameters + /// - `id` - The ID of the asset. + /// + /// # Returns + /// Returns `Ok(())` if successful, or an error if the operation fails. + pub fn start_destroy(id: AssetId) -> Result<()> { + build_dispatch(START_DESTROY) + .input::() + .output::, true>() + .handle_error_code::() + .call(&(id)) + } + + /// Set the metadata for a token with a given asset ID. + /// + /// # Parameters + /// - `id`: The identifier of the asset to update. + /// - `name`: The user friendly name of this asset. Limited in length by `StringLimit`. + /// - `symbol`: The exchange symbol for this asset. Limited in length by `StringLimit`. + /// - `decimals`: The number of decimals this asset uses to represent one unit. + /// + /// # Returns + /// Returns `Ok(())` if successful, or an error if the operation fails. + pub fn set_metadata(id: AssetId, name: Vec, symbol: Vec, decimals: u8) -> Result<()> { + build_dispatch(SET_METADATA) + .input::<(AssetId, Vec, Vec, u8)>() + .output::, true>() + .handle_error_code::() + .call(&(id, name, symbol, decimals)) + } + + /// Clear the metadata for a token with a given asset ID. + /// + /// # Parameters + /// - `id` - The ID of the asset. + /// + /// # Returns + /// Returns `Ok(())` if successful, or an error if the operation fails. + pub fn clear_metadata(id: AssetId) -> Result<()> { + build_dispatch(CLEAR_METADATA) + .input::() + .output::, true>() + .handle_error_code::() + .call(&(id)) + } + + /// Checks if token with a given asset ID exists. + /// + /// # Parameters + /// - `id` - The ID of the asset. + #[inline] + pub fn asset_exists(id: AssetId) -> Result { + build_read_state(ASSET_EXISTS) + .input::() + .output::, true>() + .handle_error_code::() + .call(&(id)) + } +} /// Represents various errors related to local fungible assets in the Pop API. /// diff --git a/runtime/devnet/src/config/api.rs b/runtime/devnet/src/config/api.rs index b3932a79..bdff6bbb 100644 --- a/runtime/devnet/src/config/api.rs +++ b/runtime/devnet/src/config/api.rs @@ -25,6 +25,10 @@ impl Contains for AllowedApiCalls { | transfer_from { .. } | approve { .. } | increase_allowance { .. } | decrease_allowance { .. } + | create { .. } | set_metadata { .. } + | start_destroy { .. } + | clear_metadata { .. } + | mint { .. } | burn { .. } ) ) } @@ -40,7 +44,7 @@ impl Contains> for AllowedApiCalls { TotalSupply(..) | BalanceOf { .. } | Allowance { .. } | TokenName(..) | TokenSymbol(..) - | TokenDecimals(..) + | TokenDecimals(..) | AssetExists(..) ) ) } From 00c59032b3755d2cf8b3442095876612425116f9 Mon Sep 17 00:00:00 2001 From: Tin Chung <56880684+chungquantin@users.noreply.github.com> Date: Fri, 9 Aug 2024 18:37:37 +0700 Subject: [PATCH 035/112] refactor: remove bare_call code duplication in integration test (#168) --- .../integration-tests/src/fungibles/utils.rs | 91 +++++++------------ 1 file changed, 35 insertions(+), 56 deletions(-) diff --git a/pop-api/integration-tests/src/fungibles/utils.rs b/pop-api/integration-tests/src/fungibles/utils.rs index 2f9be65c..33a25f7a 100644 --- a/pop-api/integration-tests/src/fungibles/utils.rs +++ b/pop-api/integration-tests/src/fungibles/utils.rs @@ -1,13 +1,17 @@ use super::*; +fn do_bare_call(function: &str, addr: AccountId32, params: Vec) -> ExecReturnValue { + let function = function_selector(function); + let params = [function, params].concat(); + bare_call(addr, params, 0).expect("should work") +} + pub(super) fn decoded(result: ExecReturnValue) -> Result { ::decode(&mut &result.data[1..]).map_err(|_| result) } pub(super) fn total_supply(addr: AccountId32, asset_id: AssetId) -> Result { - let function = function_selector("total_supply"); - let params = [function, asset_id.encode()].concat(); - let result = bare_call(addr, params, 0).expect("should work"); + let result = do_bare_call("total_supply", addr, asset_id.encode()); decoded::>(result.clone()) .unwrap_or_else(|_| panic!("Contract reverted: {:?}", result)) } @@ -17,9 +21,8 @@ pub(super) fn balance_of( asset_id: AssetId, owner: AccountId32, ) -> Result { - let function = function_selector("balance_of"); - let params = [function, asset_id.encode(), owner.encode()].concat(); - let result = bare_call(addr, params, 0).expect("should work"); + let params = [asset_id.encode(), owner.encode()].concat(); + let result = do_bare_call("balance_of", addr, params); decoded::>(result.clone()) .unwrap_or_else(|_| panic!("Contract reverted: {:?}", result)) } @@ -30,41 +33,32 @@ pub(super) fn allowance( owner: AccountId32, spender: AccountId32, ) -> Result { - let function = function_selector("allowance"); - let params = [function, asset_id.encode(), owner.encode(), spender.encode()].concat(); - let result = bare_call(addr, params, 0).expect("should work"); + let params = [asset_id.encode(), owner.encode(), spender.encode()].concat(); + let result = do_bare_call("allowance", addr, params); decoded::>(result.clone()) .unwrap_or_else(|_| panic!("Contract reverted: {:?}", result)) } pub(super) fn token_name(addr: AccountId32, asset_id: AssetId) -> Result, Error> { - let function = function_selector("token_name"); - let params = [function, asset_id.encode()].concat(); - let result = bare_call(addr, params, 0).expect("should work"); + let result = do_bare_call("token_name", addr, asset_id.encode()); decoded::, Error>>(result.clone()) .unwrap_or_else(|_| panic!("Contract reverted: {:?}", result)) } pub(super) fn token_symbol(addr: AccountId32, asset_id: AssetId) -> Result, Error> { - let function = function_selector("token_symbol"); - let params = [function, asset_id.encode()].concat(); - let result = bare_call(addr, params, 0).expect("should work"); + let result = do_bare_call("token_symbol", addr, asset_id.encode()); decoded::, Error>>(result.clone()) .unwrap_or_else(|_| panic!("Contract reverted: {:?}", result)) } pub(super) fn token_decimals(addr: AccountId32, asset_id: AssetId) -> Result { - let function = function_selector("token_decimals"); - let params = [function, asset_id.encode()].concat(); - let result = bare_call(addr, params, 0).expect("should work"); + let result = do_bare_call("token_decimals", addr, asset_id.encode()); decoded::>(result.clone()) .unwrap_or_else(|_| panic!("Contract reverted: {:?}", result)) } pub(super) fn asset_exists(addr: AccountId32, asset_id: AssetId) -> Result { - let function = function_selector("asset_exists"); - let params = [function, asset_id.encode()].concat(); - let result = bare_call(addr, params, 0).expect("should work"); + let result = do_bare_call("asset_exists", addr, asset_id.encode()); decoded::>(result.clone()) .unwrap_or_else(|_| panic!("Contract reverted: {:?}", result)) } @@ -75,9 +69,8 @@ pub(super) fn transfer( to: AccountId32, value: Balance, ) -> Result<(), Error> { - let function = function_selector("transfer"); - let params = [function, asset_id.encode(), to.encode(), value.encode()].concat(); - let result = bare_call(addr, params, 0).expect("should work"); + let params = [asset_id.encode(), to.encode(), value.encode()].concat(); + let result = do_bare_call("transfer", addr, params); decoded::>(result.clone()) .unwrap_or_else(|_| panic!("Contract reverted: {:?}", result)) } @@ -89,12 +82,10 @@ pub(super) fn transfer_from( to: AccountId32, value: Balance, ) -> Result<(), Error> { - let function = function_selector("transfer_from"); let data: Vec = vec![]; let params = - [function, asset_id.encode(), from.encode(), to.encode(), value.encode(), data.encode()] - .concat(); - let result = bare_call(addr, params, 0).expect("should work"); + [asset_id.encode(), from.encode(), to.encode(), value.encode(), data.encode()].concat(); + let result = do_bare_call("transfer_from", addr, params); decoded::>(result.clone()) .unwrap_or_else(|_| panic!("Contract reverted: {:?}", result)) } @@ -105,9 +96,8 @@ pub(super) fn approve( spender: AccountId32, value: Balance, ) -> Result<(), Error> { - let function = function_selector("approve"); - let params = [function, asset_id.encode(), spender.encode(), value.encode()].concat(); - let result = bare_call(addr, params, 0).expect("should work"); + let params = [asset_id.encode(), spender.encode(), value.encode()].concat(); + let result = do_bare_call("approve", addr, params); decoded::>(result.clone()) .unwrap_or_else(|_| panic!("Contract reverted: {:?}", result)) } @@ -118,9 +108,8 @@ pub(super) fn increase_allowance( spender: AccountId32, value: Balance, ) -> Result<(), Error> { - let function = function_selector("increase_allowance"); - let params = [function, asset_id.encode(), spender.encode(), value.encode()].concat(); - let result = bare_call(addr, params, 0).expect("should work"); + let params = [asset_id.encode(), spender.encode(), value.encode()].concat(); + let result = do_bare_call("increase_allowance", addr, params); decoded::>(result.clone()) .unwrap_or_else(|_| panic!("Contract reverted: {:?}", result)) } @@ -131,9 +120,8 @@ pub(super) fn decrease_allowance( spender: AccountId32, value: Balance, ) -> Result<(), Error> { - let function = function_selector("decrease_allowance"); - let params = [function, asset_id.encode(), spender.encode(), value.encode()].concat(); - let result = bare_call(addr, params, 0).expect("should work"); + let params = [asset_id.encode(), spender.encode(), value.encode()].concat(); + let result = do_bare_call("decrease_allowance", addr, params); decoded::>(result.clone()) .unwrap_or_else(|_| panic!("Contract reverted: {:?}", result)) } @@ -144,17 +132,14 @@ pub(super) fn create( admin: AccountId32, min_balance: Balance, ) -> Result<(), Error> { - let function = function_selector("create"); - let params = [function, asset_id.encode(), admin.encode(), min_balance.encode()].concat(); - let result = bare_call(addr, params, 0).expect("should work"); + let params = [asset_id.encode(), admin.encode(), min_balance.encode()].concat(); + let result = do_bare_call("create", addr, params); decoded::>(result.clone()) .unwrap_or_else(|_| panic!("Contract reverted: {:?}", result)) } pub(super) fn start_destroy(addr: AccountId32, asset_id: AssetId) -> Result<(), Error> { - let function = function_selector("start_destroy"); - let params = [function, asset_id.encode()].concat(); - let result = bare_call(addr, params, 0).expect("should work"); + let result = do_bare_call("start_destroy", addr, asset_id.encode()); match decoded::>(result) { Ok(x) => x, Err(result) => panic!("Contract reverted: {:?}", result), @@ -168,18 +153,14 @@ pub(super) fn set_metadata( symbol: Vec, decimals: u8, ) -> Result<(), Error> { - let function = function_selector("set_metadata"); - let params = - [function, asset_id.encode(), name.encode(), symbol.encode(), decimals.encode()].concat(); - let result = bare_call(addr, params, 0).expect("should work"); + let params = [asset_id.encode(), name.encode(), symbol.encode(), decimals.encode()].concat(); + let result = do_bare_call("set_metadata", addr, params); decoded::>(result.clone()) .unwrap_or_else(|_| panic!("Contract reverted: {:?}", result)) } pub(super) fn clear_metadata(addr: AccountId32, asset_id: AssetId) -> Result<(), Error> { - let function = function_selector("clear_metadata"); - let params = [function, asset_id.encode()].concat(); - let result = bare_call(addr, params, 0).expect("should work"); + let result = do_bare_call("clear_metadata", addr, asset_id.encode()); decoded::>(result.clone()) .unwrap_or_else(|_| panic!("Contract reverted: {:?}", result)) } @@ -190,9 +171,8 @@ pub(super) fn mint( account: AccountId32, amount: Balance, ) -> Result<(), Error> { - let function = function_selector("mint"); - let params = [function, asset_id.encode(), account.encode(), amount.encode()].concat(); - let result = bare_call(addr, params, 0).expect("should work"); + let params = [asset_id.encode(), account.encode(), amount.encode()].concat(); + let result = do_bare_call("mint", addr, params); decoded::>(result.clone()) .unwrap_or_else(|_| panic!("Contract reverted: {:?}", result)) } @@ -203,9 +183,8 @@ pub(super) fn burn( account: AccountId32, amount: Balance, ) -> Result<(), Error> { - let function = function_selector("burn"); - let params = [function, asset_id.encode(), account.encode(), amount.encode()].concat(); - let result = bare_call(addr, params, 0).expect("should work"); + let params = [asset_id.encode(), account.encode(), amount.encode()].concat(); + let result = do_bare_call("burn", addr, params); decoded::>(result.clone()) .unwrap_or_else(|_| panic!("Contract reverted: {:?}", result)) } From 9ebe1621081f0593bf93096bccf86e1a5b761317 Mon Sep 17 00:00:00 2001 From: Daanvdplas Date: Tue, 13 Aug 2024 10:52:42 +0200 Subject: [PATCH 036/112] fix: compilation --- Cargo.lock | 1621 +++++++++++++++++++++++++++------------------------- 1 file changed, 831 insertions(+), 790 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 982705a3..7f033a20 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -23,11 +23,11 @@ dependencies = [ [[package]] name = "addr2line" -version = "0.21.0" +version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +checksum = "6e4503c46a5c0c7844e948c9a4d6acd9f50cccb4de1c48eb9e291ea17470c678" dependencies = [ - "gimli 0.28.1", + "gimli 0.29.0", ] [[package]] @@ -68,7 +68,7 @@ dependencies = [ "cipher 0.4.4", "ctr", "ghash", - "subtle 2.5.0", + "subtle 2.4.1", ] [[package]] @@ -77,7 +77,7 @@ version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "891477e0c6a8957309ee5c45a6368af3ae14bb510732d2684ffa19af310920f9" dependencies = [ - "getrandom 0.2.12", + "getrandom 0.2.15", "once_cell", "version_check", ] @@ -89,7 +89,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" dependencies = [ "cfg-if", - "getrandom 0.2.12", + "getrandom 0.2.15", "once_cell", "version_check", "zerocopy", @@ -106,9 +106,9 @@ dependencies = [ [[package]] name = "allocator-api2" -version = "0.2.16" +version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" +checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f" [[package]] name = "always-assert" @@ -142,47 +142,48 @@ dependencies = [ [[package]] name = "anstream" -version = "0.6.13" +version = "0.6.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d96bd03f33fe50a863e394ee9718a706f988b9079b20c3784fb726e7678b62fb" +checksum = "64e15c1ab1f89faffbf04a634d5e1962e9074f2741eef6d97f3c4e322426d526" dependencies = [ "anstyle", "anstyle-parse", "anstyle-query", "anstyle-wincon", "colorchoice", + "is_terminal_polyfill", "utf8parse", ] [[package]] name = "anstyle" -version = "1.0.6" +version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8901269c6307e8d93993578286ac0edf7f195079ffff5ebdeea6a59ffb7e36bc" +checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1" [[package]] name = "anstyle-parse" -version = "0.2.3" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c75ac65da39e5fe5ab759307499ddad880d724eed2f6ce5b5e8a26f4f387928c" +checksum = "eb47de1e80c2b463c735db5b217a0ddc39d612e7ac9e2e96a5aed1f57616c1cb" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" -version = "1.0.2" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648" +checksum = "6d36fc52c7f6c869915e99412912f22093507da8d9e942ceaf66fe4b7c14422a" dependencies = [ "windows-sys 0.52.0", ] [[package]] name = "anstyle-wincon" -version = "3.0.2" +version = "3.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7" +checksum = "5bf74e1b6e971609db8ca7a9ce79fd5768ab6ae46441c572e46cf596f59e57f8" dependencies = [ "anstyle", "windows-sys 0.52.0", @@ -190,9 +191,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.81" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0952808a6c2afd1aa8947271f3a60f1a6763c7b912d210184c5149b5cf147247" +checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" [[package]] name = "approx" @@ -214,7 +215,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.55", + "syn 2.0.74", ] [[package]] @@ -354,15 +355,15 @@ checksum = "f52f63c5c1316a16a4b35eaac8b76a98248961a533f061684cb2a7cb0eafb6c6" [[package]] name = "array-bytes" -version = "6.2.2" +version = "6.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f840fb7195bcfc5e17ea40c26e5ce6d5b9ce5d584466e17703209657e459ae0" +checksum = "5d5dde061bd34119e902bbb2d9b90c5692635cf59fb91d582c2b68043f1b8293" [[package]] name = "arrayref" -version = "0.3.7" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b4930d2cb77ce62f89ee5d5289b4ac049559b1c45539271f5ed4fdc7db34545" +checksum = "9d151e35f61089500b617991b791fc8bfd237ae50cd5950803758a179b41e67a" [[package]] name = "arrayvec" @@ -404,7 +405,7 @@ dependencies = [ "proc-macro2", "quote", "syn 1.0.109", - "synstructure", + "synstructure 0.12.6", ] [[package]] @@ -427,7 +428,7 @@ checksum = "9b34d609dfbaf33d6889b2b7106d3ca345eacad44200913df5ba02bfd31d2ba9" [[package]] name = "asset-hub-paseo-runtime" version = "1.0.0" -source = "git+https://github.com/paseo-network/runtimes/?tag=v1.2.5-system-chains#e7265b10b28d8b82c3146e72c98895dac2b55729" +source = "git+https://github.com/paseo-network/runtimes/?tag=v1.2.5-system-chains#2fa66a19eef96bd2c079385057fab2564d09b751" dependencies = [ "assets-common", "bp-asset-hub-paseo", @@ -468,6 +469,7 @@ dependencies = [ "pallet-transaction-payment-rpc-runtime-api", "pallet-uniques", "pallet-utility", + "pallet-vesting", "pallet-xcm", "pallet-xcm-benchmarks", "pallet-xcm-bridge-hub-router", @@ -570,27 +572,25 @@ dependencies = [ [[package]] name = "async-channel" -version = "2.2.0" +version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f28243a43d821d11341ab73c80bed182dc015c514b951616cf79bd4af39af0c3" +checksum = "89b47800b0be77592da0afd425cc03468052844aff33b84e33cc696f64e77b6a" dependencies = [ "concurrent-queue", - "event-listener 5.2.0", - "event-listener-strategy 0.5.0", + "event-listener-strategy", "futures-core", - "pin-project-lite 0.2.13", + "pin-project-lite 0.2.14", ] [[package]] name = "async-executor" -version = "1.8.0" +version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17ae5ebefcc48e7452b4987947920dac9450be1110cadf34d1b8c116bdbaf97c" +checksum = "d7ebdfa2ebdab6b1760375fa7d6f382b9f486eac35fc994625a00e89280bdbb7" dependencies = [ - "async-lock 3.3.0", "async-task", "concurrent-queue", - "fastrand 2.0.2", + "fastrand 2.1.0", "futures-lite 2.3.0", "slab", ] @@ -629,21 +629,21 @@ dependencies = [ [[package]] name = "async-io" -version = "2.3.2" +version = "2.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcccb0f599cfa2f8ace422d3555572f47424da5648a4382a9dd0310ff8210884" +checksum = "444b0228950ee6501b3568d3c93bf1176a1fdbc3b758dcd9475046d30f4dc7e8" dependencies = [ - "async-lock 3.3.0", + "async-lock 3.4.0", "cfg-if", "concurrent-queue", "futures-io", "futures-lite 2.3.0", "parking", - "polling 3.6.0", - "rustix 0.38.32", + "polling 3.7.3", + "rustix 0.38.34", "slab", "tracing", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -657,13 +657,13 @@ dependencies = [ [[package]] name = "async-lock" -version = "3.3.0" +version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d034b430882f8381900d3fe6f0aaa3ad94f2cb4ac519b429692a1bc2dda4ae7b" +checksum = "ff6e472cdea888a4bd64f342f09b3f50e1886d32afe8df3d663c01140b811b18" dependencies = [ - "event-listener 4.0.3", - "event-listener-strategy 0.4.0", - "pin-project-lite 0.2.13", + "event-listener 5.3.1", + "event-listener-strategy", + "pin-project-lite 0.2.14", ] [[package]] @@ -690,43 +690,43 @@ dependencies = [ "cfg-if", "event-listener 3.1.0", "futures-lite 1.13.0", - "rustix 0.38.32", + "rustix 0.38.34", "windows-sys 0.48.0", ] [[package]] name = "async-signal" -version = "0.2.5" +version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e47d90f65a225c4527103a8d747001fc56e375203592b25ad103e1ca13124c5" +checksum = "637e00349800c0bdf8bfc21ebbc0b6524abea702b0da4168ac00d070d0c0b9f3" dependencies = [ - "async-io 2.3.2", - "async-lock 2.8.0", + "async-io 2.3.4", + "async-lock 3.4.0", "atomic-waker", "cfg-if", "futures-core", "futures-io", - "rustix 0.38.32", + "rustix 0.38.34", "signal-hook-registry", "slab", - "windows-sys 0.48.0", + "windows-sys 0.59.0", ] [[package]] name = "async-task" -version = "4.7.0" +version = "4.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbb36e985947064623dbd357f727af08ffd077f93d696782f3c56365fa2e2799" +checksum = "8b75356056920673b02621b35afd0f7dda9306d03c79a30f5c56c44cf256e3de" [[package]] name = "async-trait" -version = "0.1.79" +version = "0.1.81" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a507401cad91ec6a857ed5513a2073c82a9b9048762b885bb98655b306964681" +checksum = "6e0c28dcc82d7c8ead5cb13beb15405b57b8546e93215673ff8ca0349a028107" dependencies = [ "proc-macro2", "quote", - "syn 2.0.55", + "syn 2.0.74", ] [[package]] @@ -739,7 +739,7 @@ dependencies = [ "futures-sink", "futures-util", "memchr", - "pin-project-lite 0.2.13", + "pin-project-lite 0.2.14", ] [[package]] @@ -756,22 +756,22 @@ checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" [[package]] name = "autocfg" -version = "1.2.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1fdabc7756949593fe60f30ec81974b613357de856987752631dea1e3394c80" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "backtrace" -version = "0.3.71" +version = "0.3.73" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26b05800d2e817c8b3b4b54abd461726265fa9789ae34330622f2db9ee696f9d" +checksum = "5cc23269a4f8976d0a4d2e7109211a419fe30e8d88d677cd60b6bc79c5732e0a" dependencies = [ - "addr2line 0.21.0", + "addr2line 0.22.0", "cc", "cfg-if", "libc", "miniz_oxide", - "object 0.32.2", + "object 0.36.3", "rustc-demangle", ] @@ -845,13 +845,13 @@ dependencies = [ "lazy_static", "lazycell", "peeking_take_while", - "prettyplease 0.2.17", + "prettyplease 0.2.20", "proc-macro2", "quote", "regex", "rustc-hash", "shlex", - "syn 2.0.55", + "syn 2.0.74", ] [[package]] @@ -881,9 +881,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.5.0" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" [[package]] name = "bitvec" @@ -953,9 +953,9 @@ dependencies = [ [[package]] name = "blake3" -version = "1.5.1" +version = "1.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30cca6d3674597c30ddf2c587bf8d9d65c9a84d2326d941cc79c9842dfe0ef52" +checksum = "e9ec96fe9a81b5e365f9db71fe00edc4fe4ca2cc7dcb7861f0603012a7caa210" dependencies = [ "arrayref", "arrayvec 0.7.4", @@ -984,18 +984,15 @@ dependencies = [ [[package]] name = "blocking" -version = "1.5.1" +version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a37913e8dc4ddcc604f0c6d3bf2887c995153af3611de9e23c352b44c1b9118" +checksum = "703f41c54fc768e63e091340b424302bb1c29ef4aa0c7f10fe849dfb114d29ea" dependencies = [ - "async-channel 2.2.0", - "async-lock 3.3.0", + "async-channel 2.3.1", "async-task", - "fastrand 2.0.2", "futures-io", "futures-lite 2.3.0", "piper", - "tracing", ] [[package]] @@ -1022,7 +1019,7 @@ dependencies = [ [[package]] name = "bp-asset-hub-paseo" version = "1.0.0" -source = "git+https://github.com/paseo-network/runtimes/?tag=v1.2.5-system-chains#e7265b10b28d8b82c3146e72c98895dac2b55729" +source = "git+https://github.com/paseo-network/runtimes/?tag=v1.2.5-system-chains#2fa66a19eef96bd2c079385057fab2564d09b751" dependencies = [ "frame-support", "sp-std", @@ -1049,7 +1046,7 @@ dependencies = [ [[package]] name = "bp-bridge-hub-paseo" version = "1.0.0" -source = "git+https://github.com/paseo-network/runtimes/?tag=v1.2.5-system-chains#e7265b10b28d8b82c3146e72c98895dac2b55729" +source = "git+https://github.com/paseo-network/runtimes/?tag=v1.2.5-system-chains#2fa66a19eef96bd2c079385057fab2564d09b751" dependencies = [ "bp-bridge-hub-cumulus", "bp-messages", @@ -1066,9 +1063,9 @@ dependencies = [ [[package]] name = "bp-header-chain" -version = "0.8.0" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96157f586811969b3911d26cc79e02b28cfbecf859d96d7c12b6af10b9ea9350" +checksum = "1c4d2c457d5e18a5dbfe47a2ecd01f95036930a4a7ac0f3e47c2843bb067331b" dependencies = [ "bp-runtime", "finality-grandpa", @@ -1278,9 +1275,9 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.15.4" +version = "3.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ff69b9dd49fd426c69a0db9fc04dd934cdb6645ff000864d98f7e2af8830eaa" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" [[package]] name = "byte-slice-cast" @@ -1296,9 +1293,9 @@ checksum = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7" [[package]] name = "bytemuck" -version = "1.15.0" +version = "1.16.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d6d68c57235a3a081186990eca2867354726650f42f7516ca50c28d6281fd15" +checksum = "102087e286b4677862ea56cf8fc58bb2cdfa8725c40ffb80fe3a008eb7f2fc83" [[package]] name = "byteorder" @@ -1308,9 +1305,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.6.0" +version = "1.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9" +checksum = "8318a53db07bb3f8dca91a600466bdb3f2eaadeedfdbcf02e1accbad9271ba50" [[package]] name = "bzip2-sys" @@ -1335,9 +1332,9 @@ dependencies = [ [[package]] name = "camino" -version = "1.1.6" +version = "1.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c59e92b5a388f549b863a7bea62612c09f24c8393560709a54558a9abdfb3b9c" +checksum = "e0ec6b951b160caa93cc0c7b209e5a3bff7aae9062213451ac99493cd844c239" dependencies = [ "serde", ] @@ -1359,7 +1356,7 @@ checksum = "eee4243f1f26fc7a42710e7439c149e2b10b05472f88090acce52632f231a73a" dependencies = [ "camino", "cargo-platform", - "semver 1.0.22", + "semver 1.0.23", "serde", "serde_json", "thiserror", @@ -1367,9 +1364,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.0.90" +version = "1.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8cd6604a82acf3039f1144f54b8eb34e91ffba622051189e71b781822d5ee1f5" +checksum = "e9e8aabfac534be767c909e0690571677d49f41bd8465ae876fe043d52ba5292" dependencies = [ "jobserver", "libc", @@ -1386,9 +1383,9 @@ dependencies = [ [[package]] name = "cfg-expr" -version = "0.15.7" +version = "0.15.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa50868b64a9a6fda9d593ce778849ea8715cd2a3d2cc17ffdb4a2f2f2f1961d" +checksum = "d067ad48b8650848b989a59a86c6c36a995d02d2bf778d45c3c5d57bc2718f02" dependencies = [ "smallvec", ] @@ -1441,16 +1438,16 @@ dependencies = [ [[package]] name = "chrono" -version = "0.4.35" +version = "0.4.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8eaf5903dcbc0a39312feb77df2ff4c76387d591b9fc7b04a238dcf8bb62639a" +checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" dependencies = [ "android-tzdata", "iana-time-zone", "js-sys", "num-traits", "wasm-bindgen", - "windows-targets 0.52.4", + "windows-targets 0.52.6", ] [[package]] @@ -1497,9 +1494,9 @@ dependencies = [ [[package]] name = "clang-sys" -version = "1.7.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67523a3b4be3ce1989d607a828d036249522dd9c1c8de7f4dd2dae43a37369d1" +checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4" dependencies = [ "glob", "libc", @@ -1508,9 +1505,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.4" +version = "4.5.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90bc066a67923782aa8515dbaea16946c5bcc5addbd668bb80af688e53e548a0" +checksum = "11d8838454fda655dafd3accb2b6e2bea645b9e4078abe84a22ceb947235c5cc" dependencies = [ "clap_builder", "clap_derive", @@ -1518,9 +1515,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.2" +version = "4.5.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae129e2e766ae0ec03484e609954119f123cc1fe650337e155d03b022f24f7b4" +checksum = "216aec2b177652e3846684cbfe25c9964d18ec45234f0f5da5157b207ed1aab6" dependencies = [ "anstream", "anstyle", @@ -1531,21 +1528,21 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.4" +version = "4.5.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "528131438037fd55894f62d6e9f068b8f45ac57ffa77517819645d10aed04f64" +checksum = "501d359d5f3dcaf6ecdeee48833ae73ec6e42723a1e52419c79abf9507eec0a0" dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.55", + "syn 2.0.74", ] [[package]] name = "clap_lex" -version = "0.7.0" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce" +checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97" [[package]] name = "coarsetime" @@ -1570,39 +1567,39 @@ dependencies = [ [[package]] name = "color-print" -version = "0.3.5" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a858372ff14bab9b1b30ea504f2a4bc534582aee3e42ba2d41d2a7baba63d5d" +checksum = "1ee543c60ff3888934877a5671f45494dd27ed4ba25c6670b9a7576b7ed7a8c0" dependencies = [ "color-print-proc-macro", ] [[package]] name = "color-print-proc-macro" -version = "0.3.5" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57e37866456a721d0a404439a1adae37a31be4e0055590d053dfe6981e05003f" +checksum = "77ff1a80c5f3cb1ca7c06ffdd71b6a6dd6d8f896c42141fbd43f50ed28dcdb93" dependencies = [ "nom", "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.74", ] [[package]] name = "colorchoice" -version = "1.0.0" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" +checksum = "d3fd119d74b830634cea2a0f58bbd0d54540518a14397557951e79340abc28c0" [[package]] name = "comfy-table" -version = "7.1.0" +version = "7.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c64043d6c7b7a4c58e39e7efccfdea7b93d885a795d0c054a69dbbf4dd52686" +checksum = "b34115915337defe99b2aff5c2ce6771e5fbc4079f4b506301f5cf394c8452f7" dependencies = [ - "strum 0.25.0", - "strum_macros 0.25.3", + "strum 0.26.3", + "strum_macros 0.26.4", "unicode-width", ] @@ -1614,9 +1611,9 @@ checksum = "2382f75942f4b3be3690fe4f86365e9c853c1587d6ee58212cebf6e2a9ccd101" [[package]] name = "concurrent-queue" -version = "2.4.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d16048cd947b08fa32c24458a22f5dc5e835264f689f4f5653210c69fd107363" +checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973" dependencies = [ "crossbeam-utils", ] @@ -1655,7 +1652,7 @@ version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f9d839f2a20b0aee515dc581a6172f2321f96cab76c1a38a4c584a194955390e" dependencies = [ - "getrandom 0.2.12", + "getrandom 0.2.15", "once_cell", "tiny-keccak", ] @@ -1696,9 +1693,9 @@ dependencies = [ [[package]] name = "core-foundation-sys" -version = "0.8.6" +version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" [[package]] name = "core2" @@ -1730,9 +1727,9 @@ dependencies = [ [[package]] name = "cpufeatures" -version = "0.2.12" +version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" +checksum = "51e852e6dc9a5bed1fae92dd2375037bf2b768725bf3be87811edee3249d09ad" dependencies = [ "libc", ] @@ -1837,9 +1834,9 @@ dependencies = [ [[package]] name = "crc32fast" -version = "1.4.0" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3855a8a784b474f333699ef2bbca9db2c4a1f6d9088a90a2d25b1eb53111eaa" +checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" dependencies = [ "cfg-if", ] @@ -1874,9 +1871,9 @@ dependencies = [ [[package]] name = "crossbeam-utils" -version = "0.8.19" +version = "0.8.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345" +checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" [[package]] name = "crunchy" @@ -1892,7 +1889,7 @@ checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" dependencies = [ "generic-array 0.14.7", "rand_core 0.6.4", - "subtle 2.5.0", + "subtle 2.4.1", "zeroize", ] @@ -1924,17 +1921,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b584a330336237c1eecd3e94266efb216c56ed91225d634cb2991c5f3fd1aeab" dependencies = [ "generic-array 0.14.7", - "subtle 2.5.0", + "subtle 2.4.1", ] [[package]] name = "crypto-mac" -version = "0.11.0" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25fab6889090c8133f3deb8f73ba3c65a7f456f66436fc012a1b1e272b1e103e" +checksum = "b1d1a86f49236c215f271d40892d5fc950490551400b02ef360692c29815c714" dependencies = [ "generic-array 0.14.7", - "subtle 2.5.0", + "subtle 2.4.1", ] [[package]] @@ -1975,7 +1972,7 @@ dependencies = [ "cumulus-primitives-core", "futures", "parity-scale-codec", - "parking_lot 0.12.1", + "parking_lot 0.12.3", "polkadot-node-primitives", "polkadot-node-subsystem", "polkadot-overseer", @@ -2088,7 +2085,7 @@ dependencies = [ "futures", "futures-timer", "parity-scale-codec", - "parking_lot 0.12.1", + "parking_lot 0.12.3", "polkadot-node-primitives", "polkadot-parachain-primitives", "polkadot-primitives", @@ -2252,7 +2249,7 @@ dependencies = [ "proc-macro-crate 3.1.0", "proc-macro2", "quote", - "syn 2.0.55", + "syn 2.0.74", ] [[package]] @@ -2444,13 +2441,13 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4c7718fe298d567adc44fae3dd7024418d6eff08264041e4b0544d1892861cd6" dependencies = [ - "array-bytes 6.2.2", + "array-bytes 6.2.3", "async-trait", "cumulus-primitives-core", "cumulus-relay-chain-interface", "cumulus-relay-chain-rpc-interface", "futures", - "parking_lot 0.12.1", + "parking_lot 0.12.3", "polkadot-availability-recovery", "polkadot-collator-protocol", "polkadot-core-primitives", @@ -2544,24 +2541,23 @@ dependencies = [ "byteorder", "digest 0.9.0", "rand_core 0.5.1", - "subtle 2.5.0", + "subtle 2.4.1", "zeroize", ] [[package]] name = "curve25519-dalek" -version = "4.1.2" +version = "4.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a677b8922c94e01bdbb12126b0bc852f00447528dee1782229af9c720c3f348" +checksum = "97fb8b7c4503de7d6ae7b42ab72a5a59857b4c937ec27a3d4539dba95b5ab2be" dependencies = [ "cfg-if", "cpufeatures", "curve25519-dalek-derive", "digest 0.10.7", "fiat-crypto", - "platforms", "rustc_version", - "subtle 2.5.0", + "subtle 2.4.1", "zeroize", ] @@ -2573,7 +2569,7 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.55", + "syn 2.0.74", ] [[package]] @@ -2591,9 +2587,9 @@ dependencies = [ [[package]] name = "cxx" -version = "1.0.120" +version = "1.0.124" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff4dc7287237dd438b926a81a1a5605dad33d286870e5eee2db17bf2bcd9e92a" +checksum = "273dcfd3acd4e1e276af13ed2a43eea7001318823e7a726a6b3ed39b4acc0b82" dependencies = [ "cc", "cxxbridge-flags", @@ -2603,9 +2599,9 @@ dependencies = [ [[package]] name = "cxx-build" -version = "1.0.120" +version = "1.0.124" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f47c6c8ad7c1a10d3ef0fe3ff6733f4db0d78f08ef0b13121543163ef327058b" +checksum = "d8b2766fbd92be34e9ed143898fce6c572dc009de39506ed6903e5a05b68914e" dependencies = [ "cc", "codespan-reporting", @@ -2613,37 +2609,37 @@ dependencies = [ "proc-macro2", "quote", "scratch", - "syn 2.0.55", + "syn 2.0.74", ] [[package]] name = "cxxbridge-flags" -version = "1.0.120" +version = "1.0.124" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "701a1ac7a697e249cdd8dc026d7a7dafbfd0dbcd8bd24ec55889f2bc13dd6287" +checksum = "839fcd5e43464614ffaa989eaf1c139ef1f0c51672a1ed08023307fa1b909ccd" [[package]] name = "cxxbridge-macro" -version = "1.0.120" +version = "1.0.124" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b404f596046b0bb2d903a9c786b875a126261b52b7c3a64bbb66382c41c771df" +checksum = "4b2c1c1776b986979be68bb2285da855f8d8a35851a769fca8740df7c3d07877" dependencies = [ "proc-macro2", "quote", - "syn 2.0.55", + "syn 2.0.74", ] [[package]] name = "data-encoding" -version = "2.5.0" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e962a19be5cfc3f3bf6dd8f61eb50107f356ad6270fbb3ed41476571db78be5" +checksum = "e8566979429cf69b49a5c740c60791108e86440e8be149bbea4fe54d2c32d6e2" [[package]] name = "data-encoding-macro" -version = "0.1.14" +version = "0.1.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20c01c06f5f429efdf2bae21eb67c28b3df3cf85b7dd2d8ef09c0838dac5d33e" +checksum = "f1559b6cba622276d6d63706db152618eeb15b89b3e4041446b05876e352e639" dependencies = [ "data-encoding", "data-encoding-macro-internal", @@ -2651,9 +2647,9 @@ dependencies = [ [[package]] name = "data-encoding-macro-internal" -version = "0.1.12" +version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0047d07f2c89b17dd631c80450d69841a6b5d7fb17278cbc43d7e4cfcf2576f3" +checksum = "332d754c0af53bc87c108fed664d121ecf59207ec4196041f04d6ab9002ad33f" dependencies = [ "data-encoding", "syn 1.0.109", @@ -2661,9 +2657,9 @@ dependencies = [ [[package]] name = "der" -version = "0.7.8" +version = "0.7.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fffa369a668c8af7dbf8b5e56c9f744fbd399949ed171606040001947de40b1c" +checksum = "f55bf8e7b65898637379c1b74eb1551107c8294ed26d855ceb9fd1a09cfc9bc0" dependencies = [ "const-oid", "zeroize", @@ -2722,20 +2718,20 @@ checksum = "d65d7ce8132b7c0e54497a4d9a55a1c2a0912a0d786cf894472ba818fba45762" dependencies = [ "proc-macro2", "quote", - "syn 2.0.55", + "syn 2.0.74", ] [[package]] name = "derive_more" -version = "0.99.17" +version = "0.99.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" +checksum = "5f33878137e4dafd7fa914ad4e259e18a4e8e532b9617a2d0150262bf53abfce" dependencies = [ "convert_case", "proc-macro2", "quote", "rustc_version", - "syn 1.0.109", + "syn 2.0.74", ] [[package]] @@ -2771,7 +2767,7 @@ dependencies = [ "block-buffer 0.10.4", "const-oid", "crypto-common", - "subtle 2.5.0", + "subtle 2.4.1", ] [[package]] @@ -2818,13 +2814,13 @@ dependencies = [ [[package]] name = "displaydoc" -version = "0.2.4" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "487585f4d0c6655fe74905e2504d8ad6908e4db67f744eb140876906c2f3175d" +checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.55", + "syn 2.0.74", ] [[package]] @@ -2848,9 +2844,9 @@ dependencies = [ "proc-macro2", "quote", "regex", - "syn 2.0.55", + "syn 2.0.74", "termcolor", - "toml 0.8.12", + "toml 0.8.19", "walkdir", ] @@ -2862,9 +2858,9 @@ checksum = "1435fa1053d8b2fbbe9be7e97eca7f33d37b28409959813daefc1446a14247f1" [[package]] name = "downcast-rs" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ea835d29036a4087793836fa931b08837ad5e957da9e23886b29586fb9b6650" +checksum = "75b325c5dbd37f80359721ad39aca5a29fb04c89279657cffdda8736d0c0b9d2" [[package]] name = "dtoa" @@ -2929,12 +2925,12 @@ version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4a3daa8e81a3963a60642bcc1f90a670680bd4a77535faa384e9d1c79d620871" dependencies = [ - "curve25519-dalek 4.1.2", + "curve25519-dalek 4.1.3", "ed25519", "rand_core 0.6.4", "serde", "sha2 0.10.8", - "subtle 2.5.0", + "subtle 2.4.1", "zeroize", ] @@ -2958,9 +2954,9 @@ version = "4.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7d9ce6874da5d4415896cd45ffbc4d1cfc0c4f9c079427bd870742c30f2f65a9" dependencies = [ - "curve25519-dalek 4.1.2", + "curve25519-dalek 4.1.3", "ed25519", - "hashbrown 0.14.3", + "hashbrown 0.14.5", "hex", "rand_core 0.6.4", "sha2 0.10.8", @@ -2969,9 +2965,9 @@ dependencies = [ [[package]] name = "either" -version = "1.10.0" +version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11157ac094ffbdde99aa67b23417ebdd801842852b500e395a45a9c0aac03e4a" +checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" [[package]] name = "elliptic-curve" @@ -2988,7 +2984,7 @@ dependencies = [ "pkcs8", "rand_core 0.6.4", "sec1", - "subtle 2.5.0", + "subtle 2.4.1", "zeroize", ] @@ -3045,40 +3041,40 @@ dependencies = [ [[package]] name = "enumflags2" -version = "0.7.9" +version = "0.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3278c9d5fb675e0a51dabcf4c0d355f692b064171535ba72361be1528a9d8e8d" +checksum = "d232db7f5956f3f14313dc2f87985c58bd2c695ce124c8cdd984e08e15ac133d" dependencies = [ "enumflags2_derive", ] [[package]] name = "enumflags2_derive" -version = "0.7.9" +version = "0.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c785274071b1b420972453b306eeca06acf4633829db4223b58a2a8c5953bc4" +checksum = "de0d48a183585823424a4ce1aa132d174a6a81bd540895822eb4c8373a8e49e8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.55", + "syn 2.0.74", ] [[package]] name = "enumn" -version = "0.1.13" +version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fd000fd6988e73bbe993ea3db9b1aa64906ab88766d654973924340c8cddb42" +checksum = "2f9ed6b3789237c8a0c1c505af1c7eb2c560df6186f01b098c3a1064ea532f38" dependencies = [ "proc-macro2", "quote", - "syn 2.0.55", + "syn 2.0.74", ] [[package]] name = "env_filter" -version = "0.1.0" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a009aa4810eb158359dda09d0c87378e4bbb89b5a801f016885a4707ba24f7ea" +checksum = "4f2c92ceda6ceec50f43169f9ee8424fe2db276791afde7b2cd8bc084cb376ab" dependencies = [ "log", "regex", @@ -3099,9 +3095,9 @@ dependencies = [ [[package]] name = "env_logger" -version = "0.11.3" +version = "0.11.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38b35839ba51819680ba087cd351788c9a3c476841207e0b8cee0b04722343b9" +checksum = "e13fa619b91fb2381732789fc5de83b45675e882f66623b7d8cb4f643017018d" dependencies = [ "anstream", "anstyle", @@ -3124,9 +3120,9 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "errno" -version = "0.3.8" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" +checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" dependencies = [ "libc", "windows-sys 0.52.0", @@ -3187,49 +3183,28 @@ checksum = "d93877bcde0eb80ca09131a08d23f0a5c18a620b01db137dba666d18cd9b30c2" dependencies = [ "concurrent-queue", "parking", - "pin-project-lite 0.2.13", + "pin-project-lite 0.2.14", ] [[package]] name = "event-listener" -version = "4.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67b215c49b2b248c855fb73579eb1f4f26c38ffdc12973e20e07b91d78d5646e" -dependencies = [ - "concurrent-queue", - "parking", - "pin-project-lite 0.2.13", -] - -[[package]] -name = "event-listener" -version = "5.2.0" +version = "5.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b5fb89194fa3cad959b833185b3063ba881dbfc7030680b314250779fb4cc91" +checksum = "6032be9bd27023a771701cc49f9f053c751055f71efb2e0ae5c15809093675ba" dependencies = [ "concurrent-queue", "parking", - "pin-project-lite 0.2.13", -] - -[[package]] -name = "event-listener-strategy" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "958e4d70b6d5e81971bebec42271ec641e7ff4e170a6fa605f2b8a8b65cb97d3" -dependencies = [ - "event-listener 4.0.3", - "pin-project-lite 0.2.13", + "pin-project-lite 0.2.14", ] [[package]] name = "event-listener-strategy" -version = "0.5.0" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "feedafcaa9b749175d5ac357452a9d41ea2911da598fde46ce1fe02c37751291" +checksum = "0f214dc438f977e6d4e3500aaa277f5ad94ca83fbbd9b1a15713ce2344ccc5a1" dependencies = [ - "event-listener 5.2.0", - "pin-project-lite 0.2.13", + "event-listener 5.3.1", + "pin-project-lite 0.2.14", ] [[package]] @@ -3255,16 +3230,17 @@ dependencies = [ [[package]] name = "expander" -version = "2.1.0" +version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00e83c02035136f1592a47964ea60c05a50e4ed8b5892cfac197063850898d4d" +checksum = "e2c470c71d91ecbd179935b24170459e926382eaaa86b590b78814e180d8a8e2" dependencies = [ "blake2 0.10.6", + "file-guard", "fs-err", - "prettier-please", + "prettyplease 0.2.20", "proc-macro2", "quote", - "syn 2.0.55", + "syn 2.0.74", ] [[package]] @@ -3284,9 +3260,9 @@ dependencies = [ [[package]] name = "fastrand" -version = "2.0.2" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "658bd65b1cf4c852a3cc96f18a8ce7b5640f6b703f905c7d74532294c2a63984" +checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a" [[package]] name = "fatality" @@ -3306,7 +3282,7 @@ checksum = "f5aa1e3ae159e592ad222dc90c5acbad632b527779ba88486abe92782ab268bd" dependencies = [ "expander 0.0.4", "indexmap 1.9.3", - "proc-macro-crate 1.3.1", + "proc-macro-crate 1.1.3", "proc-macro2", "quote", "syn 1.0.109", @@ -3330,14 +3306,24 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" dependencies = [ "rand_core 0.6.4", - "subtle 2.5.0", + "subtle 2.4.1", ] [[package]] name = "fiat-crypto" -version = "0.2.7" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c007b1ae3abe1cb6f85a16305acd418b7ca6343b953633fee2b76d8f108b830f" +checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d" + +[[package]] +name = "file-guard" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21ef72acf95ec3d7dbf61275be556299490a245f017cf084bd23b4f68cf9407c" +dependencies = [ + "libc", + "winapi", +] [[package]] name = "file-per-thread-logger" @@ -3351,14 +3337,14 @@ dependencies = [ [[package]] name = "filetime" -version = "0.2.23" +version = "0.2.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ee447700ac8aa0b2f2bd7bc4462ad686ba06baa6727ac149a2d6277f0d240fd" +checksum = "bf401df4a4e3872c4fe8151134cf483738e74b67fc934d6532c882b3d24a4550" dependencies = [ "cfg-if", "libc", - "redox_syscall 0.4.1", - "windows-sys 0.52.0", + "libredox", + "windows-sys 0.59.0", ] [[package]] @@ -3373,7 +3359,7 @@ dependencies = [ "log", "num-traits", "parity-scale-codec", - "parking_lot 0.12.1", + "parking_lot 0.12.3", "scale-info", ] @@ -3397,9 +3383,9 @@ checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" [[package]] name = "flate2" -version = "1.0.28" +version = "1.0.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46303f565772937ffe1d394a4fac6f411c6013172fadde9dcdb1e147a086940e" +checksum = "7f211bbe8e69bbd0cfdea405084f128ae8b4aaa6b0b522fc8f2b009084797920" dependencies = [ "crc32fast", "libz-sys", @@ -3478,7 +3464,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "efe02c96362e3c7308cdea7545859f767194a1f3f00928f0e1357f4b8a0b3b2c" dependencies = [ "Inflector", - "array-bytes 6.2.2", + "array-bytes 6.2.3", "chrono", "clap", "comfy-table", @@ -3529,7 +3515,7 @@ dependencies = [ "proc-macro-crate 3.1.0", "proc-macro2", "quote", - "syn 2.0.55", + "syn 2.0.74", ] [[package]] @@ -3587,7 +3573,7 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5bb1eec9eb46d3e016c95b2fa875118c04609f2150013c56a894cae00581e265" dependencies = [ - "array-bytes 6.2.2", + "array-bytes 6.2.3", "docify", "frame-support", "frame-system", @@ -3627,7 +3613,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b8e52c84b611d2049d9253f83a62ab0f093e4be5c42a7ef42ea5bb16d6611e32" dependencies = [ "aquamarine", - "array-bytes 6.2.2", + "array-bytes 6.2.3", "bitflags 1.3.2", "docify", "environmental", @@ -3671,7 +3657,7 @@ dependencies = [ "Inflector", "cfg-expr", "derive-syn-parse 0.1.5", - "expander 2.1.0", + "expander 2.2.1", "frame-support-procedural-tools", "itertools 0.10.5", "macro_magic", @@ -3679,7 +3665,7 @@ dependencies = [ "proc-macro2", "quote", "sp-crypto-hashing", - "syn 2.0.55", + "syn 2.0.74", ] [[package]] @@ -3692,7 +3678,7 @@ dependencies = [ "proc-macro-crate 3.1.0", "proc-macro2", "quote", - "syn 2.0.55", + "syn 2.0.74", ] [[package]] @@ -3703,7 +3689,7 @@ checksum = "68672b9ec6fe72d259d3879dc212c5e42e977588cdac830c76f54d9f492aeb58" dependencies = [ "proc-macro2", "quote", - "syn 2.0.55", + "syn 2.0.74", ] [[package]] @@ -3791,7 +3777,7 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "29f9df8a11882c4e3335eb2d18a0137c505d9ca927470b0cac9c6f0ae07d28f7" dependencies = [ - "rustix 0.38.32", + "rustix 0.38.34", "windows-sys 0.48.0", ] @@ -3861,7 +3847,7 @@ dependencies = [ "futures-io", "memchr", "parking", - "pin-project-lite 0.2.13", + "pin-project-lite 0.2.14", "waker-fn", ] @@ -3871,11 +3857,11 @@ version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "52527eb5074e35e9339c6b4e8d12600c7128b68fb25dcb9fa9dec18f7c25f3a5" dependencies = [ - "fastrand 2.0.2", + "fastrand 2.1.0", "futures-core", "futures-io", "parking", - "pin-project-lite 0.2.13", + "pin-project-lite 0.2.14", ] [[package]] @@ -3886,7 +3872,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn 2.0.55", + "syn 2.0.74", ] [[package]] @@ -3931,7 +3917,7 @@ dependencies = [ "futures-sink", "futures-task", "memchr", - "pin-project-lite 0.2.13", + "pin-project-lite 0.2.14", "pin-utils", "slab", ] @@ -3988,9 +3974,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.12" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" dependencies = [ "cfg-if", "libc", @@ -4030,9 +4016,9 @@ dependencies = [ [[package]] name = "gimli" -version = "0.28.1" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" +checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd" [[package]] name = "glob" @@ -4048,7 +4034,7 @@ checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" dependencies = [ "ff", "rand_core 0.6.4", - "subtle 2.5.0", + "subtle 2.4.1", ] [[package]] @@ -4063,7 +4049,7 @@ dependencies = [ "futures-sink", "futures-util", "http", - "indexmap 2.2.6", + "indexmap 2.3.0", "slab", "tokio", "tokio-util", @@ -4119,9 +4105,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.14.3" +version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" dependencies = [ "ahash 0.8.11", "allocator-api2", @@ -4134,7 +4120,7 @@ version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e8094feaf31ff591f651a2664fb9cfd92bba7a60ce3197265e9482ebe753c8f7" dependencies = [ - "hashbrown 0.14.3", + "hashbrown 0.14.5", ] [[package]] @@ -4155,6 +4141,12 @@ version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" +[[package]] +name = "hermit-abi" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc" + [[package]] name = "hex" version = "0.4.3" @@ -4192,7 +4184,7 @@ version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2a2a2320eb7ec0ebe8da8f744d7812d9fc4cb4d09344ac01898dbcb6a20ae69b" dependencies = [ - "crypto-mac 0.11.0", + "crypto-mac 0.11.1", "digest 0.9.0", ] @@ -4255,7 +4247,7 @@ checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" dependencies = [ "bytes", "http", - "pin-project-lite 0.2.13", + "pin-project-lite 0.2.14", ] [[package]] @@ -4266,9 +4258,9 @@ checksum = "add0ab9360ddbd88cfeb3bd9574a1d85cfdfa14db10b3e21d3700dbc4328758f" [[package]] name = "httparse" -version = "1.8.0" +version = "1.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" +checksum = "0fcc0b4a115bf80b728eb8ea024ad5bd707b615bfed49e0665b6e0f86fd082d9" [[package]] name = "httpdate" @@ -4284,9 +4276,9 @@ checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" [[package]] name = "hyper" -version = "0.14.28" +version = "0.14.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf96e135eb83a2a8ddf766e426a841d8ddd7449d5f00d34ea02b41d2f19eef80" +checksum = "a152ddd61dfaec7273fe8419ab357f33aee0d914c5f4efbf0d96fa749eea5ec9" dependencies = [ "bytes", "futures-channel", @@ -4298,8 +4290,8 @@ dependencies = [ "httparse", "httpdate", "itoa", - "pin-project-lite 0.2.13", - "socket2 0.5.6", + "pin-project-lite 0.2.14", + "socket2 0.5.7", "tokio", "tower-service", "tracing", @@ -4316,7 +4308,7 @@ dependencies = [ "http", "hyper", "log", - "rustls 0.21.10", + "rustls 0.21.12", "rustls-native-certs", "tokio", "tokio-rustls", @@ -4333,7 +4325,7 @@ dependencies = [ "iana-time-zone-haiku", "js-sys", "wasm-bindgen", - "windows-core", + "windows-core 0.52.0", ] [[package]] @@ -4382,7 +4374,7 @@ version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d6b0422c86d7ce0e97169cc42e04ae643caf278874a7a3c87b8150a220dc7e1e" dependencies = [ - "async-io 2.3.2", + "async-io 2.3.4", "core-foundation", "fnv", "futures", @@ -4446,18 +4438,18 @@ dependencies = [ [[package]] name = "include_dir" -version = "0.7.3" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18762faeff7122e89e0857b02f7ce6fcc0d101d5e9ad2ad7846cc01d61b7f19e" +checksum = "923d117408f1e49d914f1a379a309cffe4f18c05cf4e3d12e613a15fc81bd0dd" dependencies = [ "include_dir_macros", ] [[package]] name = "include_dir_macros" -version = "0.7.3" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b139284b5cf57ecfa712bcc66950bb635b31aff41c188e8a4cfc758eca374a3f" +checksum = "7cab85a7ed0bd5f0e76d93846e0147172bed2e2d3f859bcc33a8d9699cad1a75" dependencies = [ "proc-macro2", "quote", @@ -4476,12 +4468,12 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.2.6" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" +checksum = "de3fc2e30ba82dd1b3911c8de1ffc143c74a914a14e99514d7637e3099df5ea0" dependencies = [ "equivalent", - "hashbrown 0.14.3", + "hashbrown 0.14.5", ] [[package]] @@ -4514,9 +4506,9 @@ dependencies = [ [[package]] name = "instant" -version = "0.1.12" +version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" +checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222" dependencies = [ "cfg-if", ] @@ -4574,7 +4566,7 @@ version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" dependencies = [ - "hermit-abi", + "hermit-abi 0.3.9", "libc", "windows-sys 0.48.0", ] @@ -4591,7 +4583,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b58db92f96b720de98181bbbe63c831e87005ab460c1bf306eb2622b4707997f" dependencies = [ - "socket2 0.5.6", + "socket2 0.5.7", "widestring", "windows-sys 0.48.0", "winreg", @@ -4609,7 +4601,7 @@ version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f23ff5ef2b80d608d61efee834934d862cd92461afc0560dedf493e4c033738b" dependencies = [ - "hermit-abi", + "hermit-abi 0.3.9", "libc", "windows-sys 0.52.0", ] @@ -4623,6 +4615,12 @@ dependencies = [ "winapi", ] +[[package]] +name = "is_terminal_polyfill" +version = "1.70.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" + [[package]] name = "itertools" version = "0.10.5" @@ -4641,26 +4639,35 @@ dependencies = [ "either", ] +[[package]] +name = "itertools" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" +dependencies = [ + "either", +] + [[package]] name = "itoa" -version = "1.0.10" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" +checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" [[package]] name = "jobserver" -version = "0.1.28" +version = "0.1.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab46a6e9526ddef3ae7f787c06f0f2600639ba80ea3eade3d8e670a2230f51d6" +checksum = "48d1dbcbbeb6a7fec7e059840aa538bd62aaccf972c7346c4d9d2059312853d0" dependencies = [ "libc", ] [[package]] name = "js-sys" -version = "0.3.69" +version = "0.3.70" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" +checksum = "1868808506b929d7b0cfa8f75951347aa71bb21144b7791bae35d9bccfcfe37a" dependencies = [ "wasm-bindgen", ] @@ -4715,7 +4722,7 @@ dependencies = [ "futures-util", "hyper", "jsonrpsee-types", - "parking_lot 0.12.1", + "parking_lot 0.12.3", "rand", "rustc-hash", "serde", @@ -4753,7 +4760,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "29110019693a4fa2dbda04876499d098fa16d70eba06b1e6e2b3f1b251419515" dependencies = [ "heck 0.4.1", - "proc-macro-crate 1.3.1", + "proc-macro-crate 1.1.3", "proc-macro2", "quote", "syn 1.0.109", @@ -4853,7 +4860,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bf7a85fe66f9ff9cd74e169fdd2c94c6e1e74c412c99a73b4df3200b5d3760b2" dependencies = [ "kvdb", - "parking_lot 0.12.1", + "parking_lot 0.12.3", ] [[package]] @@ -4864,7 +4871,7 @@ checksum = "b644c70b92285f66bfc2032922a79000ea30af7bc2ab31902992a5dcb9b434f6" dependencies = [ "kvdb", "num_cpus", - "parking_lot 0.12.1", + "parking_lot 0.12.3", "regex", "rocksdb", "smallvec", @@ -4872,9 +4879,9 @@ dependencies = [ [[package]] name = "landlock" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1530c5b973eeed4ac216af7e24baf5737645a6272e361f1fb95710678b67d9cc" +checksum = "9baa9eeb6e315942429397e617a190f4fdc696ef1ee0342939d641029cbb4ea7" dependencies = [ "enumflags2", "libc", @@ -4883,9 +4890,9 @@ dependencies = [ [[package]] name = "lazy_static" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" [[package]] name = "lazycell" @@ -4895,18 +4902,18 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" [[package]] name = "libc" -version = "0.2.153" +version = "0.2.155" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" +checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" [[package]] name = "libloading" -version = "0.8.3" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c2a198fb6b0eada2a8df47933734e6d35d350665a33a3593d7164fa52c75c19" +checksum = "4979f22fdb869068da03c9f7528f8297c6fd2606bc3a4affe42e6a823fdb8da4" dependencies = [ "cfg-if", - "windows-targets 0.52.4", + "windows-targets 0.52.6", ] [[package]] @@ -4924,7 +4931,7 @@ dependencies = [ "bytes", "futures", "futures-timer", - "getrandom 0.2.12", + "getrandom 0.2.15", "instant", "libp2p-allow-block-list", "libp2p-connection-limits", @@ -4989,7 +4996,7 @@ dependencies = [ "multihash 0.17.0", "multistream-select", "once_cell", - "parking_lot 0.12.1", + "parking_lot 0.12.3", "pin-project", "quick-protobuf", "rand", @@ -5009,7 +5016,7 @@ dependencies = [ "futures", "libp2p-core", "log", - "parking_lot 0.12.1", + "parking_lot 0.12.3", "smallvec", "trust-dns-resolver", ] @@ -5171,7 +5178,7 @@ dependencies = [ "libp2p-identity", "libp2p-tls", "log", - "parking_lot 0.12.1", + "parking_lot 0.12.3", "quinn-proto", "rand", "rustls 0.20.9", @@ -5287,7 +5294,7 @@ dependencies = [ "futures-rustls", "libp2p-core", "log", - "parking_lot 0.12.1", + "parking_lot 0.12.3", "quicksink", "rw-stream-sink", "soketto", @@ -5310,13 +5317,13 @@ dependencies = [ [[package]] name = "libredox" -version = "0.0.1" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85c833ca1e66078851dba29046874e38f08b2c883700aa29a03ddd3b23814ee8" +checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "libc", - "redox_syscall 0.4.1", + "redox_syscall 0.5.3", ] [[package]] @@ -5361,7 +5368,7 @@ checksum = "5be9b9bb642d8522a44d533eab56c16c738301965504753b03ad1de3425d5451" dependencies = [ "crunchy", "digest 0.9.0", - "subtle 2.5.0", + "subtle 2.4.1", ] [[package]] @@ -5384,9 +5391,9 @@ dependencies = [ [[package]] name = "libz-sys" -version = "1.1.16" +version = "1.1.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e143b5e666b2695d28f6bca6497720813f699c9602dd7f5cac91008b8ada7f9" +checksum = "fdc53a7799a7496ebc9fd29f31f7df80e83c9bda5299768af5f9e59eeea74647" dependencies = [ "cc", "pkg-config", @@ -5440,9 +5447,9 @@ checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" [[package]] name = "linux-raw-sys" -version = "0.4.13" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" +checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" [[package]] name = "lioness" @@ -5458,9 +5465,9 @@ dependencies = [ [[package]] name = "lock_api" -version = "0.4.11" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" +checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" dependencies = [ "autocfg", "scopeguard", @@ -5468,9 +5475,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.21" +version = "0.4.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" +checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" [[package]] name = "lru" @@ -5507,9 +5514,9 @@ dependencies = [ [[package]] name = "lz4" -version = "1.24.0" +version = "1.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e9e2dd86df36ce760a60f6ff6ad526f7ba1f14ba0356f8254fb6905e6494df1" +checksum = "958b4caa893816eea05507c20cfe47574a43d9a697138a7872990bba8a0ece68" dependencies = [ "libc", "lz4-sys", @@ -5517,9 +5524,9 @@ dependencies = [ [[package]] name = "lz4-sys" -version = "1.9.4" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57d27b317e207b10f69f5e75494119e391a96f48861ae870d1da6edac98ca900" +checksum = "109de74d5d2353660401699a4174a4ff23fcc649caf553df71933c7fb45ad868" dependencies = [ "cc", "libc", @@ -5536,50 +5543,50 @@ dependencies = [ [[package]] name = "macro_magic" -version = "0.5.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e03844fc635e92f3a0067e25fa4bf3e3dbf3f2927bf3aa01bb7bc8f1c428949d" +checksum = "cc33f9f0351468d26fbc53d9ce00a096c8522ecb42f19b50f34f2c422f76d21d" dependencies = [ "macro_magic_core", "macro_magic_macros", "quote", - "syn 2.0.55", + "syn 2.0.74", ] [[package]] name = "macro_magic_core" -version = "0.5.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "468155613a44cfd825f1fb0ffa532b018253920d404e6fca1e8d43155198a46d" +checksum = "1687dc887e42f352865a393acae7cf79d98fab6351cde1f58e9e057da89bf150" dependencies = [ "const-random", - "derive-syn-parse 0.1.5", + "derive-syn-parse 0.2.0", "macro_magic_core_macros", "proc-macro2", "quote", - "syn 2.0.55", + "syn 2.0.74", ] [[package]] name = "macro_magic_core_macros" -version = "0.5.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ea73aa640dc01d62a590d48c0c3521ed739d53b27f919b25c3551e233481654" +checksum = "b02abfe41815b5bd98dbd4260173db2c116dda171dc0fe7838cb206333b83308" dependencies = [ "proc-macro2", "quote", - "syn 2.0.55", + "syn 2.0.74", ] [[package]] name = "macro_magic_macros" -version = "0.5.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef9d79ae96aaba821963320eb2b6e34d17df1e5a83d8a1985c29cc5be59577b3" +checksum = "73ea28ee64b88876bf45277ed9a5817c1817df061a74f2b988971a12570e5869" dependencies = [ "macro_magic_core", "quote", - "syn 2.0.55", + "syn 2.0.74", ] [[package]] @@ -5620,9 +5627,9 @@ checksum = "2532096657941c2fea9c289d370a250971c689d4f143798ff67113ec042024a5" [[package]] name = "matrixmultiply" -version = "0.3.8" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7574c1cf36da4798ab73da5b215bbf444f50718207754cb522201d78d1cd0ff2" +checksum = "9380b911e3e96d10c1f415da0876389aaf1b56759054eeb0de7df940c456ba1a" dependencies = [ "autocfg", "rawpointer", @@ -5630,9 +5637,9 @@ dependencies = [ [[package]] name = "memchr" -version = "2.7.1" +version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" [[package]] name = "memfd" @@ -5640,7 +5647,7 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b2cffa4ad52c6f791f4f8b15f0c05f9824b2ced1160e88cc393d64fff9a8ac64" dependencies = [ - "rustix 0.38.32", + "rustix 0.38.34", ] [[package]] @@ -5710,22 +5717,23 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] name = "miniz_oxide" -version = "0.7.2" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d811f3e15f28568be3407c8e7fdb6514c1cda3cb30683f15b6a1a1dc4ea14a7" +checksum = "b8a240ddb74feaf34a79a7add65a741f3167852fba007066dcac1ca548d89c08" dependencies = [ "adler", ] [[package]] name = "mio" -version = "0.8.11" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" +checksum = "80e04d1dcff3aae0704555fe5fee3bcfaf3d1fdf8a7e521d5b9d2b42acb52cec" dependencies = [ + "hermit-abi 0.3.9", "libc", "wasi 0.11.0+wasi-snapshot-preview1", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -5739,16 +5747,16 @@ dependencies = [ "bitflags 1.3.2", "blake2 0.10.6", "c2-chacha", - "curve25519-dalek 4.1.2", + "curve25519-dalek 4.1.3", "either", "hashlink", "lioness", "log", - "parking_lot 0.12.1", + "parking_lot 0.12.3", "rand", "rand_chacha 0.3.1", "rand_distr", - "subtle 2.5.0", + "subtle 2.4.1", "thiserror", "zeroize", ] @@ -5857,7 +5865,7 @@ dependencies = [ "blake3", "core2", "digest 0.10.7", - "multihash-derive 0.8.0", + "multihash-derive 0.8.1", "sha2 0.10.8", "sha3", "unsigned-varint", @@ -5871,7 +5879,7 @@ checksum = "cfd8a792c1694c6da4f68db0a9d707c72bd260994da179e6030a5dcee00bb815" dependencies = [ "core2", "digest 0.10.7", - "multihash-derive 0.8.0", + "multihash-derive 0.8.1", "sha2 0.10.8", "unsigned-varint", ] @@ -5908,16 +5916,16 @@ dependencies = [ [[package]] name = "multihash-derive" -version = "0.8.0" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc076939022111618a5026d3be019fd8b366e76314538ff9a1b59ffbcbf98bcd" +checksum = "1d6d4752e6230d8ef7adf7bd5d8c4b1f6561c1014c5ba9a37445ccefe18aa1db" dependencies = [ - "proc-macro-crate 1.3.1", + "proc-macro-crate 1.1.3", "proc-macro-error", "proc-macro2", "quote", "syn 1.0.109", - "synstructure", + "synstructure 0.12.6", ] [[package]] @@ -5933,16 +5941,16 @@ dependencies = [ [[package]] name = "multihash-derive-impl" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d38685e08adb338659871ecfc6ee47ba9b22dcc8abcf6975d379cc49145c3040" +checksum = "3958713ce794e12f7c6326fac9aa274c68d74c4881dd37b3e2662b8a2046bb19" dependencies = [ - "proc-macro-crate 1.3.1", + "proc-macro-crate 2.0.0", "proc-macro-error", "proc-macro2", "quote", - "syn 1.0.109", - "synstructure", + "syn 2.0.74", + "synstructure 0.13.1", ] [[package]] @@ -5967,9 +5975,9 @@ dependencies = [ [[package]] name = "nalgebra" -version = "0.32.4" +version = "0.32.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4541eb06dce09c0241ebbaab7102f0a01a0c8994afed2e5d0d66775016e25ac2" +checksum = "7b5c17de023a86f59ed79891b2e5d5a94c705dbe904a5b5c9c952ea6221b03e4" dependencies = [ "approx", "matrixmultiply", @@ -5983,13 +5991,13 @@ dependencies = [ [[package]] name = "nalgebra-macros" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91761aed67d03ad966ef783ae962ef9bbaca728d2dd7ceb7939ec110fffad998" +checksum = "254a5372af8fc138e36684761d3c0cdb758a4410e938babcff1c860ce14ddbfc" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.74", ] [[package]] @@ -6062,9 +6070,9 @@ dependencies = [ [[package]] name = "netlink-sys" -version = "0.8.5" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6471bf08e7ac0135876a9581bf3217ef0333c191c128d34878079f42ee150411" +checksum = "416060d346fbaf1f23f9512963e3e878f1a78e707cb699ba9215761754244307" dependencies = [ "bytes", "futures", @@ -6090,7 +6098,7 @@ version = "0.27.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2eb04e9c688eff1c89d72b407f168cf79bb9e867a9d3323ed6c01519eb9cc053" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "cfg-if", "libc", ] @@ -6131,20 +6139,19 @@ checksum = "61807f77802ff30975e01f4f071c8ba10c022052f98b3294119f3e615d13e5be" [[package]] name = "num-bigint" -version = "0.4.4" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "608e7659b5c3d7cba262d894801b9ec9d00de989e8a82bd4bef91d08da45cdc0" +checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" dependencies = [ - "autocfg", "num-integer", "num-traits", ] [[package]] name = "num-complex" -version = "0.4.5" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23c6602fda94a57c990fe0df199a035d83576b496aa29f4e634a8ac6004e68a6" +checksum = "73f88a1307638156682bada9d7604135552957b7818057dcef22705b4d509495" dependencies = [ "num-traits", ] @@ -6176,11 +6183,10 @@ dependencies = [ [[package]] name = "num-rational" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0638a1c9d0a3c0914158145bc76cff373a75a627e6ecbfb71cbe6f453a5a19b0" +checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824" dependencies = [ - "autocfg", "num-bigint", "num-integer", "num-traits", @@ -6188,9 +6194,9 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.18" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", "libm", @@ -6202,7 +6208,7 @@ version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" dependencies = [ - "hermit-abi", + "hermit-abi 0.3.9", "libc", ] @@ -6226,9 +6232,9 @@ dependencies = [ [[package]] name = "object" -version = "0.32.2" +version = "0.36.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" +checksum = "27b64972346851a39438c60b341ebc01bba47464ae329e55cf343eb93964efd9" dependencies = [ "memchr", ] @@ -6274,9 +6280,9 @@ checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" [[package]] name = "orchestra" -version = "0.3.5" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2356622ffdfe72362a45a1e5e87bb113b8327e596e39b91f11f0ef4395c8da79" +checksum = "92829eef0328a3d1cd22a02c0e51deb92a5362df3e7d21a4e9bdc38934694e66" dependencies = [ "async-trait", "dyn-clonable", @@ -6291,15 +6297,15 @@ dependencies = [ [[package]] name = "orchestra-proc-macro" -version = "0.3.5" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eedb646674596266dc9bb2b5c7eea7c36b32ecc7777eba0d510196972d72c4fd" +checksum = "1344346d5af32c95bbddea91b18a88cc83eac394192d20ef2fc4c40a74332355" dependencies = [ - "expander 2.1.0", - "indexmap 2.2.6", + "expander 2.2.1", + "indexmap 2.3.0", "itertools 0.11.0", "petgraph", - "proc-macro-crate 1.3.1", + "proc-macro-crate 3.1.0", "proc-macro2", "quote", "syn 1.0.109", @@ -6560,7 +6566,7 @@ version = "29.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7d334f24d3c0c016d16aa87d069485847d622e8ebebace18ec5cf56609ca3a67" dependencies = [ - "array-bytes 6.2.2", + "array-bytes 6.2.3", "binary-merkle-tree", "frame-support", "frame-system", @@ -6802,7 +6808,7 @@ checksum = "3163c6bc21b55a0ccb74c546ba784d9c9e69beb9240c059d28a3052f4cbce509" dependencies = [ "proc-macro2", "quote", - "syn 2.0.55", + "syn 2.0.74", ] [[package]] @@ -7470,7 +7476,7 @@ dependencies = [ "proc-macro-crate 3.1.0", "proc-macro2", "quote", - "syn 2.0.55", + "syn 2.0.74", ] [[package]] @@ -7849,7 +7855,7 @@ dependencies = [ "log", "lz4", "memmap2 0.5.10", - "parking_lot 0.12.1", + "parking_lot 0.12.3", "rand", "siphasher", "snap", @@ -7901,7 +7907,7 @@ dependencies = [ "impl-trait-for-tuples", "lru 0.8.1", "parity-util-mem-derive", - "parking_lot 0.12.1", + "parking_lot 0.12.3", "primitive-types", "smallvec", "winapi", @@ -7915,7 +7921,7 @@ checksum = "f557c32c6d268a07c921471619c0295f5efad3a0e76d4f97a05c091a51d110b2" dependencies = [ "proc-macro2", "syn 1.0.109", - "synstructure", + "synstructure 0.12.6", ] [[package]] @@ -7943,12 +7949,12 @@ dependencies = [ [[package]] name = "parking_lot" -version = "0.12.1" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" +checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" dependencies = [ "lock_api", - "parking_lot_core 0.9.9", + "parking_lot_core 0.9.10", ] [[package]] @@ -7967,15 +7973,15 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.9" +version = "0.9.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" +checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" dependencies = [ "cfg-if", "libc", - "redox_syscall 0.4.1", + "redox_syscall 0.5.3", "smallvec", - "windows-targets 0.48.5", + "windows-targets 0.52.6", ] [[package]] @@ -7987,7 +7993,7 @@ checksum = "7924d1d0ad836f665c9065e26d016c673ece3993f30d340068b16f282afc1156" [[package]] name = "paseo-runtime" version = "1.2.5" -source = "git+https://github.com/paseo-network/runtimes/?tag=v1.2.5-system-chains#e7265b10b28d8b82c3146e72c98895dac2b55729" +source = "git+https://github.com/paseo-network/runtimes/?tag=v1.2.5-system-chains#2fa66a19eef96bd2c079385057fab2564d09b751" dependencies = [ "binary-merkle-tree", "frame-benchmarking", @@ -8082,7 +8088,7 @@ dependencies = [ [[package]] name = "paseo-runtime-constants" version = "1.0.0" -source = "git+https://github.com/paseo-network/runtimes/?tag=v1.2.5-system-chains#e7265b10b28d8b82c3146e72c98895dac2b55729" +source = "git+https://github.com/paseo-network/runtimes/?tag=v1.2.5-system-chains#2fa66a19eef96bd2c079385057fab2564d09b751" dependencies = [ "frame-support", "polkadot-primitives", @@ -8096,9 +8102,9 @@ dependencies = [ [[package]] name = "paste" -version = "1.0.14" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" [[package]] name = "pbkdf2" @@ -8106,7 +8112,7 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d95f5254224e617595d2cc3cc73ff0a5eaf2637519e25f03388154e9378b6ffa" dependencies = [ - "crypto-mac 0.11.0", + "crypto-mac 0.11.1", ] [[package]] @@ -8141,9 +8147,9 @@ checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "pest" -version = "2.7.8" +version = "2.7.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56f8023d0fb78c8e03784ea1c7f3fa36e68a723138990b8d5a47d916b651e7a8" +checksum = "cd53dff83f26735fdc1ca837098ccf133605d794cdae66acfc2bfac3ec809d95" dependencies = [ "memchr", "thiserror", @@ -8152,9 +8158,9 @@ dependencies = [ [[package]] name = "pest_derive" -version = "2.7.8" +version = "2.7.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0d24f72393fd16ab6ac5738bc33cdb6a9aa73f8b902e8fe29cf4e67d7dd1026" +checksum = "2a548d2beca6773b1c244554d36fcf8548a8a58e74156968211567250e48e49a" dependencies = [ "pest", "pest_generator", @@ -8162,22 +8168,22 @@ dependencies = [ [[package]] name = "pest_generator" -version = "2.7.8" +version = "2.7.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdc17e2a6c7d0a492f0158d7a4bd66cc17280308bbaff78d5bef566dca35ab80" +checksum = "3c93a82e8d145725dcbaf44e5ea887c8a869efdcc28706df2d08c69e17077183" dependencies = [ "pest", "pest_meta", "proc-macro2", "quote", - "syn 2.0.55", + "syn 2.0.74", ] [[package]] name = "pest_meta" -version = "2.7.8" +version = "2.7.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "934cd7631c050f4674352a6e835d5f6711ffbfb9345c2fc0107155ac495ae293" +checksum = "a941429fea7e08bedec25e4f6785b6ffaacc6b755da98df5ef3e7dcf4a124c4f" dependencies = [ "once_cell", "pest", @@ -8186,12 +8192,12 @@ dependencies = [ [[package]] name = "petgraph" -version = "0.6.4" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1d3afd2628e69da2be385eb6f2fd57c8ac7977ceeff6dc166ff1657b0e386a9" +checksum = "b4c5cc86750666a3ed20bdaf5ca2a0344f9c67674cae0515bec2da16fbaa47db" dependencies = [ "fixedbitset", - "indexmap 2.2.6", + "indexmap 2.3.0", ] [[package]] @@ -8211,7 +8217,7 @@ checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" dependencies = [ "proc-macro2", "quote", - "syn 2.0.55", + "syn 2.0.74", ] [[package]] @@ -8222,9 +8228,9 @@ checksum = "257b64915a082f7811703966789728173279bdebb956b143dbcd23f6f970a777" [[package]] name = "pin-project-lite" -version = "0.2.13" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" +checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" [[package]] name = "pin-utils" @@ -8234,12 +8240,12 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "piper" -version = "0.2.1" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "668d31b1c4eba19242f2088b2bf3316b82ca31082a8335764db4e083db7485d4" +checksum = "96c8c490f422ef9a4efd2cb5b42b76c8613d7e7dfc1caf667b8a3350a5acc066" dependencies = [ "atomic-waker", - "fastrand 2.0.2", + "fastrand 2.1.0", "futures-io", ] @@ -8259,12 +8265,6 @@ version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" -[[package]] -name = "platforms" -version = "3.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "626dec3cac7cc0e1577a2ec3fc496277ec2baa084bebad95bb6fdbfae235f84c" - [[package]] name = "polkadot-approval-distribution" version = "8.0.0" @@ -8426,7 +8426,7 @@ dependencies = [ "fatality", "futures", "futures-timer", - "indexmap 2.2.6", + "indexmap 2.3.0", "parity-scale-codec", "polkadot-erasure-coding", "polkadot-node-network-protocol", @@ -8492,7 +8492,7 @@ dependencies = [ "fatality", "futures", "parity-scale-codec", - "parking_lot 0.12.1", + "parking_lot 0.12.3", "polkadot-node-metrics", "polkadot-node-network-protocol", "polkadot-node-subsystem", @@ -8753,7 +8753,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f3bbb1b5f4b966f21a0336e94c0a0222958d2f3cba451da1157af271d07f9748" dependencies = [ "always-assert", - "array-bytes 6.2.2", + "array-bytes 6.2.3", "blake3", "cfg-if", "futures", @@ -8851,7 +8851,7 @@ dependencies = [ "log", "mick-jaeger", "parity-scale-codec", - "parking_lot 0.12.1", + "parking_lot 0.12.3", "polkadot-node-primitives", "polkadot-primitives", "sc-network", @@ -8984,7 +8984,7 @@ dependencies = [ "kvdb", "parity-db", "parity-scale-codec", - "parking_lot 0.12.1", + "parking_lot 0.12.3", "pin-project", "polkadot-node-jaeger", "polkadot-node-metrics", @@ -9015,7 +9015,7 @@ dependencies = [ "futures", "futures-timer", "orchestra", - "parking_lot 0.12.1", + "parking_lot 0.12.3", "polkadot-node-metrics", "polkadot-node-network-protocol", "polkadot-node-primitives", @@ -9250,7 +9250,7 @@ dependencies = [ "pallet-transaction-payment-rpc-runtime-api", "parity-db", "parity-scale-codec", - "parking_lot 0.12.1", + "parking_lot 0.12.3", "polkadot-approval-distribution", "polkadot-availability-bitfield-distribution", "polkadot-availability-distribution", @@ -9353,7 +9353,7 @@ dependencies = [ "fatality", "futures", "futures-timer", - "indexmap 2.2.6", + "indexmap 2.3.0", "parity-scale-codec", "polkadot-node-network-protocol", "polkadot-node-primitives", @@ -9391,7 +9391,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6380dbe1fb03ecc74ad55d841cfc75480222d153ba69ddcb00977866cbdabdb8" dependencies = [ "polkavm-derive-impl", - "syn 2.0.55", + "syn 2.0.74", ] [[package]] @@ -9403,7 +9403,7 @@ dependencies = [ "polkavm-common", "proc-macro2", "quote", - "syn 2.0.55", + "syn 2.0.74", ] [[package]] @@ -9418,23 +9418,23 @@ dependencies = [ "concurrent-queue", "libc", "log", - "pin-project-lite 0.2.13", + "pin-project-lite 0.2.14", "windows-sys 0.48.0", ] [[package]] name = "polling" -version = "3.6.0" +version = "3.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0c976a60b2d7e99d6f229e414670a9b85d13ac305cc6d1e9c134de58c5aaaf6" +checksum = "cc2790cd301dec6cd3b7a025e4815cf825724a51c98dccfe6a3e55f05ffb6511" dependencies = [ "cfg-if", "concurrent-queue", - "hermit-abi", - "pin-project-lite 0.2.13", - "rustix 0.38.32", + "hermit-abi 0.4.0", + "pin-project-lite 0.2.14", + "rustix 0.38.34", "tracing", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -9557,7 +9557,7 @@ dependencies = [ "cumulus-primitives-aura", "cumulus-primitives-core", "cumulus-primitives-utility", - "env_logger 0.11.3", + "env_logger 0.11.5", "frame-benchmarking", "frame-executive", "frame-support", @@ -9631,7 +9631,7 @@ dependencies = [ "cumulus-primitives-aura", "cumulus-primitives-core", "cumulus-primitives-utility", - "env_logger 0.11.3", + "env_logger 0.11.5", "frame-benchmarking", "frame-executive", "frame-support", @@ -9693,9 +9693,9 @@ dependencies = [ [[package]] name = "portable-atomic" -version = "1.6.0" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7170ef9988bc169ba16dd36a7fa041e5c4cbeb6a35b76d4c03daded371eae7c0" +checksum = "da544ee218f0d287a911e9c99a39a8c9bc8fcad3cb8db5959940044ecfc67265" [[package]] name = "powerfmt" @@ -9705,9 +9705,12 @@ checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" [[package]] name = "ppv-lite86" -version = "0.2.17" +version = "0.2.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" +checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" +dependencies = [ + "zerocopy", +] [[package]] name = "predicates" @@ -9725,35 +9728,25 @@ dependencies = [ [[package]] name = "predicates-core" -version = "1.0.6" +version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b794032607612e7abeb4db69adb4e33590fa6cf1149e95fd7cb00e634b92f174" +checksum = "ae8177bee8e75d6846599c6b9ff679ed51e882816914eec639944d7c9aa11931" [[package]] name = "predicates-tree" -version = "1.0.9" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "368ba315fb8c5052ab692e68a0eefec6ec57b23a36959c14496f0b0df2c0cecf" +checksum = "41b740d195ed3166cd147c8047ec98db0e22ec019eb8eeb76d343b795304fb13" dependencies = [ "predicates-core", "termtree", ] -[[package]] -name = "prettier-please" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22020dfcf177fcc7bf5deaf7440af371400c67c0de14c399938d8ed4fb4645d3" -dependencies = [ - "proc-macro2", - "syn 2.0.55", -] - [[package]] name = "prettyplease" -version = "0.1.11" +version = "0.1.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f28f53e8b192565862cf99343194579a022eb9c7dd3a8d03134734803c7b3125" +checksum = "6c8646e95016a7a6c4adea95bafa8a16baab64b583356217f2c85db4a39d9a86" dependencies = [ "proc-macro2", "syn 1.0.109", @@ -9761,12 +9754,12 @@ dependencies = [ [[package]] name = "prettyplease" -version = "0.2.17" +version = "0.2.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d3928fb5db768cb86f891ff014f0144589297e3c6a1aba6ed7cecfdace270c7" +checksum = "5f12335488a2f3b0a83b14edad48dca9879ce89b2edd10e80237e4e852dd645e" dependencies = [ "proc-macro2", - "syn 2.0.55", + "syn 2.0.74", ] [[package]] @@ -9802,12 +9795,21 @@ dependencies = [ [[package]] name = "proc-macro-crate" -version = "1.3.1" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" +checksum = "e17d47ce914bf4de440332250b0edd23ce48c005f59fab39d3335866b114f11a" dependencies = [ - "once_cell", - "toml_edit 0.19.15", + "thiserror", + "toml 0.5.11", +] + +[[package]] +name = "proc-macro-crate" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e8366a6159044a37876a2b9817124296703c586a5c92e2c53751fa06d8d43e8" +dependencies = [ + "toml_edit 0.20.7", ] [[package]] @@ -9851,29 +9853,29 @@ checksum = "834da187cfe638ae8abb0203f0b33e5ccdb02a28e7199f2f47b3e2754f50edca" dependencies = [ "proc-macro2", "quote", - "syn 2.0.55", + "syn 2.0.74", ] [[package]] name = "proc-macro2" -version = "1.0.79" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e835ff2298f5721608eb1a980ecaee1aef2c132bf95ecc026a11b7bf3c01c02e" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] [[package]] name = "prometheus" -version = "0.13.3" +version = "0.13.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "449811d15fbdf5ceb5c1144416066429cf82316e2ec8ce0c1f6f8a02e7bbcf8c" +checksum = "3d33c28a30771f7f96db69893f78b857f7450d7e0237e9c8fc6427a81bae7ed1" dependencies = [ "cfg-if", "fnv", "lazy_static", "memchr", - "parking_lot 0.12.1", + "parking_lot 0.12.3", "thiserror", ] @@ -9885,7 +9887,7 @@ checksum = "5d6fa99d535dd930d1249e6c79cb3c2915f9172a540fe2b02a4c8f9ca954721e" dependencies = [ "dtoa", "itoa", - "parking_lot 0.12.1", + "parking_lot 0.12.3", "prometheus-client-derive-encode", ] @@ -9897,7 +9899,7 @@ checksum = "440f724eba9f6996b75d63681b0a92b06947f1457076d503a4d2e2c8f56442b8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.55", + "syn 2.0.74", ] [[package]] @@ -9912,12 +9914,12 @@ dependencies = [ [[package]] name = "prost" -version = "0.12.3" +version = "0.12.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "146c289cda302b98a28d40c8b3b90498d6e526dd24ac2ecea73e4e491685b94a" +checksum = "deb1435c188b76130da55f17a466d252ff7b1418b2ad3e037d127b94e3411f29" dependencies = [ "bytes", - "prost-derive 0.12.3", + "prost-derive 0.12.6", ] [[package]] @@ -9933,7 +9935,7 @@ dependencies = [ "log", "multimap", "petgraph", - "prettyplease 0.1.11", + "prettyplease 0.1.25", "prost 0.11.9", "prost-types", "regex", @@ -9957,15 +9959,15 @@ dependencies = [ [[package]] name = "prost-derive" -version = "0.12.3" +version = "0.12.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "efb6c9a1dd1def8e2124d17e83a20af56f1570d6c2d2bd9e266ccb768df3840e" +checksum = "81bddcdb20abf9501610992b6759a4c888aef7d1a7247ef75e2404275ac24af1" dependencies = [ "anyhow", - "itertools 0.11.0", + "itertools 0.12.1", "proc-macro2", "quote", - "syn 2.0.55", + "syn 2.0.74", ] [[package]] @@ -10045,9 +10047,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.35" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] @@ -10104,7 +10106,7 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ - "getrandom 0.2.12", + "getrandom 0.2.15", ] [[package]] @@ -10175,20 +10177,20 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.4.1" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" +checksum = "2a908a6e00f1fdd0dfd9c0eb08ce85126f6d8bbda50017e74bc4a4b7d4a926a4" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.6.0", ] [[package]] name = "redox_users" -version = "0.4.4" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a18479200779601e498ada4e8c1e1f50e3ee19deb0259c25825a98b5603b2cb4" +checksum = "bd283d9651eeda4b2a83a43c1c91b266c40fd76ecd39a50a8c630ae69dc72891" dependencies = [ - "getrandom 0.2.12", + "getrandom 0.2.15", "libredox", "thiserror", ] @@ -10207,22 +10209,22 @@ dependencies = [ [[package]] name = "ref-cast" -version = "1.0.22" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4846d4c50d1721b1a3bef8af76924eef20d5e723647333798c1b519b3a9473f" +checksum = "ccf0a6f84d5f1d581da8b41b47ec8600871962f2a528115b542b362d4b744931" dependencies = [ "ref-cast-impl", ] [[package]] name = "ref-cast-impl" -version = "1.0.22" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fddb4f8d99b0a2ebafc65a87a69a7b9875e4b1ae1f00db265d300ef7f28bccc" +checksum = "bcc303e793d3734489387d205e9b186fac9c6cfacedd98cbb2e8a5943595f3e6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.55", + "syn 2.0.74", ] [[package]] @@ -10239,14 +10241,14 @@ dependencies = [ [[package]] name = "regex" -version = "1.10.4" +version = "1.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c" +checksum = "4219d74c6b67a3654a9fbebc4b419e22126d13d2f3c4a07ee0cb61ff79a79619" dependencies = [ "aho-corasick", "memchr", - "regex-automata 0.4.6", - "regex-syntax 0.8.2", + "regex-automata 0.4.7", + "regex-syntax 0.8.4", ] [[package]] @@ -10260,13 +10262,13 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.6" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea" +checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" dependencies = [ "aho-corasick", "memchr", - "regex-syntax 0.8.2", + "regex-syntax 0.8.4", ] [[package]] @@ -10277,9 +10279,9 @@ checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" [[package]] name = "regex-syntax" -version = "0.8.2" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" +checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" [[package]] name = "resolv-conf" @@ -10298,7 +10300,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" dependencies = [ "hmac 0.12.1", - "subtle 2.5.0", + "subtle 2.4.1", ] [[package]] @@ -10324,7 +10326,7 @@ checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" dependencies = [ "cc", "cfg-if", - "getrandom 0.2.12", + "getrandom 0.2.15", "libc", "spin 0.9.8", "untrusted 0.9.0", @@ -10519,9 +10521,9 @@ dependencies = [ [[package]] name = "rustc-demangle" -version = "0.1.23" +version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" +checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" [[package]] name = "rustc-hash" @@ -10541,7 +10543,7 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" dependencies = [ - "semver 1.0.22", + "semver 1.0.23", ] [[package]] @@ -10583,14 +10585,14 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.32" +version = "0.38.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65e04861e65f21776e67888bfbea442b3642beaa0138fdb1dd7a84a52dffdb89" +checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "errno", "libc", - "linux-raw-sys 0.4.13", + "linux-raw-sys 0.4.14", "windows-sys 0.52.0", ] @@ -10608,9 +10610,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.21.10" +version = "0.21.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9d5a6813c0759e4609cd494e8e725babae6a2ca7b62a5536a13daaec6fcb7ba" +checksum = "3f56a14d1f48b391359b22f731fd4bd7e43c97f3c50eee276f3aa09c94784d3e" dependencies = [ "log", "ring 0.17.8", @@ -10651,9 +10653,9 @@ dependencies = [ [[package]] name = "rustversion" -version = "1.0.14" +version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" +checksum = "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6" [[package]] name = "ruzstd" @@ -10679,15 +10681,15 @@ dependencies = [ [[package]] name = "ryu" -version = "1.0.17" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1" +checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" [[package]] name = "safe_arch" -version = "0.7.1" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f398075ce1e6a179b46f51bd88d0598b92b00d3551f1a2d4ac49e771b56ac354" +checksum = "c3460605018fdc9612bce72735cba0d27efbcd9904780d44c7e3a9948f96148a" dependencies = [ "bytemuck", ] @@ -10728,7 +10730,7 @@ dependencies = [ "multihash 0.18.1", "multihash-codetable", "parity-scale-codec", - "prost 0.12.3", + "prost 0.12.6", "prost-build", "rand", "sc-client-api", @@ -10788,7 +10790,7 @@ version = "28.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0f73880050f8b04fed7f6301279ef3899df13a3891bd06156d56f9a1c50fefba" dependencies = [ - "array-bytes 6.2.2", + "array-bytes 6.2.3", "docify", "log", "memmap2 0.9.4", @@ -10818,7 +10820,7 @@ dependencies = [ "proc-macro-crate 3.1.0", "proc-macro2", "quote", - "syn 2.0.55", + "syn 2.0.74", ] [[package]] @@ -10827,7 +10829,7 @@ version = "0.37.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e8a284c10ea92b1fe789b9f0e5815d393f3a1e3bf6a4adaa884f24e36143b83b" dependencies = [ - "array-bytes 6.2.2", + "array-bytes 6.2.3", "bip39", "chrono", "clap", @@ -10873,7 +10875,7 @@ dependencies = [ "futures", "log", "parity-scale-codec", - "parking_lot 0.12.1", + "parking_lot 0.12.3", "sc-executor", "sc-transaction-pool-api", "sc-utils", @@ -10905,7 +10907,7 @@ dependencies = [ "log", "parity-db", "parity-scale-codec", - "parking_lot 0.12.1", + "parking_lot 0.12.3", "sc-client-api", "sc-state-db", "schnellru", @@ -10930,7 +10932,7 @@ dependencies = [ "libp2p-identity", "log", "mockall", - "parking_lot 0.12.1", + "parking_lot 0.12.3", "sc-client-api", "sc-utils", "serde", @@ -10988,7 +10990,7 @@ dependencies = [ "num-rational", "num-traits", "parity-scale-codec", - "parking_lot 0.12.1", + "parking_lot 0.12.3", "sc-client-api", "sc-consensus", "sc-consensus-epochs", @@ -11040,14 +11042,14 @@ version = "14.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e9ce3ee15eff7fa642791966d427f185184df3c7f4e58893705f3e7781da8ef5" dependencies = [ - "array-bytes 6.2.2", + "array-bytes 6.2.3", "async-channel 1.9.0", "async-trait", "fnv", "futures", "log", "parity-scale-codec", - "parking_lot 0.12.1", + "parking_lot 0.12.3", "sc-client-api", "sc-consensus", "sc-network", @@ -11081,7 +11083,7 @@ dependencies = [ "jsonrpsee", "log", "parity-scale-codec", - "parking_lot 0.12.1", + "parking_lot 0.12.3", "sc-consensus-beefy", "sc-rpc", "serde", @@ -11112,7 +11114,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ae91e5b5a120be4d13a59eaf94fd85d7c7af528482b8e21d861fa1167df3083" dependencies = [ "ahash 0.8.11", - "array-bytes 6.2.2", + "array-bytes 6.2.3", "async-trait", "dyn-clone", "finality-grandpa", @@ -11121,7 +11123,7 @@ dependencies = [ "futures-timer", "log", "parity-scale-codec", - "parking_lot 0.12.1", + "parking_lot 0.12.3", "rand", "sc-block-builder", "sc-chain-spec", @@ -11201,7 +11203,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "aa2ac6c356538d67987bbb867e11a12a84ba87250c70fd50005b6d74f570a4f7" dependencies = [ "parity-scale-codec", - "parking_lot 0.12.1", + "parking_lot 0.12.3", "sc-executor-common", "sc-executor-wasmtime", "schnellru", @@ -11240,7 +11242,7 @@ dependencies = [ "cfg-if", "libc", "log", - "parking_lot 0.12.1", + "parking_lot 0.12.3", "rustix 0.36.17", "sc-allocator", "sc-executor-common", @@ -11273,8 +11275,8 @@ version = "26.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4cc4f6a558dd23e3bae2e9f195da822465258b9aaf211c34360d7f6efb944e54" dependencies = [ - "array-bytes 6.2.2", - "parking_lot 0.12.1", + "array-bytes 6.2.3", + "parking_lot 0.12.3", "serde_json", "sp-application-crypto", "sp-core", @@ -11299,7 +11301,7 @@ dependencies = [ "mixnet", "multiaddr", "parity-scale-codec", - "parking_lot 0.12.1", + "parking_lot 0.12.3", "sc-client-api", "sc-network", "sc-transaction-pool-api", @@ -11318,7 +11320,7 @@ version = "0.35.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f231c7d5e749ec428b4cfa669d759ae76cd3da4f50d7352a2d711acdc7532891" dependencies = [ - "array-bytes 6.2.2", + "array-bytes 6.2.3", "async-channel 1.9.0", "async-trait", "asynchronous-codec", @@ -11333,7 +11335,7 @@ dependencies = [ "log", "mockall", "parity-scale-codec", - "parking_lot 0.12.1", + "parking_lot 0.12.3", "partial_sort", "pin-project", "rand", @@ -11367,7 +11369,7 @@ dependencies = [ "futures", "libp2p-identity", "log", - "prost 0.12.3", + "prost 0.12.6", "prost-build", "sc-client-api", "sc-network", @@ -11421,13 +11423,13 @@ version = "0.34.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "38d84ef0b212c775f58e0304ec09166089f6b09afddf559b7c2b5702933b3be4" dependencies = [ - "array-bytes 6.2.2", + "array-bytes 6.2.3", "async-channel 1.9.0", "futures", "libp2p-identity", "log", "parity-scale-codec", - "prost 0.12.3", + "prost 0.12.6", "prost-build", "sc-client-api", "sc-network", @@ -11443,7 +11445,7 @@ version = "0.34.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9aa9377059deece4e7d419d9ec456f657268c0c603e1cf98df4a920f6da83461" dependencies = [ - "array-bytes 6.2.2", + "array-bytes 6.2.3", "async-channel 1.9.0", "async-trait", "fork-tree", @@ -11453,7 +11455,7 @@ dependencies = [ "log", "mockall", "parity-scale-codec", - "prost 0.12.3", + "prost 0.12.6", "prost-build", "sc-client-api", "sc-consensus", @@ -11480,7 +11482,7 @@ version = "0.34.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "16c9cad4baf348725bd82eadcd1747fc112ec49c76b863755ce79c588fa73fe4" dependencies = [ - "array-bytes 6.2.2", + "array-bytes 6.2.3", "futures", "libp2p", "log", @@ -11500,7 +11502,7 @@ version = "30.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1aee89f2abd406356bfd688bd7a51155dc963259e4b752bb85d1f8a061a194fd" dependencies = [ - "array-bytes 6.2.2", + "array-bytes 6.2.3", "bytes", "fnv", "futures", @@ -11512,7 +11514,7 @@ dependencies = [ "num_cpus", "once_cell", "parity-scale-codec", - "parking_lot 0.12.1", + "parking_lot 0.12.3", "rand", "sc-client-api", "sc-network", @@ -11549,7 +11551,7 @@ dependencies = [ "jsonrpsee", "log", "parity-scale-codec", - "parking_lot 0.12.1", + "parking_lot 0.12.3", "sc-block-builder", "sc-chain-spec", "sc-client-api", @@ -11615,14 +11617,14 @@ version = "0.35.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a7f10275c62296a785f6e2ac716521e3b6e0fae470416fdf86491cbbfcc2e23d" dependencies = [ - "array-bytes 6.2.2", + "array-bytes 6.2.3", "futures", "futures-util", "hex", "jsonrpsee", "log", "parity-scale-codec", - "parking_lot 0.12.1", + "parking_lot 0.12.3", "sc-chain-spec", "sc-client-api", "sc-rpc", @@ -11654,7 +11656,7 @@ dependencies = [ "jsonrpsee", "log", "parity-scale-codec", - "parking_lot 0.12.1", + "parking_lot 0.12.3", "pin-project", "rand", "sc-chain-spec", @@ -11712,7 +11714,7 @@ checksum = "aa842052c41ad379eaecdfddc0d5c953d57e311ae688233f68f461b91d38da0a" dependencies = [ "log", "parity-scale-codec", - "parking_lot 0.12.1", + "parking_lot 0.12.3", "sp-core", ] @@ -11782,7 +11784,7 @@ dependencies = [ "futures", "libp2p", "log", - "parking_lot 0.12.1", + "parking_lot 0.12.3", "pin-project", "rand", "sc-utils", @@ -11805,7 +11807,7 @@ dependencies = [ "libc", "log", "parity-scale-codec", - "parking_lot 0.12.1", + "parking_lot 0.12.3", "regex", "rustc-hash", "sc-client-api", @@ -11832,7 +11834,7 @@ dependencies = [ "proc-macro-crate 3.1.0", "proc-macro2", "quote", - "syn 2.0.55", + "syn 2.0.74", ] [[package]] @@ -11847,7 +11849,7 @@ dependencies = [ "linked-hash-map", "log", "parity-scale-codec", - "parking_lot 0.12.1", + "parking_lot 0.12.3", "sc-client-api", "sc-transaction-pool-api", "sc-utils", @@ -11891,16 +11893,16 @@ dependencies = [ "futures-timer", "lazy_static", "log", - "parking_lot 0.12.1", + "parking_lot 0.12.3", "prometheus", "sp-arithmetic", ] [[package]] name = "scale-info" -version = "2.11.1" +version = "2.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "788745a868b0e751750388f4e6546eb921ef714a4317fa6954f7cde114eb2eb7" +checksum = "eca070c12893629e2cc820a9761bedf6ce1dcddc9852984d1dc734b8bd9bd024" dependencies = [ "bitvec", "cfg-if", @@ -11912,11 +11914,11 @@ dependencies = [ [[package]] name = "scale-info-derive" -version = "2.11.1" +version = "2.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7dc2f4e8bc344b9fc3d5f74f72c2e55bfc38d28dc2ebc69c194a3df424e4d9ac" +checksum = "2d35494501194174bda522a32605929eefc9ecf7e0a326c26db1fdd85881eb62" dependencies = [ - "proc-macro-crate 1.3.1", + "proc-macro-crate 3.1.0", "proc-macro2", "quote", "syn 1.0.109", @@ -11933,9 +11935,9 @@ dependencies = [ [[package]] name = "schnellru" -version = "0.2.1" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "772575a524feeb803e5b0fcbc6dd9f367e579488197c94c6e4023aad2305774d" +checksum = "c9a8ef13a93c54d20580de1e5c413e624e53121d42fc7e2c11d10ef7f8b02367" dependencies = [ "ahash 0.8.11", "cfg-if", @@ -11967,13 +11969,13 @@ dependencies = [ "aead", "arrayref", "arrayvec 0.7.4", - "curve25519-dalek 4.1.2", + "curve25519-dalek 4.1.3", "getrandom_or_panic", "merlin", "rand_core 0.6.4", "serde_bytes", "sha2 0.10.8", - "subtle 2.5.0", + "subtle 2.4.1", "zeroize", ] @@ -12009,7 +12011,7 @@ dependencies = [ "der", "generic-array 0.14.7", "pkcs8", - "subtle 2.5.0", + "subtle 2.4.1", "zeroize", ] @@ -12051,11 +12053,11 @@ dependencies = [ [[package]] name = "security-framework" -version = "2.9.2" +version = "2.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05b64fb303737d99b81884b2c63433e9ae28abebe5eb5045dcdd175dc2ecf4de" +checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.6.0", "core-foundation", "core-foundation-sys", "libc", @@ -12064,9 +12066,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.9.1" +version = "2.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e932934257d3b408ed8f30db49d85ea163bfe74961f017f405b025af298f0c7a" +checksum = "75da29fe9b9b08fe9d6b22b5b4bcbc75d8db3aa31e639aa56bb62e9d46bfceaf" dependencies = [ "core-foundation-sys", "libc", @@ -12083,9 +12085,9 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.22" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92d43fe69e652f3df9bdc2b85b2854a0825b86e4fb76bc44d945137d053639ca" +checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" dependencies = [ "serde", ] @@ -12098,9 +12100,9 @@ checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" [[package]] name = "serde" -version = "1.0.197" +version = "1.0.207" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2" +checksum = "5665e14a49a4ea1b91029ba7d3bca9f299e1f7cfa194388ccc20f14743e784f2" dependencies = [ "serde_derive", ] @@ -12116,40 +12118,41 @@ dependencies = [ [[package]] name = "serde_bytes" -version = "0.11.14" +version = "0.11.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b8497c313fd43ab992087548117643f6fcd935cbf36f176ffda0aacf9591734" +checksum = "387cc504cb06bb40a96c8e04e951fe01854cf6bc921053c954e4a606d9675c6a" dependencies = [ "serde", ] [[package]] name = "serde_derive" -version = "1.0.197" +version = "1.0.207" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" +checksum = "6aea2634c86b0e8ef2cfdc0c340baede54ec27b1e46febd7f80dffb2aa44a00e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.55", + "syn 2.0.74", ] [[package]] name = "serde_json" -version = "1.0.114" +version = "1.0.124" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5f09b1bd632ef549eaa9f60a1f8de742bdbc698e6cee2095fc84dde5f549ae0" +checksum = "66ad62847a56b3dba58cc891acd13884b9c61138d330c0d7b6181713d4fce38d" dependencies = [ "itoa", + "memchr", "ryu", "serde", ] [[package]] name = "serde_spanned" -version = "0.6.5" +version = "0.6.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb3622f419d1296904700073ea6cc23ad690adbd66f13ea683df73298736f0c1" +checksum = "eb5b1b31579f3811bf615c144393417496f152e12ac8b7663bf664f4a815306d" dependencies = [ "serde", ] @@ -12229,9 +12232,9 @@ checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" [[package]] name = "signal-hook-registry" -version = "1.4.1" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" +checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1" dependencies = [ "libc", ] @@ -12353,7 +12356,7 @@ dependencies = [ "fnv", "futures-lite 1.13.0", "futures-util", - "hashbrown 0.14.3", + "hashbrown 0.14.5", "hex", "hmac 0.12.1", "itertools 0.11.0", @@ -12402,13 +12405,13 @@ dependencies = [ "futures-channel", "futures-lite 1.13.0", "futures-util", - "hashbrown 0.14.3", + "hashbrown 0.14.5", "hex", "itertools 0.11.0", "log", "lru 0.11.1", "no-std-net", - "parking_lot 0.12.1", + "parking_lot 0.12.3", "pin-project", "rand", "rand_chacha 0.3.1", @@ -12436,12 +12439,12 @@ dependencies = [ "aes-gcm", "blake2 0.10.6", "chacha20poly1305", - "curve25519-dalek 4.1.2", + "curve25519-dalek 4.1.3", "rand_core 0.6.4", "ring 0.17.8", "rustc_version", "sha2 0.10.8", - "subtle 2.5.0", + "subtle 2.4.1", ] [[package]] @@ -12456,9 +12459,9 @@ dependencies = [ [[package]] name = "snowbridge-beacon-primitives" -version = "0.1.0" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60a73ef707257064bc4ecce8323cdb7c30e8ecd1ce74aa89a6e82e81fa8b9970" +checksum = "5404af73550b39022e08e5500b30fba627e109a56407b7e80b08da2305b11bfe" dependencies = [ "byte-slice-cast", "frame-support", @@ -12481,9 +12484,9 @@ dependencies = [ [[package]] name = "snowbridge-core" -version = "0.1.1" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a3e2e3b94bfcfc8f363e21a6c5a1d3c67eb4592ada672c868a3236ad1dd563b" +checksum = "aed4ebefed4c40b9c00e9adf5f02ab2760a7a2dad8bf05110c0013a7a59f4097" dependencies = [ "ethabi-decode", "frame-support", @@ -12577,9 +12580,9 @@ dependencies = [ [[package]] name = "socket2" -version = "0.5.6" +version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05ffd9c0a93b7543e062e759284fcf5f5e3b098501104bfbdde4d404db792871" +checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" dependencies = [ "libc", "windows-sys 0.52.0", @@ -12632,11 +12635,11 @@ checksum = "0301e2f77afb450fbf2b093f8b324c7ad88cc82e5e69bd5dc8658a1f068b2a96" dependencies = [ "Inflector", "blake2 0.10.6", - "expander 2.1.0", + "expander 2.2.1", "proc-macro-crate 3.1.0", "proc-macro2", "quote", - "syn 2.0.55", + "syn 2.0.74", ] [[package]] @@ -12703,7 +12706,7 @@ dependencies = [ "futures", "log", "parity-scale-codec", - "parking_lot 0.12.1", + "parking_lot 0.12.3", "schnellru", "sp-api", "sp-consensus", @@ -12826,7 +12829,7 @@ version = "29.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7c33c7a1568175250628567d50c4e1c54a6ac5bc1190413b9be29a9e810cbe73" dependencies = [ - "array-bytes 6.2.2", + "array-bytes 6.2.3", "bip39", "bitflags 1.3.2", "blake2 0.10.6", @@ -12843,7 +12846,7 @@ dependencies = [ "log", "merlin", "parity-scale-codec", - "parking_lot 0.12.1", + "parking_lot 0.12.3", "paste", "primitive-types", "rand", @@ -12888,7 +12891,7 @@ checksum = "b85d0f1f1e44bd8617eb2a48203ee854981229e3e79e6f468c7175d5fd37489b" dependencies = [ "quote", "sp-crypto-hashing", - "syn 2.0.55", + "syn 2.0.74", ] [[package]] @@ -12898,7 +12901,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "722cbecdbf5b94578137dbd07feb51e95f7de221be0c1ff4dcfe0bb4cd986929" dependencies = [ "kvdb", - "parking_lot 0.12.1", + "parking_lot 0.12.3", ] [[package]] @@ -12909,7 +12912,7 @@ checksum = "48d09fa0a5f7299fb81ee25ae3853d26200f7a348148aed6de76be905c007dbe" dependencies = [ "proc-macro2", "quote", - "syn 2.0.55", + "syn 2.0.74", ] [[package]] @@ -12995,7 +12998,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "444f2d53968b1ce5e908882710ff1f3873fcf3e95f59d57432daf685bbacb959" dependencies = [ "parity-scale-codec", - "parking_lot 0.12.1", + "parking_lot 0.12.3", "sp-core", "sp-externalities", "thiserror", @@ -13154,11 +13157,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cfaf6e85b2ec12a4b99cd6d8d57d083e30c94b7f1b0d8f93547121495aae6f0c" dependencies = [ "Inflector", - "expander 2.1.0", + "expander 2.2.1", "proc-macro-crate 3.1.0", "proc-macro2", "quote", - "syn 2.0.55", + "syn 2.0.74", ] [[package]] @@ -13201,7 +13204,7 @@ dependencies = [ "hash-db", "log", "parity-scale-codec", - "parking_lot 0.12.1", + "parking_lot 0.12.3", "rand", "smallvec", "sp-core", @@ -13221,7 +13224,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "309a9ae4e8134bbed8ffc510cf4d461a4a651f9250b556de782cedd876abe1ff" dependencies = [ "aes-gcm", - "curve25519-dalek 4.1.2", + "curve25519-dalek 4.1.3", "ed25519-dalek", "hkdf", "parity-scale-codec", @@ -13325,7 +13328,7 @@ dependencies = [ "memory-db", "nohash-hasher", "parity-scale-codec", - "parking_lot 0.12.1", + "parking_lot 0.12.3", "rand", "scale-info", "schnellru", @@ -13365,7 +13368,7 @@ dependencies = [ "parity-scale-codec", "proc-macro2", "quote", - "syn 2.0.55", + "syn 2.0.74", ] [[package]] @@ -13496,7 +13499,7 @@ version = "8.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "48fa328b87de3466bc38cc9a07244c42c647b7755b81115e1dfeb47cc13fc6e6" dependencies = [ - "array-bytes 6.2.2", + "array-bytes 6.2.3", "bounded-collections", "derivative", "environmental", @@ -13597,15 +13600,15 @@ dependencies = [ "bitflags 1.3.2", "byteorder", "keccak", - "subtle 2.5.0", + "subtle 2.4.1", "zeroize", ] [[package]] name = "strsim" -version = "0.11.0" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ee073c9e4cd00e28217186dbe12796d692868f432bf2e97ee73bed0c56dfa01" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "strum" @@ -13618,9 +13621,9 @@ dependencies = [ [[package]] name = "strum" -version = "0.25.0" +version = "0.26.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "290d54ea6f91c969195bdbcd7442c8c2a2ba87da8bf60a7ee86a235d4bc1e125" +checksum = "8fec0f0aef304996cf250b31b5a10dee7980c85da9d759361292b8bca5a18f06" [[package]] name = "strum_macros" @@ -13637,15 +13640,15 @@ dependencies = [ [[package]] name = "strum_macros" -version = "0.25.3" +version = "0.26.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23dc1fa9ac9c169a78ba62f0b841814b7abae11bdd047b9c58f893439e309ea0" +checksum = "4c6bee85a5a24955dc440386795aa378cd9cf82acd5f764469152d2270e581be" dependencies = [ - "heck 0.4.1", + "heck 0.5.0", "proc-macro2", "quote", "rustversion", - "syn 2.0.55", + "syn 2.0.74", ] [[package]] @@ -13746,7 +13749,7 @@ dependencies = [ "sp-maybe-compressed-blob", "strum 0.24.1", "tempfile", - "toml 0.8.12", + "toml 0.8.19", "walkdir", "wasm-opt", ] @@ -13759,9 +13762,9 @@ checksum = "2d67a5a62ba6e01cb2192ff309324cb4875d0c451d55fe2319433abe7a05a8ee" [[package]] name = "subtle" -version = "2.5.0" +version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" +checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" [[package]] name = "subtle-ng" @@ -13782,9 +13785,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.55" +version = "2.0.74" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "002a1b3dbf967edfafc32655d0f377ab0bb7b994aa1d32c8cc7e9b8bf3ebb8f0" +checksum = "1fceb41e3d546d0bd83421d3409b1460cc7444cd389341a4c880fe7a042cb3d7" dependencies = [ "proc-macro2", "quote", @@ -13803,6 +13806,17 @@ dependencies = [ "unicode-xid", ] +[[package]] +name = "synstructure" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.74", +] + [[package]] name = "system-configuration" version = "0.5.1" @@ -13827,7 +13841,7 @@ dependencies = [ [[package]] name = "system-parachains-constants" version = "1.0.0" -source = "git+https://github.com/paseo-network/runtimes/?tag=v1.2.5-system-chains#e7265b10b28d8b82c3146e72c98895dac2b55729" +source = "git+https://github.com/paseo-network/runtimes/?tag=v1.2.5-system-chains#2fa66a19eef96bd2c079385057fab2564d09b751" dependencies = [ "frame-support", "parachains-common", @@ -13846,20 +13860,21 @@ checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" [[package]] name = "target-lexicon" -version = "0.12.14" +version = "0.12.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1fc403891a21bcfb7c37834ba66a547a8f402146eba7265b5a6d88059c9ff2f" +checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1" [[package]] name = "tempfile" -version = "3.10.1" +version = "3.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" +checksum = "04cbcdd0c794ebb0d4cf35e88edd2f7d2c4c3e9a5a6dab322839b321c6a87a64" dependencies = [ "cfg-if", - "fastrand 2.0.2", - "rustix 0.38.32", - "windows-sys 0.52.0", + "fastrand 2.1.0", + "once_cell", + "rustix 0.38.34", + "windows-sys 0.59.0", ] [[package]] @@ -13877,7 +13892,7 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "21bebf2b7c9e0a515f6e0f8c51dc0f8e4696391e6f1ff30379559f8365fb0df7" dependencies = [ - "rustix 0.38.32", + "rustix 0.38.34", "windows-sys 0.48.0", ] @@ -13889,9 +13904,9 @@ checksum = "3369f5ac52d5eb6ab48c6b4ffdc8efbcad6b89c765749064ba298f2c68a16a76" [[package]] name = "thiserror" -version = "1.0.58" +version = "1.0.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03468839009160513471e86a034bb2c5c0e4baae3b43f79ffc55c4a5427b3297" +checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724" dependencies = [ "thiserror-impl", ] @@ -13913,18 +13928,18 @@ checksum = "e4c60d69f36615a077cc7663b9cb8e42275722d23e58a7fa3d2c7f2915d09d04" dependencies = [ "proc-macro2", "quote", - "syn 2.0.55", + "syn 2.0.74", ] [[package]] name = "thiserror-impl" -version = "1.0.58" +version = "1.0.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c61f3ba182994efc43764a46c018c347bc492c79f024e705f46567b418f6d4f7" +checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261" dependencies = [ "proc-macro2", "quote", - "syn 2.0.55", + "syn 2.0.74", ] [[package]] @@ -13988,9 +14003,9 @@ dependencies = [ [[package]] name = "time" -version = "0.3.34" +version = "0.3.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8248b6521bb14bc45b4067159b9b6ad792e2d6d754d6c41fb50e29fefe38749" +checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" dependencies = [ "deranged", "itoa", @@ -14009,9 +14024,9 @@ checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" [[package]] name = "time-macros" -version = "0.2.17" +version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ba3a3ef41e6672a2f0f001392bb5dcd3ff0a9992d618ca761a11c3121547774" +checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf" dependencies = [ "num-conv", "time-core", @@ -14028,9 +14043,9 @@ dependencies = [ [[package]] name = "tinyvec" -version = "1.6.0" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +checksum = "445e881f4f6d382d5f27c034e25eb92edd7c784ceab92a0937db7f2e9471b938" dependencies = [ "tinyvec_macros", ] @@ -14043,32 +14058,31 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.37.0" +version = "1.39.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1adbebffeca75fcfd058afa480fb6c0b81e165a0323f9c9d39c9697e37c46787" +checksum = "daa4fb1bc778bd6f04cbfc4bb2d06a7396a8f299dc33ea1900cedaa316f467b1" dependencies = [ "backtrace", "bytes", "libc", "mio", - "num_cpus", - "parking_lot 0.12.1", - "pin-project-lite 0.2.13", + "parking_lot 0.12.3", + "pin-project-lite 0.2.14", "signal-hook-registry", - "socket2 0.5.6", + "socket2 0.5.7", "tokio-macros", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] name = "tokio-macros" -version = "2.2.0" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" +checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" dependencies = [ "proc-macro2", "quote", - "syn 2.0.55", + "syn 2.0.74", ] [[package]] @@ -14088,7 +14102,7 @@ version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" dependencies = [ - "rustls 0.21.10", + "rustls 0.21.12", "tokio", ] @@ -14099,24 +14113,23 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "267ac89e0bec6e691e5813911606935d77c476ff49024f98abcea3e7b15e37af" dependencies = [ "futures-core", - "pin-project-lite 0.2.13", + "pin-project-lite 0.2.14", "tokio", "tokio-util", ] [[package]] name = "tokio-util" -version = "0.7.10" +version = "0.7.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15" +checksum = "9cf6b47b3771c49ac75ad09a6162f53ad4b8088b76ac60e8ec1455b31a189fe1" dependencies = [ "bytes", "futures-core", "futures-io", "futures-sink", - "pin-project-lite 0.2.13", + "pin-project-lite 0.2.14", "tokio", - "tracing", ] [[package]] @@ -14130,32 +14143,32 @@ dependencies = [ [[package]] name = "toml" -version = "0.8.12" +version = "0.8.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9dd1545e8208b4a5af1aa9bbd0b4cf7e9ea08fabc5d0a5c67fcaafa17433aa3" +checksum = "a1ed1f98e3fdc28d6d910e6737ae6ab1a93bf1985935a1193e68f93eeb68d24e" dependencies = [ "serde", "serde_spanned", "toml_datetime", - "toml_edit 0.22.9", + "toml_edit 0.22.20", ] [[package]] name = "toml_datetime" -version = "0.6.5" +version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1" +checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" dependencies = [ "serde", ] [[package]] name = "toml_edit" -version = "0.19.15" +version = "0.20.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" +checksum = "70f427fce4d84c72b5b732388bf4a9f4531b53f74e2887e3ecb2481f68f66d81" dependencies = [ - "indexmap 2.2.6", + "indexmap 2.3.0", "toml_datetime", "winnow 0.5.40", ] @@ -14166,22 +14179,22 @@ version = "0.21.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a8534fd7f78b5405e860340ad6575217ce99f38d4d5c8f2442cb5ecb50090e1" dependencies = [ - "indexmap 2.2.6", + "indexmap 2.3.0", "toml_datetime", "winnow 0.5.40", ] [[package]] name = "toml_edit" -version = "0.22.9" +version = "0.22.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e40bb779c5187258fd7aad0eb68cb8706a0a81fa712fbea808ab43c4b8374c4" +checksum = "583c44c02ad26b0c3f3066fe629275e50627026c51ac2e595cca4c230ce1ce1d" dependencies = [ - "indexmap 2.2.6", + "indexmap 2.3.0", "serde", "serde_spanned", "toml_datetime", - "winnow 0.6.5", + "winnow 0.6.18", ] [[package]] @@ -14193,7 +14206,7 @@ dependencies = [ "futures-core", "futures-util", "pin-project", - "pin-project-lite 0.2.13", + "pin-project-lite 0.2.14", "tower-layer", "tower-service", "tracing", @@ -14205,14 +14218,14 @@ version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "61c5bb1d698276a2443e5ecfabc1008bf15a36c12e6a7176e7bf089ea9131140" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "bytes", "futures-core", "futures-util", "http", "http-body", "http-range-header", - "pin-project-lite 0.2.13", + "pin-project-lite 0.2.14", "tower-layer", "tower-service", ] @@ -14236,7 +14249,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" dependencies = [ "log", - "pin-project-lite 0.2.13", + "pin-project-lite 0.2.14", "tracing-attributes", "tracing-core", ] @@ -14249,7 +14262,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.55", + "syn 2.0.74", ] [[package]] @@ -14290,11 +14303,11 @@ version = "5.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0f074568687ffdfd0adb6005aa8d1d96840197f2c159f80471285f08694cf0ce" dependencies = [ - "expander 2.1.0", + "expander 2.2.1", "proc-macro-crate 3.1.0", "proc-macro2", "quote", - "syn 2.0.55", + "syn 2.0.74", ] [[package]] @@ -14427,7 +14440,7 @@ dependencies = [ "ipconfig", "lazy_static", "lru-cache", - "parking_lot 0.12.1", + "parking_lot 0.12.3", "resolv-conf", "smallvec", "thiserror", @@ -14544,9 +14557,9 @@ dependencies = [ [[package]] name = "unicode-width" -version = "0.1.11" +version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85" +checksum = "0336d538f7abc86d282a4189614dfaa90810dfc2c6f6427eaf88e16311dd225d" [[package]] name = "unicode-xid" @@ -14561,7 +14574,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07ea" dependencies = [ "crypto-common", - "subtle 2.5.0", + "subtle 2.4.1", ] [[package]] @@ -14590,9 +14603,9 @@ checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" [[package]] name = "url" -version = "2.5.0" +version = "2.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633" +checksum = "22784dbdf76fdde8af1aeda5622b546b422b6fc585325248a2bf9f5e41e94d6c" dependencies = [ "form_urlencoded", "idna 0.5.0", @@ -14601,9 +14614,9 @@ dependencies = [ [[package]] name = "utf8parse" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "valuable" @@ -14619,9 +14632,9 @@ checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" [[package]] name = "version_check" -version = "0.9.4" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" [[package]] name = "void" @@ -14631,9 +14644,9 @@ checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" [[package]] name = "w3f-bls" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7335e4c132c28cc43caef6adb339789e599e39adbe78da0c4d547fad48cbc331" +checksum = "9c5da5fa2c6afa2c9158eaa7cd9aee249765eb32b5fb0c63ad8b9e79336a47ec" dependencies = [ "ark-bls12-377", "ark-bls12-381", @@ -14655,9 +14668,9 @@ dependencies = [ [[package]] name = "waker-fn" -version = "1.1.1" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3c4517f54858c779bbcbf228f4fca63d121bf85fbecb2dc578cdf4a39395690" +checksum = "317211a0dc0ceedd78fb2ca9a44aed3d7b9b26f81870d485c07122b4350673b7" [[package]] name = "walkdir" @@ -14701,34 +14714,35 @@ dependencies = [ [[package]] name = "wasm-bindgen" -version = "0.2.92" +version = "0.2.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" +checksum = "a82edfc16a6c469f5f44dc7b571814045d60404b55a0ee849f9bcfa2e63dd9b5" dependencies = [ "cfg-if", + "once_cell", "wasm-bindgen-macro", ] [[package]] name = "wasm-bindgen-backend" -version = "0.2.92" +version = "0.2.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" +checksum = "9de396da306523044d3302746f1208fa71d7532227f15e347e2d93e4145dd77b" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", - "syn 2.0.55", + "syn 2.0.74", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.42" +version = "0.4.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76bc14366121efc8dbb487ab05bcc9d346b3b5ec0eaa76e46594cabbe51762c0" +checksum = "61e9300f63a621e96ed275155c108eb6f843b6a26d053f122ab69724559dc8ed" dependencies = [ "cfg-if", "js-sys", @@ -14738,9 +14752,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.92" +version = "0.2.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" +checksum = "585c4c91a46b072c92e908d99cb1dcdf95c5218eeb6f3bf1efa991ee7a68cccf" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -14748,22 +14762,22 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.92" +version = "0.2.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" +checksum = "afc340c74d9005395cf9dd098506f7f44e38f2b4a21c6aaacf9a105ea5e1e836" dependencies = [ "proc-macro2", "quote", - "syn 2.0.55", + "syn 2.0.74", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.92" +version = "0.2.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" +checksum = "c62a0a307cb4a311d3a07867860911ca130c3494e8c2719593806c08bc5d0484" [[package]] name = "wasm-instrument" @@ -14776,9 +14790,9 @@ dependencies = [ [[package]] name = "wasm-opt" -version = "0.116.0" +version = "0.116.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc942673e7684671f0c5708fc18993569d184265fd5223bb51fc8e5b9b6cfd52" +checksum = "2fd87a4c135535ffed86123b6fb0f0a5a0bc89e50416c942c5f0662c645f679c" dependencies = [ "anyhow", "libc", @@ -14872,9 +14886,9 @@ dependencies = [ [[package]] name = "wasmparser-nostd" -version = "0.100.1" +version = "0.100.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9157cab83003221bfd385833ab587a039f5d6fa7304854042ba358a3b09e0724" +checksum = "d5a015fe95f3504a94bb1462c717aae75253e39b9dd6c3fb1062c934535c64aa" dependencies = [ "indexmap-nostd", ] @@ -15076,9 +15090,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.69" +version = "0.3.70" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77afa9a11836342370f4817622a2f0f418b134426d91a82dfb48f532d2ec13ef" +checksum = "26fdeaafd9bd129f65e7c031593c24d62186301e0c72c8978fa1678be7d532c0" dependencies = [ "js-sys", "wasm-bindgen", @@ -15105,15 +15119,16 @@ dependencies = [ [[package]] name = "westend-runtime" -version = "8.0.0" +version = "8.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db2a5cebb4c678a0d1291bb21f9d44ddebceae044b0fb5200fa3bed108a31595" +checksum = "b4aa5580861b05668a6af845aa271c4f699a2fc26646d524e5b0d9375fb0647e" dependencies = [ "binary-merkle-tree", "bitvec", "frame-benchmarking", "frame-election-provider-support", "frame-executive", + "frame-metadata-hash-extension", "frame-support", "frame-system", "frame-system-benchmarking", @@ -15236,14 +15251,14 @@ dependencies = [ "either", "home", "once_cell", - "rustix 0.38.32", + "rustix 0.38.34", ] [[package]] name = "wide" -version = "0.7.15" +version = "0.7.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89beec544f246e679fc25490e3f8e08003bc4bf612068f325120dad4cea02c1c" +checksum = "b828f995bf1e9622031f8009f8481a85406ce1f4d4588ff746d872043e855690" dependencies = [ "bytemuck", "safe_arch", @@ -15251,9 +15266,9 @@ dependencies = [ [[package]] name = "widestring" -version = "1.0.2" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "653f141f39ec16bba3c5abe400a0c60da7468261cc2cbf36805022876bc721a8" +checksum = "7219d36b6eac893fa81e84ebe06485e7dcbb616177469b142df14f1f4deb1311" [[package]] name = "winapi" @@ -15273,11 +15288,11 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" -version = "0.1.6" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" +checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" dependencies = [ - "winapi", + "windows-sys 0.59.0", ] [[package]] @@ -15292,7 +15307,7 @@ version = "0.51.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ca229916c5ee38c2f2bc1e9d8f04df975b4bd93f9955dc69fabb5d91270045c9" dependencies = [ - "windows-core", + "windows-core 0.51.1", "windows-targets 0.48.5", ] @@ -15305,6 +15320,15 @@ dependencies = [ "windows-targets 0.48.5", ] +[[package]] +name = "windows-core" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" +dependencies = [ + "windows-targets 0.52.6", +] + [[package]] name = "windows-sys" version = "0.45.0" @@ -15329,7 +15353,16 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets 0.52.4", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets 0.52.6", ] [[package]] @@ -15364,17 +15397,18 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.52.4" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7dd37b7e5ab9018759f893a1952c9420d060016fc19a472b4bb20d1bdd694d1b" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ - "windows_aarch64_gnullvm 0.52.4", - "windows_aarch64_msvc 0.52.4", - "windows_i686_gnu 0.52.4", - "windows_i686_msvc 0.52.4", - "windows_x86_64_gnu 0.52.4", - "windows_x86_64_gnullvm 0.52.4", - "windows_x86_64_msvc 0.52.4", + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", + "windows_i686_gnullvm", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", ] [[package]] @@ -15391,9 +15425,9 @@ checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] name = "windows_aarch64_gnullvm" -version = "0.52.4" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bcf46cf4c365c6f2d1cc93ce535f2c8b244591df96ceee75d8e83deb70a9cac9" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" [[package]] name = "windows_aarch64_msvc" @@ -15409,9 +15443,9 @@ checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] name = "windows_aarch64_msvc" -version = "0.52.4" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da9f259dd3bcf6990b55bffd094c4f7235817ba4ceebde8e6d11cd0c5633b675" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" [[package]] name = "windows_i686_gnu" @@ -15427,9 +15461,15 @@ checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] name = "windows_i686_gnu" -version = "0.52.4" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b474d8268f99e0995f25b9f095bc7434632601028cf86590aea5c8a5cb7801d3" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" [[package]] name = "windows_i686_msvc" @@ -15445,9 +15485,9 @@ checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] name = "windows_i686_msvc" -version = "0.52.4" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1515e9a29e5bed743cb4415a9ecf5dfca648ce85ee42e15873c3cd8610ff8e02" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" [[package]] name = "windows_x86_64_gnu" @@ -15463,9 +15503,9 @@ checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] name = "windows_x86_64_gnu" -version = "0.52.4" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5eee091590e89cc02ad514ffe3ead9eb6b660aedca2183455434b93546371a03" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" [[package]] name = "windows_x86_64_gnullvm" @@ -15481,9 +15521,9 @@ checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] name = "windows_x86_64_gnullvm" -version = "0.52.4" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77ca79f2451b49fa9e2af39f0747fe999fcda4f5e241b2898624dca97a1f2177" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" [[package]] name = "windows_x86_64_msvc" @@ -15499,9 +15539,9 @@ checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] name = "windows_x86_64_msvc" -version = "0.52.4" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32b752e52a2da0ddfbdbcc6fceadfeede4c939ed16d13e648833a61dfb611ed8" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "winnow" @@ -15514,9 +15554,9 @@ dependencies = [ [[package]] name = "winnow" -version = "0.6.5" +version = "0.6.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dffa400e67ed5a4dd237983829e66475f0a4a26938c4b04c21baede6262215b8" +checksum = "68a9bda4691f099d435ad181000724da8e5899daa10713c2d432552b9ccd3a6f" dependencies = [ "memchr", ] @@ -15557,7 +15597,7 @@ version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c7e468321c81fb07fa7f4c636c3972b9100f0346e5b6a9f2bd0603a52f7ed277" dependencies = [ - "curve25519-dalek 4.1.2", + "curve25519-dalek 4.1.3", "rand_core 0.6.4", "serde", "zeroize", @@ -15625,7 +15665,7 @@ dependencies = [ "Inflector", "proc-macro2", "quote", - "syn 2.0.55", + "syn 2.0.74", ] [[package]] @@ -15637,7 +15677,7 @@ dependencies = [ "futures", "log", "nohash-hasher", - "parking_lot 0.12.1", + "parking_lot 0.12.3", "rand", "static_assertions", ] @@ -15653,29 +15693,30 @@ dependencies = [ [[package]] name = "zerocopy" -version = "0.7.32" +version = "0.7.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be" +checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" dependencies = [ + "byteorder", "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.7.32" +version = "0.7.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" +checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.55", + "syn 2.0.74", ] [[package]] name = "zeroize" -version = "1.7.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" +checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" dependencies = [ "zeroize_derive", ] @@ -15688,7 +15729,7 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.55", + "syn 2.0.74", ] [[package]] @@ -15731,9 +15772,9 @@ dependencies = [ [[package]] name = "zstd-sys" -version = "2.0.9+zstd.1.5.5" +version = "2.0.13+zstd.1.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e16efa8a874a0481a574084d34cc26fdb3b99627480f785888deb6386506656" +checksum = "38ff0f21cfee8f97d94cef41359e0c89aa6113028ab0291aa8ca0038995a95aa" dependencies = [ "cc", "pkg-config", From 545bd334dac38a1b7bf28e5be6c7de7822672c8a Mon Sep 17 00:00:00 2001 From: Daanvdplas Date: Tue, 13 Aug 2024 13:33:12 +0200 Subject: [PATCH 037/112] fix: try-runtime error --- runtime/devnet/Cargo.toml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/runtime/devnet/Cargo.toml b/runtime/devnet/Cargo.toml index 5f83d991..87dce79e 100644 --- a/runtime/devnet/Cargo.toml +++ b/runtime/devnet/Cargo.toml @@ -202,6 +202,7 @@ try-runtime = [ "frame-support/try-runtime", "frame-system/try-runtime", "frame-try-runtime/try-runtime", + "pallet-api/try-runtime", "pallet-aura/try-runtime", "pallet-authorship/try-runtime", "pallet-assets/try-runtime", @@ -224,4 +225,4 @@ try-runtime = [ "parachain-info/try-runtime", "polkadot-runtime-common/try-runtime", "sp-runtime/try-runtime", -] \ No newline at end of file +] From 99d0f6d76aaac6d366ae62a68983ea0878840685 Mon Sep 17 00:00:00 2001 From: Tin Chung <56880684+chungquantin@users.noreply.github.com> Date: Tue, 13 Aug 2024 23:00:33 +0700 Subject: [PATCH 038/112] refactor: generic extension crate to de-duplicate code between runtimes (#163) --- Cargo.lock | 17 + Cargo.toml | 26 +- extension/Cargo.toml | 51 ++ extension/src/lib.rs | 323 ++++++++++++ extension/src/tests.rs | 135 +++++ .../src/extensions => extension/src}/v0.rs | 4 +- runtime/devnet/Cargo.toml | 2 + runtime/devnet/src/config/api.rs | 57 ++- runtime/devnet/src/config/contracts.rs | 7 +- runtime/devnet/src/extensions/mod.rs | 480 ------------------ runtime/devnet/src/lib.rs | 1 - 11 files changed, 583 insertions(+), 520 deletions(-) create mode 100644 extension/Cargo.toml create mode 100644 extension/src/lib.rs create mode 100644 extension/src/tests.rs rename {runtime/devnet/src/extensions => extension/src}/v0.rs (98%) delete mode 100644 runtime/devnet/src/extensions/mod.rs diff --git a/Cargo.lock b/Cargo.lock index 7f033a20..78e5e1d1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -9460,6 +9460,22 @@ dependencies = [ "universal-hash", ] +[[package]] +name = "pop-chain-extension" +version = "0.1.0" +dependencies = [ + "frame-support", + "frame-system", + "log", + "pallet-contracts", + "parity-scale-codec", + "pop-primitives", + "rand", + "sp-core", + "sp-runtime", + "sp-std", +] + [[package]] name = "pop-node" version = "0.1.0-alpha" @@ -9594,6 +9610,7 @@ dependencies = [ "parity-scale-codec", "polkadot-parachain-primitives", "polkadot-runtime-common", + "pop-chain-extension", "pop-primitives", "pop-runtime-common", "rand", diff --git a/Cargo.toml b/Cargo.toml index d082e838..f037f6b7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,18 +23,19 @@ members = [ "pallets/*", "primitives", ] -exclude = [ - "pop-api", - "tests/contracts" -] +exclude = ["pop-api", "tests/contracts"] resolver = "2" [workspace.dependencies] -codec = { package = "parity-scale-codec", version = "3.0.0", default-features = false, features = ["derive"] } +codec = { package = "parity-scale-codec", version = "3.0.0", default-features = false, features = [ + "derive", +] } hex-literal = "0.4.1" log = { version = "0.4.20", default-features = false } -scale-info = { version = "2.10.0", default-features = false, features = ["derive"] } +scale-info = { version = "2.10.0", default-features = false, features = [ + "derive", +] } smallvec = "1.11.0" serde = "1.0.195" clap = { version = "4.4.18", features = ["derive"] } @@ -52,7 +53,8 @@ substrate-build-script-utils = "11.0.0" # Local pallet-api = { path = "pallets/api", default-features = false } -pop-runtime-devnet = { path = "runtime/devnet", default-features = true } # default-features=true required for `-p pop-node` builds +pop-chain-extension = { path = "./extension", default-features = false } +pop-runtime-devnet = { path = "runtime/devnet", default-features = true } # default-features=true required for `-p pop-node` builds pop-runtime-testnet = { path = "runtime/testnet", default-features = true } # default-features=true required for `-p pop-node` builds pop-runtime-common = { path = "runtime/common", default-features = false } pop-primitives = { path = "./primitives", default-features = false } @@ -82,7 +84,9 @@ frame-system = { version = "29.0.0", default-features = false } frame-system-benchmarking = { version = "29.0.0", default-features = false } frame-system-rpc-runtime-api = { version = "27.0.0", default-features = false } frame-try-runtime = { version = "0.35.0", default-features = false } -pallet-aura = { version = "28.0.0", default-features = false, features = ["experimental"] } +pallet-aura = { version = "28.0.0", default-features = false, features = [ + "experimental", +] } pallet-authorship = { version = "29.0.0", default-features = false } pallet-assets = { version = "30.0.0", default-features = false } pallet-balances = { version = "29.0.2", default-features = false } @@ -139,7 +143,9 @@ xcm-executor = { package = "staging-xcm-executor", version = "8.0.2", default-fe # Cumulus asset-test-utils = { version = "8.0.1", default-features = false } cumulus-pallet-aura-ext = { version = "0.8.0", default-features = false } -cumulus-pallet-parachain-system = { version = "0.8.1", default-features = false, features = ["parameterized-consensus-hook"] } +cumulus-pallet-parachain-system = { version = "0.8.1", default-features = false, features = [ + "parameterized-consensus-hook", +] } cumulus-pallet-session-benchmarking = { version = "10.0.0", default-features = false } cumulus-pallet-xcm = { version = "0.8.0", default-features = false } cumulus-pallet-xcmp-queue = { version = "0.8.0", default-features = false } @@ -163,4 +169,4 @@ cumulus-client-service = "0.8.0" # Paseo asset-hub-paseo-runtime = { git = "https://github.com/paseo-network/runtimes/", tag = "v1.2.5-system-chains", default-features = false } paseo-runtime = { git = "https://github.com/paseo-network/runtimes/", tag = "v1.2.5-system-chains", default-features = false } -paseo-runtime-constants = { git = "https://github.com/paseo-network/runtimes/", tag = "v1.2.5-system-chains", default-features = false } \ No newline at end of file +paseo-runtime-constants = { git = "https://github.com/paseo-network/runtimes/", tag = "v1.2.5-system-chains", default-features = false } diff --git a/extension/Cargo.toml b/extension/Cargo.toml new file mode 100644 index 00000000..03b4221a --- /dev/null +++ b/extension/Cargo.toml @@ -0,0 +1,51 @@ +[package] +name = "pop-chain-extension" +version = "0.1.0" +authors.workspace = true +description.workspace = true +license.workspace = true +homepage.workspace = true +repository.workspace = true +edition.workspace = true +publish = false + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + +[dependencies] +codec.workspace = true +log.workspace = true + +# Local +pop-primitives.workspace = true + +# Substrate +frame-support.workspace = true +frame-system.workspace = true +pallet-contracts.workspace = true +sp-core.workspace = true +sp-runtime.workspace = true +sp-std.workspace = true + +[dev-dependencies] +rand = "0.8.5" + +[features] +default = ["std"] +std = [ + "log/std", + "codec/std", + "frame-support/std", + "frame-system/std", + "pallet-contracts/std", + "pop-primitives/std", + "sp-runtime/std", + "sp-core/std", + "sp-std/std", +] +runtime-benchmarks = [ + "frame-support/runtime-benchmarks", + "frame-system/runtime-benchmarks", + "pallet-contracts/runtime-benchmarks", + "sp-runtime/runtime-benchmarks", +] diff --git a/extension/src/lib.rs b/extension/src/lib.rs new file mode 100644 index 00000000..582f346c --- /dev/null +++ b/extension/src/lib.rs @@ -0,0 +1,323 @@ +#![cfg_attr(not(feature = "std"), no_std)] + +#[cfg(test)] +mod tests; +mod v0; + +use codec::Encode; +use frame_support::{ + dispatch::{GetDispatchInfo, PostDispatchInfo}, + pallet_prelude::*, + traits::OriginTrait, +}; +use frame_system::RawOrigin; +use pallet_contracts::chain_extension::{ + BufInBufOutState, ChainExtension, Environment, Ext, InitState, RetVal, +}; +use sp_core::crypto::UncheckedFrom; +use sp_runtime::{traits::Dispatchable, DispatchError}; +use sp_std::vec::Vec; + +/// Logging target for categorizing messages from the Pop API extension module. +const LOG_TARGET: &str = "pop-api::extension"; + +const DECODING_FAILED_ERROR: DispatchError = DispatchError::Other("DecodingFailed"); +// TODO: issue #93, we can also encode the `pop_primitives::Error::UnknownCall` which means we do use +// `Error` in the runtime and it should stay in primitives. Perhaps issue #91 will also influence +// here. Should be looked at together. +const DECODING_FAILED_ERROR_ENCODED: [u8; 4] = [255u8, 0, 0, 0]; +const UNKNOWN_CALL_ERROR: DispatchError = DispatchError::Other("UnknownCall"); +// TODO: see above. +const UNKNOWN_CALL_ERROR_ENCODED: [u8; 4] = [254u8, 0, 0, 0]; + +type ContractSchedule = ::Schedule; + +/// Type of the state reader. +pub trait ReadState { + /// Query of the state read operations. + type StateQuery: Decode; + + /// Check if a state query is allowed. + fn contains(c: &Self::StateQuery) -> bool; + + /// Reads state using the provided query, returning the result as a byte vector. + fn read(read: Self::StateQuery) -> Vec; + + /// Decodes parameters into state query. + fn decode(params: &mut &[u8]) -> Result { + decode_checked(params) + } +} + +/// Type of the dispatch call filter. +pub trait CallFilter { + /// Query of the dispatch calls operations. + type Call: Decode; + + /// Check if runtime call is allowed. + fn contains(t: &Self::Call) -> bool; +} + +/// Pop API chain extension. +#[derive(Default)] +pub struct ApiExtension(PhantomData); + +impl ChainExtension for ApiExtension +where + T: pallet_contracts::Config + + frame_system::Config< + RuntimeCall: GetDispatchInfo + Dispatchable, + >, + T::AccountId: UncheckedFrom + AsRef<[u8]>, + // Bound the type by the two traits which need to be implemented by the runtime. + I: ReadState + CallFilter::RuntimeCall> + 'static, +{ + fn call>( + &mut self, + env: Environment, + ) -> Result { + log::debug!(target:LOG_TARGET, " extension called "); + let mut env = env.buf_in_buf_out(); + // Charge weight for making a call from a contract to the runtime. + // `debug_message` weight is a good approximation of the additional overhead of going + // from contract layer to substrate layer. + // reference: https://github.com/paritytech/ink-examples/blob/b8d2caa52cf4691e0ddd7c919e4462311deb5ad0/psp22-extension/runtime/psp22-extension-example.rs#L236 + let contract_host_weight = ContractSchedule::::get().host_fn_weights; + env.charge_weight(contract_host_weight.debug_message)?; + + let (version, function_id, pallet_index, call_index) = extract_env(&env); + + let result = match FuncId::try_from(function_id) { + // Read encoded parameters from buffer and calculate weight for reading `len` bytes`. + Ok(function_id) => { + // reference: https://github.com/paritytech/polkadot-sdk/blob/117a9433dac88d5ac00c058c9b39c511d47749d2/substrate/frame/contracts/src/wasm/runtime.rs#L267 + let len = env.in_len(); + env.charge_weight(contract_host_weight.return_per_byte.saturating_mul(len.into()))?; + let params = env.read(len)?; + match function_id { + FuncId::Dispatch => { + dispatch::(&mut env, version, pallet_index, call_index, params) + }, + FuncId::ReadState => { + read_state::(&mut env, version, pallet_index, call_index, params) + }, + } + }, + Err(e) => Err(e), + }; + + match result { + Ok(_) => Ok(RetVal::Converging(0)), + Err(e) => Ok(RetVal::Converging(convert_to_status_code(e, version))), + } + } +} + +/// Extract (version, function_id, pallet_index, call_index) from the payload bytes. +fn extract_env>(env: &Environment) -> (u8, u8, u8, u8) { + // Extract version and function_id from first two bytes. + let (version, function_id) = { + let bytes = env.func_id().to_le_bytes(); + (bytes[0], bytes[1]) + }; + // Extract pallet index and call / key index from last two bytes. + let (pallet_index, call_index) = { + let bytes = env.ext_id().to_le_bytes(); + (bytes[0], bytes[1]) + }; + + (version, function_id, pallet_index, call_index) +} + +fn read_state, StateReader: ReadState>( + env: &mut Environment, + version: u8, + pallet_index: u8, + call_index: u8, + mut params: Vec, +) -> Result<(), DispatchError> { + const LOG_PREFIX: &str = " read_state |"; + + // Prefix params with version, pallet, index to simplify decoding. + params.insert(0, version); + params.insert(1, pallet_index); + params.insert(2, call_index); + let (mut encoded_version, mut encoded_read) = (¶ms[..1], ¶ms[1..]); + let version = decode_checked::(&mut encoded_version)?; + + // Charge weight for doing one storage read. + env.charge_weight(T::DbWeight::get().reads(1_u64))?; + let result = match version { + VersionedStateRead::V0 => { + let read = StateReader::decode(&mut encoded_read)?; + ensure!(StateReader::contains(&read), UNKNOWN_CALL_ERROR); + StateReader::read(read) + }, + }; + log::trace!( + target:LOG_TARGET, + "{} result: {:?}.", LOG_PREFIX, result + ); + env.write(&result, false, None) +} + +fn dispatch( + env: &mut Environment, + version: u8, + pallet_index: u8, + call_index: u8, + mut params: Vec, +) -> Result<(), DispatchError> +where + T: frame_system::Config< + RuntimeCall: GetDispatchInfo + Dispatchable, + >, + E: Ext, + Filter: CallFilter::RuntimeCall> + 'static, +{ + const LOG_PREFIX: &str = " dispatch |"; + + // Prefix params with version, pallet, index to simplify decoding. + params.insert(0, version); + params.insert(1, pallet_index); + params.insert(2, call_index); + let call = decode_checked::>(&mut ¶ms[..])?; + // Contract is the origin by default. + let origin: T::RuntimeOrigin = RawOrigin::Signed(env.ext().address().clone()).into(); + match call { + VersionedDispatch::V0(call) => dispatch_call::(env, call, origin, LOG_PREFIX), + } +} + +/// Helper method to decode the byte data to a provided type and throws error if failed. +fn decode_checked(params: &mut &[u8]) -> Result { + T::decode(params).map_err(|_| DECODING_FAILED_ERROR) +} + +fn dispatch_call( + env: &mut Environment, + call: T::RuntimeCall, + mut origin: T::RuntimeOrigin, + log_prefix: &str, +) -> Result<(), DispatchError> +where + T: frame_system::Config< + RuntimeCall: GetDispatchInfo + Dispatchable, + >, + E: Ext, + Filter: CallFilter::RuntimeCall> + 'static, +{ + let charged_dispatch_weight = env.charge_weight(call.get_dispatch_info().weight)?; + log::debug!(target:LOG_TARGET, "{} Inputted RuntimeCall: {:?}", log_prefix, call); + origin.add_filter(Filter::contains); + match call.dispatch(origin) { + Ok(info) => { + log::debug!(target:LOG_TARGET, "{} success, actual weight: {:?}", log_prefix, info.actual_weight); + // Refund weight if the actual weight is less than the charged weight. + if let Some(actual_weight) = info.actual_weight { + env.adjust_weight(charged_dispatch_weight, actual_weight); + } + Ok(()) + }, + Err(err) => { + log::debug!(target:LOG_TARGET, "{} failed: error: {:?}", log_prefix, err.error); + Err(err.error) + }, + } +} + +/// Wrapper to enable versioning of runtime state reads. +#[derive(Decode, Debug)] +enum VersionedStateRead { + /// Version zero of state reads. + #[codec(index = 0)] + V0, +} + +/// Wrapper to enable versioning of runtime calls. +#[derive(Decode, Debug)] +enum VersionedDispatch { + /// Version zero of dispatch calls. + #[codec(index = 0)] + V0(RuntimeCall), +} + +/// Function identifiers used in the Pop API. +/// +/// The `FuncId` specifies the available functions that can be called through the Pop API. Each +/// variant corresponds to a specific functionality provided by the API, facilitating the +/// interaction between smart contracts and the runtime. +#[derive(Debug)] +pub enum FuncId { + /// Represents a function call to dispatch a runtime call. + Dispatch, + /// Represents a function call to read the state from the runtime. + ReadState, +} + +impl TryFrom for FuncId { + type Error = DispatchError; + + /// Attempts to convert a `u8` value to its corresponding `FuncId` variant. + /// + /// If the `u8` value does not match any known function identifier, it returns a + /// `DispatchError::Other` indicating an unknown function ID. + fn try_from(func_id: u8) -> Result { + let id = match func_id { + 0 => Self::Dispatch, + 1 => Self::ReadState, + _ => { + return Err(UNKNOWN_CALL_ERROR); + }, + }; + Ok(id) + } +} + +/// Converts a `DispatchError` to a `u32` status code based on the version of the API the contract uses. +/// The contract calling the chain extension can convert the status code to the descriptive `Error`. +/// +/// For `Error` see `pop_primitives::::error::Error`. +/// +/// The error encoding can vary per version, allowing for flexible and backward-compatible error handling. +/// As a result, contracts maintain compatibility across different versions of the runtime. +/// +/// # Parameters +/// +/// - `error`: The `DispatchError` encountered during contract execution. +/// - `version`: The version of the chain extension, used to determine the known errors. +pub(crate) fn convert_to_status_code(error: DispatchError, version: u8) -> u32 { + let mut encoded_error: [u8; 4] = match error { + // "UnknownCall" and "DecodingFailed" are mapped to specific errors in the API and will + // never change. + UNKNOWN_CALL_ERROR => UNKNOWN_CALL_ERROR_ENCODED, + DECODING_FAILED_ERROR => DECODING_FAILED_ERROR_ENCODED, + _ => { + let mut encoded_error = error.encode(); + // Resize the encoded value to 4 bytes in order to decode the value in a u32 (4 bytes). + encoded_error.resize(4, 0); + encoded_error.try_into().expect("qed, resized to 4 bytes line above") + }, + }; + match version { + // If an unknown variant of the `DispatchError` is detected the error needs to be converted + // into the encoded value of `Error::Other`. This conversion is performed by shifting the bytes one + // position forward (discarding the last byte as it is not used) and setting the first byte to the + // encoded value of `Other` (0u8). This ensures the error is correctly categorized as an `Other` + // variant which provides all the necessary information to debug which error occurred in the runtime. + // + // Byte layout explanation: + // - Byte 0: index of the variant within `Error` + // - Byte 1: + // - Must be zero for `UNIT_ERRORS`. + // - Represents the nested error in `SINGLE_NESTED_ERRORS`. + // - Represents the first level of nesting in `DOUBLE_NESTED_ERRORS`. + // - Byte 2: + // - Represents the second level of nesting in `DOUBLE_NESTED_ERRORS`. + // - Byte 3: + // - Unused or represents further nested information. + 0 => v0::handle_unknown_error(&mut encoded_error), + _ => encoded_error = UNKNOWN_CALL_ERROR_ENCODED, + } + u32::from_le_bytes(encoded_error) +} diff --git a/extension/src/tests.rs b/extension/src/tests.rs new file mode 100644 index 00000000..a47feef9 --- /dev/null +++ b/extension/src/tests.rs @@ -0,0 +1,135 @@ +use codec::{Decode, Encode}; + +// Test ensuring `func_id()` and `ext_id()` work as expected, i.e. extracting the first two +// bytes and the last two bytes, respectively, from a 4 byte array. +#[test] +fn test_byte_extraction() { + use rand::Rng; + + // Helper functions + fn func_id(id: u32) -> u16 { + (id & 0x0000FFFF) as u16 + } + fn ext_id(id: u32) -> u16 { + (id >> 16) as u16 + } + + // Number of test iterations + let test_iterations = 1_000_000; + + // Create a random number generator + let mut rng = rand::thread_rng(); + + // Run the test for a large number of random 4-byte arrays + for _ in 0..test_iterations { + // Generate a random 4-byte array + let bytes: [u8; 4] = rng.gen(); + + // Convert the 4-byte array to a u32 value + let value = u32::from_le_bytes(bytes); + + // Extract the first two bytes (least significant 2 bytes) + let first_two_bytes = func_id(value); + + // Extract the last two bytes (most significant 2 bytes) + let last_two_bytes = ext_id(value); + + // Check if the first two bytes match the expected value + assert_eq!([bytes[0], bytes[1]], first_two_bytes.to_le_bytes()); + + // Check if the last two bytes match the expected value + assert_eq!([bytes[2], bytes[3]], last_two_bytes.to_le_bytes()); + } +} + +// Test showing all the different type of variants and its encoding. +#[test] +fn encoding_of_enum() { + #[derive(Debug, PartialEq, Encode, Decode)] + enum ComprehensiveEnum { + SimpleVariant, + DataVariant(u8), + NamedFields { w: u8 }, + NestedEnum(InnerEnum), + OptionVariant(Option), + VecVariant(Vec), + TupleVariant(u8, u8), + NestedStructVariant(NestedStruct), + NestedEnumStructVariant(NestedEnumStruct), + } + + #[derive(Debug, PartialEq, Encode, Decode)] + enum InnerEnum { + A, + B { inner_data: u8 }, + C(u8), + } + + #[derive(Debug, PartialEq, Encode, Decode)] + struct NestedStruct { + x: u8, + y: u8, + } + + #[derive(Debug, PartialEq, Encode, Decode)] + struct NestedEnumStruct { + inner_enum: InnerEnum, + } + + // Creating each possible variant for an enum. + let enum_simple = ComprehensiveEnum::SimpleVariant; + let enum_data = ComprehensiveEnum::DataVariant(42); + let enum_named = ComprehensiveEnum::NamedFields { w: 42 }; + let enum_nested = ComprehensiveEnum::NestedEnum(InnerEnum::B { inner_data: 42 }); + let enum_option = ComprehensiveEnum::OptionVariant(Some(42)); + let enum_vec = ComprehensiveEnum::VecVariant(vec![1, 2, 3, 4, 5]); + let enum_tuple = ComprehensiveEnum::TupleVariant(42, 42); + let enum_nested_struct = ComprehensiveEnum::NestedStructVariant(NestedStruct { x: 42, y: 42 }); + let enum_nested_enum_struct = ComprehensiveEnum::NestedEnumStructVariant(NestedEnumStruct { + inner_enum: InnerEnum::C(42), + }); + + // Encode and print each variant individually to see their encoded values. + println!("{:?} -> {:?}", enum_simple, enum_simple.encode()); + println!("{:?} -> {:?}", enum_data, enum_data.encode()); + println!("{:?} -> {:?}", enum_named, enum_named.encode()); + println!("{:?} -> {:?}", enum_nested, enum_nested.encode()); + println!("{:?} -> {:?}", enum_option, enum_option.encode()); + println!("{:?} -> {:?}", enum_vec, enum_vec.encode()); + println!("{:?} -> {:?}", enum_tuple, enum_tuple.encode()); + println!("{:?} -> {:?}", enum_nested_struct, enum_nested_struct.encode()); + println!("{:?} -> {:?}", enum_nested_enum_struct, enum_nested_enum_struct.encode()); +} + +#[test] +fn encoding_decoding_dispatch_error() { + use sp_runtime::{ArithmeticError, DispatchError, ModuleError, TokenError}; + + let error = DispatchError::Module(ModuleError { + index: 255, + error: [2, 0, 0, 0], + message: Some("error message"), + }); + let encoded = error.encode(); + let decoded = DispatchError::decode(&mut &encoded[..]).unwrap(); + assert_eq!(encoded, vec![3, 255, 2, 0, 0, 0]); + assert_eq!( + decoded, + // `message` is skipped for encoding. + DispatchError::Module(ModuleError { index: 255, error: [2, 0, 0, 0], message: None }) + ); + + // Example DispatchError::Token + let error = DispatchError::Token(TokenError::UnknownAsset); + let encoded = error.encode(); + let decoded = DispatchError::decode(&mut &encoded[..]).unwrap(); + assert_eq!(encoded, vec![7, 4]); + assert_eq!(decoded, error); + + // Example DispatchError::Arithmetic + let error = DispatchError::Arithmetic(ArithmeticError::Overflow); + let encoded = error.encode(); + let decoded = DispatchError::decode(&mut &encoded[..]).unwrap(); + assert_eq!(encoded, vec![8, 1]); + assert_eq!(decoded, error); +} diff --git a/runtime/devnet/src/extensions/v0.rs b/extension/src/v0.rs similarity index 98% rename from runtime/devnet/src/extensions/v0.rs rename to extension/src/v0.rs index 72760323..4c3536a4 100644 --- a/runtime/devnet/src/extensions/v0.rs +++ b/extension/src/v0.rs @@ -1,5 +1,5 @@ #[cfg(test)] -use crate::extensions::convert_to_status_code; +use crate::convert_to_status_code; pub(crate) fn handle_unknown_error(encoded_error: &mut [u8; 4]) { let unknown = match encoded_error[0] { @@ -106,7 +106,7 @@ mod tests { (DispatchError::RootNotAllowed, RootNotAllowed), ]; for (dispatch_error, expected) in test_cases { - let status_code = crate::extensions::convert_to_status_code(dispatch_error, 0); + let status_code = crate::convert_to_status_code(dispatch_error, 0); let error: Error = status_code.into(); assert_eq!(error, expected); } diff --git a/runtime/devnet/Cargo.toml b/runtime/devnet/Cargo.toml index 87dce79e..995af269 100644 --- a/runtime/devnet/Cargo.toml +++ b/runtime/devnet/Cargo.toml @@ -22,6 +22,7 @@ scale-info.workspace = true smallvec.workspace = true # Local +pop-chain-extension.workspace = true pop-primitives.workspace = true pop-runtime-common.workspace = true pallet-api.workspace = true @@ -139,6 +140,7 @@ std = [ "parachains-common/std", "polkadot-parachain-primitives/std", "polkadot-runtime-common/std", + "pop-chain-extension/std", "pop-primitives/std", "scale-info/std", "sp-api/std", diff --git a/runtime/devnet/src/config/api.rs b/runtime/devnet/src/config/api.rs index bdff6bbb..5f234cd4 100644 --- a/runtime/devnet/src/config/api.rs +++ b/runtime/devnet/src/config/api.rs @@ -1,22 +1,47 @@ use crate::{config::assets::TrustBackedAssetsInstance, fungibles, Runtime, RuntimeCall}; use codec::{Decode, Encode, MaxEncodedLen}; -use frame_support::traits::Contains; +use pop_chain_extension::{CallFilter, ReadState}; +use sp_std::vec::Vec; /// A query of runtime state. #[derive(Encode, Decode, Debug, MaxEncodedLen)] #[repr(u8)] -pub enum RuntimeRead { +pub enum RuntimeRead { /// Fungible token queries. #[codec(index = 150)] - Fungibles(fungibles::Read), + Fungibles(fungibles::Read), } -/// A type to identify allowed calls to the Runtime from the API. -pub struct AllowedApiCalls; +/// A struct that implement requirements for the Pop API chain extension. +#[derive(Default)] +pub struct Extension; +impl ReadState for Extension { + type StateQuery = RuntimeRead; -impl Contains for AllowedApiCalls { - /// Allowed runtime calls from the API. - fn contains(c: &RuntimeCall) -> bool { + fn contains(c: &Self::StateQuery) -> bool { + use fungibles::Read::*; + matches!( + c, + RuntimeRead::Fungibles( + TotalSupply(..) + | BalanceOf { .. } | Allowance { .. } + | TokenName(..) | TokenSymbol(..) + | TokenDecimals(..) | AssetExists(..) + ) + ) + } + + fn read(read: RuntimeRead) -> Vec { + match read { + RuntimeRead::Fungibles(key) => fungibles::Pallet::read_state(key), + } + } +} + +impl CallFilter for Extension { + type Call = RuntimeCall; + + fn contains(c: &Self::Call) -> bool { use fungibles::Call::*; matches!( c, @@ -34,22 +59,6 @@ impl Contains for AllowedApiCalls { } } -impl Contains> for AllowedApiCalls { - /// Allowed state queries from the API. - fn contains(c: &RuntimeRead) -> bool { - use fungibles::Read::*; - matches!( - c, - RuntimeRead::Fungibles( - TotalSupply(..) - | BalanceOf { .. } | Allowance { .. } - | TokenName(..) | TokenSymbol(..) - | TokenDecimals(..) | AssetExists(..) - ) - ) - } -} - impl fungibles::Config for Runtime { type AssetsInstance = TrustBackedAssetsInstance; type WeightInfo = fungibles::weights::SubstrateWeight; diff --git a/runtime/devnet/src/config/contracts.rs b/runtime/devnet/src/config/contracts.rs index 36d62f7f..5dc613b5 100644 --- a/runtime/devnet/src/config/contracts.rs +++ b/runtime/devnet/src/config/contracts.rs @@ -1,6 +1,7 @@ +use super::api::Extension; use crate::{ - deposit, extensions, Balance, Balances, BalancesCall, Perbill, Runtime, RuntimeCall, - RuntimeEvent, RuntimeHoldReason, Timestamp, + deposit, Balance, Balances, BalancesCall, Perbill, Runtime, RuntimeCall, RuntimeEvent, + RuntimeHoldReason, Timestamp, }; use frame_support::{ parameter_types, @@ -63,7 +64,7 @@ impl pallet_contracts::Config for Runtime { type CallStack = [pallet_contracts::Frame; 23]; type WeightPrice = pallet_transaction_payment::Pallet; type WeightInfo = pallet_contracts::weights::SubstrateWeight; - type ChainExtension = extensions::PopApiExtension; + type ChainExtension = pop_chain_extension::ApiExtension; type Schedule = Schedule; type AddressGenerator = pallet_contracts::DefaultAddressGenerator; // This node is geared towards development and testing of contracts. diff --git a/runtime/devnet/src/extensions/mod.rs b/runtime/devnet/src/extensions/mod.rs deleted file mode 100644 index d3bbdd0b..00000000 --- a/runtime/devnet/src/extensions/mod.rs +++ /dev/null @@ -1,480 +0,0 @@ -mod v0; - -use crate::{ - config::{ - api::{AllowedApiCalls, RuntimeRead}, - assets::TrustBackedAssetsInstance, - }, - fungibles::{self}, - AccountId, RuntimeCall, RuntimeOrigin, -}; -use codec::{Decode, Encode}; -use frame_support::{ - dispatch::{GetDispatchInfo, RawOrigin}, - pallet_prelude::*, - traits::{Contains, OriginTrait}, -}; -use pallet_contracts::chain_extension::{ - BufInBufOutState, ChainExtension, Environment, Ext, InitState, RetVal, -}; -use pop_primitives::AssetId; -use sp_core::crypto::UncheckedFrom; -use sp_runtime::{traits::Dispatchable, DispatchError}; -use sp_std::vec::Vec; - -const LOG_TARGET: &str = "pop-api::extension"; -const DECODING_FAILED_ERROR: DispatchError = DispatchError::Other("DecodingFailed"); -// TODO: issue #93, we can also encode the `pop_primitives::Error::UnknownCall` which means we do use -// `Error` in the runtime and it should stay in primitives. Perhaps issue #91 will also influence -// here. Should be looked at together. -const DECODING_FAILED_ERROR_ENCODED: [u8; 4] = [255u8, 0, 0, 0]; -const UNKNOWN_CALL_ERROR: DispatchError = DispatchError::Other("UnknownCall"); -// TODO: see above. -const UNKNOWN_CALL_ERROR_ENCODED: [u8; 4] = [254u8, 0, 0, 0]; - -type ContractSchedule = ::Schedule; - -#[derive(Default)] -pub struct PopApiExtension; - -impl ChainExtension for PopApiExtension -where - T: pallet_contracts::Config - + pallet_assets::Config - + fungibles::Config - + frame_system::Config< - RuntimeOrigin = RuntimeOrigin, - AccountId = AccountId, - RuntimeCall = RuntimeCall, - >, - T::AccountId: UncheckedFrom + AsRef<[u8]>, -{ - fn call(&mut self, env: Environment) -> Result - where - E: Ext, - { - log::debug!(target:LOG_TARGET, " extension called "); - let mut env = env.buf_in_buf_out(); - // Charge weight for making a call from a contract to the runtime. - // `debug_message` weight is a good approximation of the additional overhead of going - // from contract layer to substrate layer. - // reference: https://github.com/paritytech/ink-examples/blob/b8d2caa52cf4691e0ddd7c919e4462311deb5ad0/psp22-extension/runtime/psp22-extension-example.rs#L236 - let contract_host_weight = ContractSchedule::::get().host_fn_weights; - env.charge_weight(contract_host_weight.debug_message)?; - - // Extract version and function_id from first two bytes. - let (version, function_id) = { - let bytes = env.func_id().to_le_bytes(); - (bytes[0], bytes[1]) - }; - // Extract pallet index and call / key index from last two bytes. - let (pallet_index, call_index) = { - let bytes = env.ext_id().to_le_bytes(); - (bytes[0], bytes[1]) - }; - - let result = match FuncId::try_from(function_id) { - Ok(function_id) => { - // Read encoded parameters from buffer and calculate weight for reading `len` bytes`. - // reference: https://github.com/paritytech/polkadot-sdk/blob/117a9433dac88d5ac00c058c9b39c511d47749d2/substrate/frame/contracts/src/wasm/runtime.rs#L267 - let len = env.in_len(); - env.charge_weight(contract_host_weight.return_per_byte.saturating_mul(len.into()))?; - let params = env.read(len)?; - log::debug!(target: LOG_TARGET, "Read input successfully"); - match function_id { - FuncId::Dispatch => { - dispatch::(&mut env, version, pallet_index, call_index, params) - }, - FuncId::ReadState => { - read_state::(&mut env, version, pallet_index, call_index, params) - }, - } - }, - Err(e) => Err(e), - }; - - match result { - Ok(_) => Ok(RetVal::Converging(0)), - Err(e) => Ok(RetVal::Converging(convert_to_status_code(e, version))), - } - } -} - -fn dispatch( - env: &mut Environment, - version: u8, - pallet_index: u8, - call_index: u8, - mut params: Vec, -) -> Result<(), DispatchError> -where - T: frame_system::Config, - RuntimeOrigin: From>, - E: Ext, -{ - const LOG_PREFIX: &str = " dispatch |"; - - // Prefix params with version, pallet, index to simplify decoding. - params.insert(0, version); - params.insert(1, pallet_index); - params.insert(2, call_index); - let call = ::decode(&mut ¶ms[..]).map_err(|_| DECODING_FAILED_ERROR)?; - - // Contract is the origin by default. - let origin: RuntimeOrigin = RawOrigin::Signed(env.ext().address().clone()).into(); - match call { - VersionedDispatch::V0(call) => dispatch_call::(env, call, origin, LOG_PREFIX), - } -} - -fn dispatch_call( - env: &mut Environment, - call: RuntimeCall, - mut origin: RuntimeOrigin, - log_prefix: &str, -) -> Result<(), DispatchError> -where - T: frame_system::Config, - RuntimeOrigin: From>, - E: Ext, -{ - let charged_dispatch_weight = env.charge_weight(call.get_dispatch_info().weight)?; - log::debug!(target:LOG_TARGET, "{} Inputted RuntimeCall: {:?}", log_prefix, call); - origin.add_filter(AllowedApiCalls::contains); - match call.dispatch(origin) { - Ok(info) => { - log::debug!(target:LOG_TARGET, "{} success, actual weight: {:?}", log_prefix, info.actual_weight); - // Refund weight if the actual weight is less than the charged weight. - if let Some(actual_weight) = info.actual_weight { - env.adjust_weight(charged_dispatch_weight, actual_weight); - } - Ok(()) - }, - Err(err) => { - log::debug!(target:LOG_TARGET, "{} failed: error: {:?}", log_prefix, err.error); - Err(err.error) - }, - } -} - -fn read_state( - env: &mut Environment, - version: u8, - pallet_index: u8, - call_index: u8, - mut params: Vec, -) -> Result<(), DispatchError> -where - T: pallet_contracts::Config - + pallet_assets::Config - + fungibles::Config - + frame_system::Config, - E: Ext, -{ - const LOG_PREFIX: &str = " read_state |"; - - // Prefix params with version, pallet, index to simplify decoding, and decode parameters for - // reading state. - params.insert(0, version); - params.insert(1, pallet_index); - params.insert(2, call_index); - let read = - >::decode(&mut ¶ms[..]).map_err(|_| DECODING_FAILED_ERROR)?; - - // Charge weight for doing one storage read. - env.charge_weight(T::DbWeight::get().reads(1_u64))?; - let result = match read { - VersionedStateRead::V0(read) => { - ensure!(AllowedApiCalls::contains(&read), UNKNOWN_CALL_ERROR); - match read { - RuntimeRead::Fungibles(key) => fungibles::Pallet::::read_state(key), - } - }, - }; - log::trace!( - target:LOG_TARGET, - "{} result: {:?}.", LOG_PREFIX, result - ); - env.write(&result, false, None) -} - -/// Wrapper to enable versioning of runtime state reads. -#[derive(Decode, Debug)] -enum VersionedStateRead { - /// Version zero of state reads. - #[codec(index = 0)] - V0(RuntimeRead), -} - -/// Wrapper to enable versioning of runtime calls. -#[derive(Decode, Debug)] -enum VersionedDispatch { - /// Version zero of dispatch calls. - #[codec(index = 0)] - V0(RuntimeCall), -} - -// Converts a `DispatchError` to a `u32` status code based on the version of the API the contract uses. -// The contract calling the chain extension can convert the status code to the descriptive `Error`. -// -// For `Error` see `pop_primitives::::error::Error`. -// -// The error encoding can vary per version, allowing for flexible and backward-compatible error handling. -// As a result, contracts maintain compatibility across different versions of the runtime. -// -// # Parameters -// -// - `error`: The `DispatchError` encountered during contract execution. -// - `version`: The version of the chain extension, used to determine the known errors. -pub(crate) fn convert_to_status_code(error: DispatchError, version: u8) -> u32 { - let mut encoded_error: [u8; 4] = match error { - // "UnknownCall" and "DecodingFailed" are mapped to specific errors in the API and will - // never change. - UNKNOWN_CALL_ERROR => UNKNOWN_CALL_ERROR_ENCODED, - DECODING_FAILED_ERROR => DECODING_FAILED_ERROR_ENCODED, - _ => { - let mut encoded_error = error.encode(); - // Resize the encoded value to 4 bytes in order to decode the value in a u32 (4 bytes). - encoded_error.resize(4, 0); - encoded_error.try_into().expect("qed, resized to 4 bytes line above") - }, - }; - match version { - // If an unknown variant of the `DispatchError` is detected the error needs to be converted - // into the encoded value of `Error::Other`. This conversion is performed by shifting the bytes one - // position forward (discarding the last byte as it is not used) and setting the first byte to the - // encoded value of `Other` (0u8). This ensures the error is correctly categorized as an `Other` - // variant which provides all the necessary information to debug which error occurred in the runtime. - // - // Byte layout explanation: - // - Byte 0: index of the variant within `Error` - // - Byte 1: - // - Must be zero for `UNIT_ERRORS`. - // - Represents the nested error in `SINGLE_NESTED_ERRORS`. - // - Represents the first level of nesting in `DOUBLE_NESTED_ERRORS`. - // - Byte 2: - // - Represents the second level of nesting in `DOUBLE_NESTED_ERRORS`. - // - Byte 3: - // - Unused or represents further nested information. - 0 => v0::handle_unknown_error(&mut encoded_error), - _ => encoded_error = UNKNOWN_CALL_ERROR_ENCODED, - } - u32::from_le_bytes(encoded_error) -} - -/// Function identifiers used in the Pop API. -/// -/// The `FuncId` specifies the available functions that can be called through the Pop API. Each -/// variant corresponds to a specific functionality provided by the API, facilitating the -/// interaction between smart contracts and the runtime. -/// -/// - `Dispatch`: Represents a function call to dispatch a runtime call. -/// - `ReadState`: Represents a function call to read the state from the runtime. -/// - `SendXcm`: Represents a function call to send an XCM message. -#[derive(Debug)] -pub enum FuncId { - Dispatch, - ReadState, -} - -impl TryFrom for FuncId { - type Error = DispatchError; - - /// Attempts to convert a `u8` value to its corresponding `FuncId` variant. - /// - /// If the `u8` value does not match any known function identifier, it returns a - /// `DispatchError::Other` indicating an unknown function ID. - fn try_from(func_id: u8) -> Result { - let id = match func_id { - 0 => Self::Dispatch, - 1 => Self::ReadState, - _ => { - return Err(UNKNOWN_CALL_ERROR); - }, - }; - Ok(id) - } -} - -#[cfg(test)] -mod tests { - use super::*; - use crate::{Assets, Runtime, System}; - use sp_runtime::BuildStorage; - - // Test ensuring `func_id()` and `ext_id()` work as expected, i.e. extracting the first two - // bytes and the last two bytes, respectively, from a 4 byte array. - #[test] - fn test_byte_extraction() { - use rand::Rng; - - // Helper functions - fn func_id(id: u32) -> u16 { - (id & 0x0000FFFF) as u16 - } - fn ext_id(id: u32) -> u16 { - (id >> 16) as u16 - } - - // Number of test iterations - let test_iterations = 1_000_000; - - // Create a random number generator - let mut rng = rand::thread_rng(); - - // Run the test for a large number of random 4-byte arrays - for _ in 0..test_iterations { - // Generate a random 4-byte array - let bytes: [u8; 4] = rng.gen(); - - // Convert the 4-byte array to a u32 value - let value = u32::from_le_bytes(bytes); - - // Extract the first two bytes (least significant 2 bytes) - let first_two_bytes = func_id(value); - - // Extract the last two bytes (most significant 2 bytes) - let last_two_bytes = ext_id(value); - - // Check if the first two bytes match the expected value - assert_eq!([bytes[0], bytes[1]], first_two_bytes.to_le_bytes()); - - // Check if the last two bytes match the expected value - assert_eq!([bytes[2], bytes[3]], last_two_bytes.to_le_bytes()); - } - } - - // Test showing all the different type of variants and its encoding. - #[test] - fn encoding_of_enum() { - #[derive(Debug, PartialEq, Encode, Decode)] - enum ComprehensiveEnum { - SimpleVariant, - DataVariant(u8), - NamedFields { w: u8 }, - NestedEnum(InnerEnum), - OptionVariant(Option), - VecVariant(Vec), - TupleVariant(u8, u8), - NestedStructVariant(NestedStruct), - NestedEnumStructVariant(NestedEnumStruct), - } - - #[derive(Debug, PartialEq, Encode, Decode)] - enum InnerEnum { - A, - B { inner_data: u8 }, - C(u8), - } - - #[derive(Debug, PartialEq, Encode, Decode)] - struct NestedStruct { - x: u8, - y: u8, - } - - #[derive(Debug, PartialEq, Encode, Decode)] - struct NestedEnumStruct { - inner_enum: InnerEnum, - } - - // Creating each possible variant for an enum. - let enum_simple = ComprehensiveEnum::SimpleVariant; - let enum_data = ComprehensiveEnum::DataVariant(42); - let enum_named = ComprehensiveEnum::NamedFields { w: 42 }; - let enum_nested = ComprehensiveEnum::NestedEnum(InnerEnum::B { inner_data: 42 }); - let enum_option = ComprehensiveEnum::OptionVariant(Some(42)); - let enum_vec = ComprehensiveEnum::VecVariant(vec![1, 2, 3, 4, 5]); - let enum_tuple = ComprehensiveEnum::TupleVariant(42, 42); - let enum_nested_struct = - ComprehensiveEnum::NestedStructVariant(NestedStruct { x: 42, y: 42 }); - let enum_nested_enum_struct = - ComprehensiveEnum::NestedEnumStructVariant(NestedEnumStruct { - inner_enum: InnerEnum::C(42), - }); - - // Encode and print each variant individually to see their encoded values. - println!("{:?} -> {:?}", enum_simple, enum_simple.encode()); - println!("{:?} -> {:?}", enum_data, enum_data.encode()); - println!("{:?} -> {:?}", enum_named, enum_named.encode()); - println!("{:?} -> {:?}", enum_nested, enum_nested.encode()); - println!("{:?} -> {:?}", enum_option, enum_option.encode()); - println!("{:?} -> {:?}", enum_vec, enum_vec.encode()); - println!("{:?} -> {:?}", enum_tuple, enum_tuple.encode()); - println!("{:?} -> {:?}", enum_nested_struct, enum_nested_struct.encode()); - println!("{:?} -> {:?}", enum_nested_enum_struct, enum_nested_enum_struct.encode()); - } - - fn new_test_ext() -> sp_io::TestExternalities { - let t = frame_system::GenesisConfig::::default() - .build_storage() - .expect("Frame system builds valid default genesis config"); - let mut ext = sp_io::TestExternalities::new(t); - ext.execute_with(|| System::set_block_number(1)); - ext - } - - #[test] - fn encoding_decoding_dispatch_error() { - use sp_runtime::{ArithmeticError, DispatchError, ModuleError, TokenError}; - - new_test_ext().execute_with(|| { - let error = DispatchError::Module(ModuleError { - index: 255, - error: [2, 0, 0, 0], - message: Some("error message"), - }); - let encoded = error.encode(); - let decoded = DispatchError::decode(&mut &encoded[..]).unwrap(); - assert_eq!(encoded, vec![3, 255, 2, 0, 0, 0]); - assert_eq!( - decoded, - // `message` is skipped for encoding. - DispatchError::Module(ModuleError { - index: 255, - error: [2, 0, 0, 0], - message: None - }) - ); - - // Example pallet assets Error into ModuleError. - let index = <::PalletInfo as frame_support::traits::PalletInfo>::index::< - Assets, - >() - .expect("Every active module has an index in the runtime; qed") as u8; - let mut error = - pallet_assets::Error::NotFrozen::.encode(); - error.resize(MAX_MODULE_ERROR_ENCODED_SIZE, 0); - let error = DispatchError::Module(ModuleError { - index, - error: TryInto::try_into(error).expect("should work"), - message: None, - }); - let encoded = error.encode(); - let decoded = DispatchError::decode(&mut &encoded[..]).unwrap(); - assert_eq!(encoded, vec![3, 52, 18, 0, 0, 0]); - assert_eq!( - decoded, - DispatchError::Module(ModuleError { - index: 52, - error: [18, 0, 0, 0], - message: None - }) - ); - - // Example DispatchError::Token - let error = DispatchError::Token(TokenError::UnknownAsset); - let encoded = error.encode(); - let decoded = DispatchError::decode(&mut &encoded[..]).unwrap(); - assert_eq!(encoded, vec![7, 4]); - assert_eq!(decoded, error); - - // Example DispatchError::Arithmetic - let error = DispatchError::Arithmetic(ArithmeticError::Overflow); - let encoded = error.encode(); - let decoded = DispatchError::decode(&mut &encoded[..]).unwrap(); - assert_eq!(encoded, vec![8, 1]); - assert_eq!(decoded, error); - }); - } -} diff --git a/runtime/devnet/src/lib.rs b/runtime/devnet/src/lib.rs index 130fbb9a..4256ac01 100644 --- a/runtime/devnet/src/lib.rs +++ b/runtime/devnet/src/lib.rs @@ -8,7 +8,6 @@ include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs")); // Public due to integration tests crate. pub mod config; -mod extensions; mod weights; use cumulus_pallet_parachain_system::RelayNumberMonotonicallyIncreases; From 8b4f595fc745804301162a5ed5845837ee524601 Mon Sep 17 00:00:00 2001 From: Daan van der Plas <93204684+Daanvdplas@users.noreply.github.com> Date: Wed, 14 Aug 2024 10:00:49 +0200 Subject: [PATCH 039/112] feat: api events (#153) Co-authored-by: Frank Bell --- pallets/api/src/fungibles/mod.rs | 182 +++++++++++++++++++------ pallets/api/src/fungibles/tests.rs | 211 ++++++++++++++++++----------- pallets/api/src/mock.rs | 1 + pop-api/src/v0/assets/fungibles.rs | 85 ++++++++++++ runtime/devnet/src/config/api.rs | 5 +- 5 files changed, 359 insertions(+), 125 deletions(-) diff --git a/pallets/api/src/fungibles/mod.rs b/pallets/api/src/fungibles/mod.rs index eefad0e1..7aa9ac00 100644 --- a/pallets/api/src/fungibles/mod.rs +++ b/pallets/api/src/fungibles/mod.rs @@ -84,6 +84,8 @@ pub mod pallet { /// Configure the pallet by specifying the parameters and types on which it depends. #[pallet::config] pub trait Config: frame_system::Config + pallet_assets::Config { + /// Because this pallet emits events, it depends on the runtime's definition of an event. + type RuntimeEvent: From> + IsType<::RuntimeEvent>; /// The instance of pallet assets it is tightly coupled to. type AssetsInstance; /// Weight information for dispatchables in this pallet. @@ -93,6 +95,43 @@ pub mod pallet { #[pallet::pallet] pub struct Pallet(_); + /// The events that can be emitted. + #[pallet::event] + #[pallet::generate_deposit(pub(super) fn deposit_event)] + pub enum Event { + /// Event emitted when allowance by `owner` to `spender` changes. + Approval { + /// The ID of the asset. + id: AssetIdOf, + /// Account providing allowance. + owner: AccountIdOf, + /// Allowance beneficiary. + spender: AccountIdOf, + /// New allowance amount. + value: BalanceOf, + }, + /// Event emitted when transfer of tokens occurs. + Transfer { + /// The ID of the asset. + id: AssetIdOf, + /// Transfer sender. `None` in case of minting new tokens. + from: Option>, + /// Transfer recipient. `None` in case of burning tokens. + to: Option>, + /// Amount of tokens transferred (or minted/burned). + value: BalanceOf, + }, + /// Event emitted when a token class is created. + Create { + /// The ID of the asset. + id: AssetIdOf, + /// Creator of the asset. + creator: AccountIdOf, + /// Admin of the asset. + admin: AccountIdOf, + }, + } + #[pallet::call] impl Pallet { /// Transfers `value` amount of tokens from the caller's account to account `to`, with additional @@ -110,8 +149,15 @@ pub mod pallet { to: AccountIdOf, value: BalanceOf, ) -> DispatchResult { - let to = T::Lookup::unlookup(to); - AssetsOf::::transfer_keep_alive(origin, id.into(), to, value) + AssetsOf::::transfer_keep_alive( + origin.clone(), + id.clone().into(), + T::Lookup::unlookup(to.clone()), + value, + )?; + let from = ensure_signed(origin)?; + Self::deposit_event(Event::Transfer { id, from: Some(from), to: Some(to), value }); + Ok(()) } /// Transfers `value` amount tokens on behalf of `from` to account `to` with additional `data` @@ -119,7 +165,7 @@ pub mod pallet { /// /// # Parameters /// - `id` - The ID of the asset. - /// - `owner` - The account from which the asset balance will be withdrawn. + /// - `from` - The account from which the asset balance will be withdrawn. /// - `to` - The recipient account. /// - `value` - The number of tokens to transfer. #[pallet::call_index(4)] @@ -131,9 +177,15 @@ pub mod pallet { to: AccountIdOf, value: BalanceOf, ) -> DispatchResult { - let from = T::Lookup::unlookup(from); - let to = T::Lookup::unlookup(to); - AssetsOf::::transfer_approved(origin, id.into(), from, to, value) + AssetsOf::::transfer_approved( + origin, + id.clone().into(), + T::Lookup::unlookup(from.clone()), + T::Lookup::unlookup(to.clone()), + value, + )?; + Self::deposit_event(Event::Transfer { id, from: Some(from), to: Some(to), value }); + Ok(()) } /// Approves an account to spend a specified number of tokens on behalf of the caller. @@ -150,13 +202,11 @@ pub mod pallet { spender: AccountIdOf, value: BalanceOf, ) -> DispatchResultWithPostInfo { - let who = ensure_signed(origin.clone()) + let owner = ensure_signed(origin.clone()) .map_err(|e| e.with_weight(Self::weight_approve(0, 0)))?; - let current_allowance = AssetsOf::::allowance(id.clone(), &who, &spender); - let spender = T::Lookup::unlookup(spender); - let id: AssetIdParameterOf = id.into(); + let current_allowance = AssetsOf::::allowance(id.clone(), &owner, &spender); - let return_weight = match value.cmp(¤t_allowance) { + let weight = match value.cmp(¤t_allowance) { // If the new value is equal to the current allowance, do nothing. Equal => Self::weight_approve(0, 0), // If the new value is greater than the current allowance, approve the difference @@ -164,8 +214,8 @@ pub mod pallet { Greater => { AssetsOf::::approve_transfer( origin, - id, - spender, + id.clone().into(), + T::Lookup::unlookup(spender.clone()), value.saturating_sub(current_allowance), ) .map_err(|e| e.with_weight(Self::weight_approve(1, 0)))?; @@ -174,16 +224,24 @@ pub mod pallet { // If the new value is less than the current allowance, cancel the approval and // set the new value. Less => { - AssetsOf::::cancel_approval(origin.clone(), id.clone(), spender.clone()) - .map_err(|e| e.with_weight(Self::weight_approve(0, 1)))?; + let id_param: AssetIdParameterOf = id.clone().into(); + let spender_source = T::Lookup::unlookup(spender.clone()); + AssetsOf::::cancel_approval( + origin.clone(), + id_param.clone(), + spender_source.clone(), + ) + .map_err(|e| e.with_weight(Self::weight_approve(0, 1)))?; if value.is_zero() { - return Ok(Some(Self::weight_approve(0, 1)).into()); + Self::weight_approve(0, 1) + } else { + AssetsOf::::approve_transfer(origin, id_param, spender_source, value)?; + Self::weight_approve(1, 1) } - AssetsOf::::approve_transfer(origin, id, spender, value)?; - Self::weight_approve(1, 1) }, }; - Ok(Some(return_weight).into()) + Self::deposit_event(Event::Approval { id, owner, spender, value }); + Ok(Some(weight).into()) } /// Increases the allowance of a spender. @@ -193,15 +251,25 @@ pub mod pallet { /// - `spender` - The account that is allowed to spend the tokens. /// - `value` - The number of tokens to increase the allowance by. #[pallet::call_index(6)] - #[pallet::weight(AssetsWeightInfoOf::::approve_transfer())] + #[pallet::weight(::WeightInfo::approve(1, 0))] pub fn increase_allowance( origin: OriginFor, id: AssetIdOf, spender: AccountIdOf, value: BalanceOf, - ) -> DispatchResult { - let spender = T::Lookup::unlookup(spender); - AssetsOf::::approve_transfer(origin, id.into(), spender, value) + ) -> DispatchResultWithPostInfo { + let owner = ensure_signed(origin.clone()) + .map_err(|e| e.with_weight(Self::weight_approve(0, 0)))?; + AssetsOf::::approve_transfer( + origin, + id.clone().into(), + T::Lookup::unlookup(spender.clone()), + value, + ) + .map_err(|e| e.with_weight(AssetsWeightInfoOf::::approve_transfer()))?; + let value = AssetsOf::::allowance(id.clone(), &owner, &spender); + Self::deposit_event(Event::Approval { id, owner, spender, value }); + Ok(().into()) } /// Decreases the allowance of a spender. @@ -218,24 +286,31 @@ pub mod pallet { spender: AccountIdOf, value: BalanceOf, ) -> DispatchResultWithPostInfo { - let who = ensure_signed(origin.clone()) + let owner = ensure_signed(origin.clone()) .map_err(|e| e.with_weight(Self::weight_approve(0, 0)))?; - let current_allowance = AssetsOf::::allowance(id.clone(), &who, &spender); - let spender = T::Lookup::unlookup(spender); - let id: AssetIdParameterOf = id.into(); - if value.is_zero() { return Ok(Some(Self::weight_approve(0, 0)).into()); } - // Cancel the aproval and set the new value if `new_allowance` is more than zero. - AssetsOf::::cancel_approval(origin.clone(), id.clone(), spender.clone()) - .map_err(|e| e.with_weight(Self::weight_approve(0, 1)))?; + let current_allowance = AssetsOf::::allowance(id.clone(), &owner, &spender); + let spender_source = T::Lookup::unlookup(spender.clone()); + let id_param: AssetIdParameterOf = id.clone().into(); + + // Cancel the approval and set the new value if `new_allowance` is more than zero. + AssetsOf::::cancel_approval( + origin.clone(), + id_param.clone(), + spender_source.clone(), + ) + .map_err(|e| e.with_weight(Self::weight_approve(0, 1)))?; let new_allowance = current_allowance.saturating_sub(value); - if new_allowance.is_zero() { - return Ok(Some(Self::weight_approve(0, 1)).into()); - } - AssetsOf::::approve_transfer(origin, id, spender, new_allowance)?; - Ok(().into()) + let weight = if new_allowance.is_zero() { + Self::weight_approve(0, 1) + } else { + AssetsOf::::approve_transfer(origin, id_param, spender_source, new_allowance)?; + Self::weight_approve(1, 1) + }; + Self::deposit_event(Event::Approval { id, owner, spender, value: new_allowance }); + Ok(Some(weight).into()) } /// Create a new token with a given asset ID. @@ -252,8 +327,15 @@ pub mod pallet { admin: AccountIdOf, min_balance: BalanceOf, ) -> DispatchResult { - let admin = T::Lookup::unlookup(admin); - AssetsOf::::create(origin, id.into(), admin, min_balance) + let creator = ensure_signed(origin.clone())?; + AssetsOf::::create( + origin, + id.clone().into(), + T::Lookup::unlookup(admin.clone()), + min_balance, + )?; + Self::deposit_event(Event::Create { id, creator, admin }); + Ok(()) } /// Start the process of destroying a token with a given asset ID. @@ -297,7 +379,7 @@ pub mod pallet { AssetsOf::::clear_metadata(origin, id.into()) } - /// Creates `value` amount tokens and assigns them to `account`, increasing the total supply. + /// Creates `value` amount of tokens and assigns them to `account`, increasing the total supply. /// /// # Parameters /// - `id` - The ID of the asset. @@ -311,11 +393,17 @@ pub mod pallet { account: AccountIdOf, value: BalanceOf, ) -> DispatchResult { - let account = T::Lookup::unlookup(account); - AssetsOf::::mint(origin, id.into(), account, value) + AssetsOf::::mint( + origin, + id.clone().into(), + T::Lookup::unlookup(account.clone()), + value, + )?; + Self::deposit_event(Event::Transfer { id, from: None, to: Some(account), value }); + Ok(()) } - /// Destroys `value` amount tokens from `account`, reducing the total supply. + /// Destroys `value` amount of tokens from `account`, reducing the total supply. /// /// # Parameters /// - `id` - The ID of the asset. @@ -329,8 +417,14 @@ pub mod pallet { account: AccountIdOf, value: BalanceOf, ) -> DispatchResult { - let account = T::Lookup::unlookup(account); - AssetsOf::::burn(origin, id.into(), account, value) + AssetsOf::::burn( + origin, + id.clone().into(), + T::Lookup::unlookup(account.clone()), + value, + )?; + Self::deposit_event(Event::Transfer { id, from: Some(account), to: None, value }); + Ok(()) } } diff --git a/pallets/api/src/fungibles/tests.rs b/pallets/api/src/fungibles/tests.rs index d6cc87e0..ca2a85c9 100644 --- a/pallets/api/src/fungibles/tests.rs +++ b/pallets/api/src/fungibles/tests.rs @@ -2,6 +2,7 @@ use crate::{fungibles::Read::*, mock::*}; use codec::Encode; use frame_support::{ assert_ok, + sp_runtime::traits::Zero, traits::fungibles::{ approvals::Inspect as ApprovalInspect, metadata::Inspect as MetadataInspect, Inspect, }, @@ -9,34 +10,45 @@ use frame_support::{ const ASSET: u32 = 42; +type Event = crate::fungibles::Event; + #[test] fn transfer_works() { new_test_ext().execute_with(|| { - let amount: Balance = 100 * UNIT; - create_asset_and_mint_to(ALICE, ASSET, ALICE, amount); - let balance_before_transfer = Assets::balance(ASSET, &BOB); - assert_ok!(Fungibles::transfer(signed(ALICE), ASSET, BOB, amount / 2)); - let balance_after_transfer = Assets::balance(ASSET, &BOB); - assert_eq!(balance_after_transfer, balance_before_transfer + amount / 2); + let value: Balance = 100 * UNIT; + let id = ASSET; + let from = Some(ALICE); + let to = Some(BOB); + + create_asset_and_mint_to(ALICE, id, ALICE, value * 2); + let balance_before_transfer = Assets::balance(id, &BOB); + assert_ok!(Fungibles::transfer(signed(ALICE), id, BOB, value)); + let balance_after_transfer = Assets::balance(id, &BOB); + assert_eq!(balance_after_transfer, balance_before_transfer + value); + System::assert_last_event(Event::Transfer { id, from, to, value }.into()); }); } #[test] fn transfer_from_works() { new_test_ext().execute_with(|| { - let amount: Balance = 100 * UNIT; - // Approve CHARLIE to transfer up to `amount` to BOB. - create_asset_mint_and_approve(ALICE, ASSET, ALICE, amount * 2, CHARLIE, amount / 2); - let transferred = amount / 2; + let value: Balance = 100 * UNIT; + let id = ASSET; + let from = Some(ALICE); + let to = Some(BOB); + + // Approve CHARLIE to transfer up to `value` to BOB. + create_asset_mint_and_approve(ALICE, id, ALICE, value * 2, CHARLIE, value); // Successfully call transfer from. - let alice_balance_before_transfer = Assets::balance(ASSET, &ALICE); - let balance_before_transfer = Assets::balance(ASSET, &BOB); - assert_ok!(Fungibles::transfer_from(signed(CHARLIE), ASSET, ALICE, BOB, transferred)); - let alice_balance_after_transfer = Assets::balance(ASSET, &ALICE); - let balance_after_transfer = Assets::balance(ASSET, &BOB); - // Check that BOB receives the `amount` and ALICE `amount` is spent successfully by CHARLIE. - assert_eq!(balance_after_transfer, balance_before_transfer + transferred); - assert_eq!(alice_balance_after_transfer, alice_balance_before_transfer - transferred); + let alice_balance_before_transfer = Assets::balance(id, &ALICE); + let bob_balance_before_transfer = Assets::balance(id, &BOB); + assert_ok!(Fungibles::transfer_from(signed(CHARLIE), id, ALICE, BOB, value)); + let alice_balance_after_transfer = Assets::balance(id, &ALICE); + let bob_balance_after_transfer = Assets::balance(id, &BOB); + // Check that BOB receives the `value` and ALICE `amount` is spent successfully by CHARLIE. + assert_eq!(bob_balance_after_transfer, bob_balance_before_transfer + value); + assert_eq!(alice_balance_after_transfer, alice_balance_before_transfer - value); + System::assert_last_event(Event::Transfer { id, from, to, value }.into()); }); } @@ -44,130 +56,169 @@ fn transfer_from_works() { #[test] fn approve_works() { new_test_ext().execute_with(|| { - let amount: Balance = 100 * UNIT; - create_asset_and_mint_to(ALICE, ASSET, ALICE, amount); - assert_eq!(0, Assets::allowance(ASSET, &ALICE, &BOB)); - assert_ok!(Fungibles::approve(signed(ALICE), ASSET, BOB, amount)); - assert_eq!(Assets::allowance(ASSET, &ALICE, &BOB), amount); - // Approves an amount to spend that is lower than the current allowance. - assert_ok!(Fungibles::approve(signed(ALICE), ASSET, BOB, amount / 2)); - assert_eq!(Assets::allowance(ASSET, &ALICE, &BOB), amount / 2); - // Approves an amount to spend that is higher than the current allowance. - assert_ok!(Fungibles::approve(signed(ALICE), ASSET, BOB, amount * 2)); - assert_eq!(Assets::allowance(ASSET, &ALICE, &BOB), amount * 2); - // Approves an amount to spend that is equal to the current allowance. - assert_ok!(Fungibles::approve(signed(ALICE), ASSET, BOB, amount * 2)); - assert_eq!(Assets::allowance(ASSET, &ALICE, &BOB), amount * 2); + let value: Balance = 100 * UNIT; + let id = ASSET; + let owner = ALICE; + let spender = BOB; + + create_asset_and_mint_to(ALICE, id, ALICE, value); + assert_eq!(0, Assets::allowance(id, &ALICE, &BOB)); + assert_ok!(Fungibles::approve(signed(ALICE), id, BOB, value)); + assert_eq!(Assets::allowance(id, &ALICE, &BOB), value); + System::assert_last_event(Event::Approval { id, owner, spender, value }.into()); + // Approves an value to spend that is lower than the current allowance. + assert_ok!(Fungibles::approve(signed(ALICE), id, BOB, value / 2)); + assert_eq!(Assets::allowance(id, &ALICE, &BOB), value / 2); + System::assert_last_event(Event::Approval { id, owner, spender, value: value / 2 }.into()); + // Approves an value to spend that is higher than the current allowance. + assert_ok!(Fungibles::approve(signed(ALICE), id, BOB, value * 2)); + assert_eq!(Assets::allowance(id, &ALICE, &BOB), value * 2); + System::assert_last_event(Event::Approval { id, owner, spender, value: value * 2 }.into()); + // Approves an value to spend that is equal to the current allowance. + assert_ok!(Fungibles::approve(signed(ALICE), id, BOB, value * 2)); + assert_eq!(Assets::allowance(id, &ALICE, &BOB), value * 2); + System::assert_last_event(Event::Approval { id, owner, spender, value: value * 2 }.into()); // Sets allowance to zero. - assert_ok!(Fungibles::approve(signed(ALICE), ASSET, BOB, 0)); - assert_eq!(Assets::allowance(ASSET, &ALICE, &BOB), 0); + assert_ok!(Fungibles::approve(signed(ALICE), id, BOB, 0)); + assert_eq!(Assets::allowance(id, &ALICE, &BOB), 0); + System::assert_last_event(Event::Approval { id, owner, spender, value: 0 }.into()); }); } #[test] fn increase_allowance_works() { new_test_ext().execute_with(|| { - let amount: Balance = 100 * UNIT; - create_asset_and_mint_to(ALICE, ASSET, ALICE, amount); - assert_eq!(0, Assets::allowance(ASSET, &ALICE, &BOB)); - assert_ok!(Fungibles::increase_allowance(signed(ALICE), ASSET, BOB, amount)); - assert_eq!(Assets::allowance(ASSET, &ALICE, &BOB), amount); + let value: Balance = 100 * UNIT; + let id = ASSET; + let owner = ALICE; + let spender = BOB; + + create_asset_and_mint_to(ALICE, id, ALICE, value); + assert_eq!(0, Assets::allowance(id, &ALICE, &BOB)); + assert_ok!(Fungibles::increase_allowance(signed(ALICE), id, BOB, value)); + assert_eq!(Assets::allowance(id, &ALICE, &BOB), value); + System::assert_last_event(Event::Approval { id, owner, spender, value }.into()); // Additive. - assert_ok!(Fungibles::increase_allowance(signed(ALICE), ASSET, BOB, amount)); - assert_eq!(Assets::allowance(ASSET, &ALICE, &BOB), amount * 2); + assert_ok!(Fungibles::increase_allowance(signed(ALICE), id, BOB, value)); + assert_eq!(Assets::allowance(id, &ALICE, &BOB), value * 2); + System::assert_last_event(Event::Approval { id, owner, spender, value: value * 2 }.into()); }); } #[test] fn decrease_allowance_works() { new_test_ext().execute_with(|| { - let amount: Balance = 100 * UNIT; - create_asset_mint_and_approve(ALICE, ASSET, ALICE, amount, BOB, amount); - assert_eq!(Assets::allowance(ASSET, &ALICE, &BOB), amount); + let value: Balance = 100 * UNIT; + let id = ASSET; + let owner = ALICE; + let spender = BOB; + + create_asset_mint_and_approve(ALICE, id, ALICE, value, BOB, value); + assert_eq!(Assets::allowance(id, &ALICE, &BOB), value); // Owner balance is not changed if decreased by zero. - assert_ok!(Fungibles::decrease_allowance(signed(ALICE), ASSET, BOB, 0)); - assert_eq!(Assets::allowance(ASSET, &ALICE, &BOB), amount); + assert_ok!(Fungibles::decrease_allowance(signed(ALICE), id, BOB, 0)); + assert_eq!(Assets::allowance(id, &ALICE, &BOB), value); // Decrease allowance successfully. - assert_ok!(Fungibles::decrease_allowance(signed(ALICE), ASSET, BOB, amount / 2 - 1 * UNIT)); - assert_eq!(Assets::allowance(ASSET, &ALICE, &BOB), amount / 2 + 1 * UNIT); + assert_ok!(Fungibles::decrease_allowance(signed(ALICE), id, BOB, value / 2)); + assert_eq!(Assets::allowance(id, &ALICE, &BOB), value / 2); + System::assert_last_event(Event::Approval { id, owner, spender, value: value / 2 }.into()); // Saturating if current allowance is decreased more than the owner balance. - assert_ok!(Fungibles::decrease_allowance(signed(ALICE), ASSET, BOB, amount)); - assert_eq!(Assets::allowance(ASSET, &ALICE, &BOB), 0); + assert_ok!(Fungibles::decrease_allowance(signed(ALICE), id, BOB, value)); + assert_eq!(Assets::allowance(id, &ALICE, &BOB), 0); + System::assert_last_event(Event::Approval { id, owner, spender, value: 0 }.into()); }); } #[test] fn create_works() { new_test_ext().execute_with(|| { - assert!(!Assets::asset_exists(ASSET)); - assert_ok!(Fungibles::create(signed(ALICE), ASSET, ALICE, 100)); - assert!(Assets::asset_exists(ASSET)); + let id = ASSET; + let creator = ALICE; + let admin = ALICE; + + assert!(!Assets::asset_exists(id)); + assert_ok!(Fungibles::create(signed(creator), id, admin, 100)); + assert!(Assets::asset_exists(id)); + System::assert_last_event(Event::Create { id, creator, admin }.into()); }); } #[test] fn start_destroy_works() { new_test_ext().execute_with(|| { - create_asset(ALICE, ASSET); - assert_ok!(Fungibles::start_destroy(signed(ALICE), ASSET)); + let id = ASSET; + + create_asset(ALICE, id); + assert_ok!(Fungibles::start_destroy(signed(ALICE), id)); }); } #[test] fn set_metadata_works() { new_test_ext().execute_with(|| { + let id = ASSET; let name = vec![42]; let symbol = vec![42]; let decimals = 42; - create_asset(ALICE, ASSET); + + create_asset(ALICE, id); assert_ok!(Fungibles::set_metadata( signed(ALICE), - ASSET, + id, name.clone(), symbol.clone(), decimals )); - assert_eq!(Assets::name(ASSET), name); - assert_eq!(Assets::symbol(ASSET), symbol); - assert_eq!(Assets::decimals(ASSET), decimals); + assert_eq!(Assets::name(id), name); + assert_eq!(Assets::symbol(id), symbol); + assert_eq!(Assets::decimals(id), decimals); }); } #[test] fn clear_metadata_works() { new_test_ext().execute_with(|| { - let name = vec![42]; - let symbol = vec![42]; - let decimals = 42; - create_asset_and_set_metadata(ALICE, ASSET, name, symbol, decimals); - assert_ok!(Fungibles::clear_metadata(signed(ALICE), ASSET)); - assert_eq!(Assets::name(ASSET), Vec::::new()); - assert_eq!(Assets::symbol(ASSET), Vec::::new()); - assert_eq!(Assets::decimals(ASSET), 0u8); + let id = ASSET; + + create_asset_and_set_metadata(ALICE, id, vec![42], vec![42], 42); + assert_ok!(Fungibles::clear_metadata(signed(ALICE), id)); + assert!(Assets::name(id).is_empty()); + assert!(Assets::symbol(id).is_empty()); + assert!(Assets::decimals(id).is_zero()); }); } #[test] fn mint_works() { new_test_ext().execute_with(|| { - let amount: Balance = 100 * UNIT; - create_asset(ALICE, ASSET); - let balance_before_mint = Assets::balance(ASSET, &BOB); - assert_ok!(Fungibles::mint(signed(ALICE), ASSET, BOB, amount)); - let balance_after_mint = Assets::balance(ASSET, &BOB); - assert_eq!(balance_after_mint, balance_before_mint + amount); + let value: Balance = 100 * UNIT; + let id = ASSET; + let from = None; + let to = Some(BOB); + + create_asset(ALICE, id); + let balance_before_mint = Assets::balance(id, &BOB); + assert_ok!(Fungibles::mint(signed(ALICE), id, BOB, value)); + let balance_after_mint = Assets::balance(id, &BOB); + assert_eq!(balance_after_mint, balance_before_mint + value); + System::assert_last_event(Event::Transfer { id, from, to, value }.into()); }); } #[test] fn burn_works() { new_test_ext().execute_with(|| { - let amount: Balance = 100 * UNIT; - create_asset_and_mint_to(ALICE, ASSET, BOB, amount); - let balance_before_burn = Assets::balance(ASSET, &BOB); - assert_ok!(Fungibles::burn(signed(ALICE), ASSET, BOB, amount)); - let balance_after_burn = Assets::balance(ASSET, &BOB); - assert_eq!(balance_after_burn, balance_before_burn - amount); + let value: Balance = 100 * UNIT; + let id = ASSET; + let from = Some(BOB); + let to = None; + + create_asset_and_mint_to(ALICE, id, BOB, value); + let balance_before_burn = Assets::balance(id, &BOB); + assert_ok!(Fungibles::burn(signed(ALICE), id, BOB, value)); + let balance_after_burn = Assets::balance(id, &BOB); + assert_eq!(balance_after_burn, balance_before_burn - value); + System::assert_last_event(Event::Transfer { id, from, to, value }.into()); }); } diff --git a/pallets/api/src/mock.rs b/pallets/api/src/mock.rs index b20e2635..77e17394 100644 --- a/pallets/api/src/mock.rs +++ b/pallets/api/src/mock.rs @@ -97,6 +97,7 @@ impl pallet_assets::Config for Test { type BenchmarkHelper = (); } impl crate::fungibles::Config for Test { + type RuntimeEvent = RuntimeEvent; type AssetsInstance = AssetsInstance; type WeightInfo = (); } diff --git a/pop-api/src/v0/assets/fungibles.rs b/pop-api/src/v0/assets/fungibles.rs index 8600c439..323db2b6 100644 --- a/pop-api/src/v0/assets/fungibles.rs +++ b/pop-api/src/v0/assets/fungibles.rs @@ -58,6 +58,91 @@ mod constants { pub(super) const BURN: u8 = 20; } +/// A set of events for use in smart contracts interacting with the fungibles API. +/// +/// The `Transfer` and `Approval` events conform to the PSP-22 standard. The other events +/// (`Create`, `StartDestroy`, `SetMetadata`, `ClearMetadata`) are provided for convenience. +/// +/// These events are not emitted by the API itself but can be used in your contracts to +/// track asset operations. Be mindful of the costs associated with emitting events. +/// +/// For more details, refer to [ink! events](https://use.ink/basics/events). +pub mod events { + use super::*; + + /// Event emitted when allowance by `owner` to `spender` changes. + #[ink::event] + pub struct Approval { + /// Account providing allowance. + #[ink(topic)] + pub owner: AccountId, + /// Allowance beneficiary. + #[ink(topic)] + pub spender: AccountId, + /// New allowance amount. + pub value: u128, + } + + /// Event emitted when transfer of tokens occurs. + #[ink::event] + pub struct Transfer { + /// Transfer sender. `None` in case of minting new tokens. + #[ink(topic)] + pub from: Option, + /// Transfer recipient. `None` in case of burning tokens. + #[ink(topic)] + pub to: Option, + /// Amount of tokens transferred (or minted/burned). + pub value: u128, + } + + /// Event emitted when a token class is created. + #[ink::event] + pub struct Create { + /// The ID of the asset. + #[ink(topic)] + pub id: AssetId, + /// Creator of the asset. + #[ink(topic)] + pub creator: AccountId, + /// Admin of the asset. + #[ink(topic)] + pub admin: AccountId, + } + + /// Event emitted when a asset is in the process of being destroyed. + #[ink::event] + pub struct StartDestroy { + /// The ID of the asset. + #[ink(topic)] + pub id: AssetId, + } + + /// Event emitted when new metadata is set for an asset. + #[ink::event] + pub struct SetMetadata { + /// The ID of the asset created. + #[ink(topic)] + pub id: AssetId, + /// The name of the asset. + #[ink(topic)] + pub name: Vec, + /// The symbol of the asset. + #[ink(topic)] + pub symbol: Vec, + /// The decimals of the asset. + pub decimals: u8, + } + + /// Event emitted when metadata is cleared for a token. + #[ink::event] + pub struct ClearMetadata { + /// The ID of the asset. + #[ink(topic)] + pub id: AssetId, + } +} + /// Returns the total token supply for a given asset ID. /// /// # Parameters diff --git a/runtime/devnet/src/config/api.rs b/runtime/devnet/src/config/api.rs index 5f234cd4..4a404c99 100644 --- a/runtime/devnet/src/config/api.rs +++ b/runtime/devnet/src/config/api.rs @@ -1,4 +1,6 @@ -use crate::{config::assets::TrustBackedAssetsInstance, fungibles, Runtime, RuntimeCall}; +use crate::{ + config::assets::TrustBackedAssetsInstance, fungibles, Runtime, RuntimeCall, RuntimeEvent, +}; use codec::{Decode, Encode, MaxEncodedLen}; use pop_chain_extension::{CallFilter, ReadState}; use sp_std::vec::Vec; @@ -60,6 +62,7 @@ impl CallFilter for Extension { } impl fungibles::Config for Runtime { + type RuntimeEvent = RuntimeEvent; type AssetsInstance = TrustBackedAssetsInstance; type WeightInfo = fungibles::weights::SubstrateWeight; } From f13b39cb85417830aa7951fab5a29e5b407812f2 Mon Sep 17 00:00:00 2001 From: Daan van der Plas <93204684+Daanvdplas@users.noreply.github.com> Date: Fri, 16 Aug 2024 10:27:06 +0200 Subject: [PATCH 040/112] docs: pop api (#190) Co-authored-by: Frank Bell <60948618+evilrobot-01@users.noreply.github.com> --- pop-api/src/lib.rs | 23 +++++--- pop-api/src/v0/assets/fungibles.rs | 91 ++++++++---------------------- pop-api/src/v0/assets/mod.rs | 1 + pop-api/src/v0/mod.rs | 21 +++---- 4 files changed, 53 insertions(+), 83 deletions(-) diff --git a/pop-api/src/lib.rs b/pop-api/src/lib.rs index 78a79f80..cc785c14 100644 --- a/pop-api/src/lib.rs +++ b/pop-api/src/lib.rs @@ -1,3 +1,10 @@ +//! The `pop-api` crate provides an API for smart contracts to interact with the Pop Network runtime. +//! +//! This crate abstracts away complexities to deliver a streamlined developer experience while supporting +//! multiple API versions to ensure backward compatibility. It is designed with a focus on stability, +//! future-proofing, and storage efficiency, allowing developers to easily integrate powerful runtime +//! features into their contracts without unnecessary overhead. + #![cfg_attr(not(feature = "std"), no_std, no_main)] use constants::DECODING_FAILED; @@ -5,7 +12,9 @@ use ink::env::chain_extension::{ChainExtensionMethod, FromStatusCode}; #[cfg(feature = "assets")] pub use v0::assets; +/// Module providing primitives types. pub mod primitives; +/// The first version of the API. pub mod v0; /// A result type used by the API, with the `StatusCode` as the error type. @@ -27,13 +36,13 @@ mod constants { pub(crate) const FUNGIBLES: u8 = 150; } -/// Helper method to build `ChainExtensionMethod`. -/// -/// Parameters: -/// - 'version': The version of the chain extension. -/// - 'function': The ID of the function. -/// - 'module': The index of the runtime module. -/// - 'dispatchable': The index of the module dispatchable functions. +// Helper method to build a dispatch call or a call to read state. +// +// Parameters: +// - 'version': The version of the chain extension. +// - 'function': The ID of the function. +// - 'module': The index of the runtime module. +// - 'dispatchable': The index of the module dispatchable functions. fn build_extension_method( version: u8, function: u8, diff --git a/pop-api/src/v0/assets/fungibles.rs b/pop-api/src/v0/assets/fungibles.rs index 323db2b6..c881f823 100644 --- a/pop-api/src/v0/assets/fungibles.rs +++ b/pop-api/src/v0/assets/fungibles.rs @@ -1,3 +1,11 @@ +//! The `fungibles` module provides an API for interacting and managing fungible assets on Pop Network. +//! +//! The API includes the following interfaces: +//! 1. PSP-22 +//! 2. PSP-22 Metadata +//! 3. Asset Management +//! 4. PSP-22 Mintable & Burnable + use crate::{ constants::{ASSETS, BALANCES, FUNGIBLES}, primitives::{AccountId, AssetId, Balance}, @@ -8,28 +16,22 @@ use constants::*; use ink::{env::chain_extension::ChainExtensionMethod, prelude::vec::Vec}; pub use metadata::*; -/// Helper method to build a dispatch call `ChainExtensionMethod` for fungibles `v0`. -/// -/// Parameters: -/// - 'dispatchable': The index of the module dispatchable functions. +// Helper method to build a dispatch call. +// +// Parameters: +// - 'dispatchable': The index of the dispatchable function within the module. fn build_dispatch(dispatchable: u8) -> ChainExtensionMethod<(), (), (), false> { crate::v0::build_dispatch(FUNGIBLES, dispatchable) } -/// Helper method to build a dispatch call `ChainExtensionMethod` for fungibles `v0`. -/// -/// Parameters: -/// - 'state_query': The index of the runtime state query. +// Helper method to build a call to read state. +// +// Parameters: +// - 'state_query': The index of the runtime state query. fn build_read_state(state_query: u8) -> ChainExtensionMethod<(), (), (), false> { crate::v0::build_read_state(FUNGIBLES, state_query) } -/// Local Fungibles: -/// 1. PSP-22 Interface -/// 2. PSP-22 Metadata Interface -/// 3. Asset Management -/// 4. PSP-22 Mintable & Burnable Interface - mod constants { /// 1. PSP-22 Interface: pub(super) const TOTAL_SUPPLY: u8 = 0; @@ -147,9 +149,6 @@ pub mod events { /// /// # Parameters /// - `id` - The ID of the asset. -/// -/// # Returns -/// The total supply of the token, or an error if the operation fails. #[inline] pub fn total_supply(id: AssetId) -> Result { build_read_state(TOTAL_SUPPLY) @@ -165,9 +164,6 @@ pub fn total_supply(id: AssetId) -> Result { /// # Parameters /// - `id` - The ID of the asset. /// - `owner` - The account whose balance is being queried. -/// -/// # Returns -/// The balance of the specified account, or an error if the operation fails. #[inline] pub fn balance_of(id: AssetId, owner: AccountId) -> Result { build_read_state(BALANCE_OF) @@ -184,9 +180,6 @@ pub fn balance_of(id: AssetId, owner: AccountId) -> Result { /// - `id` - The ID of the asset. /// - `owner` - The account that owns the tokens. /// - `spender` - The account that is allowed to spend the tokens. -/// -/// # Returns -/// The remaining allowance, or an error if the operation fails. #[inline] pub fn allowance(id: AssetId, owner: AccountId, spender: AccountId) -> Result { build_read_state(ALLOWANCE) @@ -203,9 +196,6 @@ pub fn allowance(id: AssetId, owner: AccountId, spender: AccountId) -> Result Result<()> { build_dispatch(TRANSFER) @@ -223,9 +213,6 @@ pub fn transfer(id: AssetId, to: AccountId, value: Balance) -> Result<()> { /// - `from` - The account from which the tokens are transferred. /// - `to` - The recipient account. /// - `value` - The number of tokens to transfer. -/// -/// # Returns -/// Returns `Ok(())` if successful, or an error if the transfer fails. #[inline] pub fn transfer_from(id: AssetId, from: AccountId, to: AccountId, value: Balance) -> Result<()> { build_dispatch(TRANSFER_FROM) @@ -241,9 +228,6 @@ pub fn transfer_from(id: AssetId, from: AccountId, to: AccountId, value: Balance /// - `id` - The ID of the asset. /// - `spender` - The account that is allowed to spend the tokens. /// - `value` - The number of tokens to approve. -/// -/// # Returns -/// Returns `Ok(())` if successful, or an error if the approval fails. #[inline] pub fn approve(id: AssetId, spender: AccountId, value: Balance) -> Result<()> { build_dispatch(APPROVE) @@ -259,9 +243,6 @@ pub fn approve(id: AssetId, spender: AccountId, value: Balance) -> Result<()> { /// - `id` - The ID of the asset. /// - `spender` - The account that is allowed to spend the tokens. /// - `value` - The number of tokens to increase the allowance by. -/// -/// # Returns -/// Returns `Ok(())` if successful, or an error if the operation fails. #[inline] pub fn increase_allowance(id: AssetId, spender: AccountId, value: Balance) -> Result<()> { build_dispatch(INCREASE_ALLOWANCE) @@ -277,9 +258,6 @@ pub fn increase_allowance(id: AssetId, spender: AccountId, value: Balance) -> Re /// - `id` - The ID of the asset. /// - `spender` - The account that is allowed to spend the tokens. /// - `value` - The number of tokens to decrease the allowance by. -/// -/// # Returns -/// Returns `Ok(())` if successful, or an error if the operation fails. #[inline] pub fn decrease_allowance(id: AssetId, spender: AccountId, value: Balance) -> Result<()> { build_dispatch(DECREASE_ALLOWANCE) @@ -295,9 +273,7 @@ pub fn decrease_allowance(id: AssetId, spender: AccountId, value: Balance) -> Re /// - `id` - The ID of the asset. /// - `account` - The account to be credited with the created tokens. /// - `value` - The number of tokens to mint. -/// -/// # Returns -/// Returns `Ok(())` if successful, or an error if the operation fails. +#[inline] pub fn mint(id: AssetId, account: AccountId, value: Balance) -> Result<()> { build_dispatch(MINT) .input::<(AssetId, AccountId, Balance)>() @@ -312,9 +288,7 @@ pub fn mint(id: AssetId, account: AccountId, value: Balance) -> Result<()> { /// - `id` - The ID of the asset. /// - `account` - The account from which the tokens will be destroyed. /// - `value` - The number of tokens to destroy. -/// -/// # Returns -/// Returns `Ok(())` if successful, or an error if the operation fails. +#[inline] pub fn burn(id: AssetId, account: AccountId, value: Balance) -> Result<()> { build_dispatch(BURN) .input::<(AssetId, AccountId, Balance)>() @@ -323,6 +297,7 @@ pub fn burn(id: AssetId, account: AccountId, value: Balance) -> Result<()> { .call(&(id, account, value)) } +/// The PSP-22 Metadata interface for querying metadata. pub mod metadata { use super::*; @@ -330,9 +305,6 @@ pub mod metadata { /// /// # Parameters /// - `id` - The ID of the asset. - /// - /// # Returns - /// The name of the token as a byte vector, or an error if the operation fails. #[inline] pub fn token_name(id: AssetId) -> Result> { build_read_state(TOKEN_NAME) @@ -346,9 +318,6 @@ pub mod metadata { /// /// # Parameters /// - `id` - The ID of the asset. - /// - /// # Returns - /// The symbol of the token as a byte vector, or an error if the operation fails. #[inline] pub fn token_symbol(id: AssetId) -> Result> { build_read_state(TOKEN_SYMBOL) @@ -362,9 +331,6 @@ pub mod metadata { /// /// # Parameters /// - `id` - The ID of the asset. - /// - /// # Returns - /// The number of decimals of the token, or an error if the operation fails. #[inline] pub fn token_decimals(id: AssetId) -> Result { build_read_state(TOKEN_DECIMALS) @@ -375,7 +341,8 @@ pub mod metadata { } } -pub mod asset_management { +/// The interface for creating, managing and destroying fungible assets. +pub mod management { use super::*; /// Create a new token with a given asset ID. @@ -384,9 +351,7 @@ pub mod asset_management { /// - `id` - The ID of the asset. /// - `admin` - The account that will administer the asset. /// - `min_balance` - The minimum balance required for accounts holding this asset. - /// - /// # Returns - /// Returns `Ok(())` if successful, or an error if the creation fails. + #[inline] pub fn create(id: AssetId, admin: AccountId, min_balance: Balance) -> Result<()> { build_dispatch(CREATE) .input::<(AssetId, AccountId, Balance)>() @@ -399,9 +364,7 @@ pub mod asset_management { /// /// # Parameters /// - `id` - The ID of the asset. - /// - /// # Returns - /// Returns `Ok(())` if successful, or an error if the operation fails. + #[inline] pub fn start_destroy(id: AssetId) -> Result<()> { build_dispatch(START_DESTROY) .input::() @@ -417,9 +380,7 @@ pub mod asset_management { /// - `name`: The user friendly name of this asset. Limited in length by `StringLimit`. /// - `symbol`: The exchange symbol for this asset. Limited in length by `StringLimit`. /// - `decimals`: The number of decimals this asset uses to represent one unit. - /// - /// # Returns - /// Returns `Ok(())` if successful, or an error if the operation fails. + #[inline] pub fn set_metadata(id: AssetId, name: Vec, symbol: Vec, decimals: u8) -> Result<()> { build_dispatch(SET_METADATA) .input::<(AssetId, Vec, Vec, u8)>() @@ -432,9 +393,7 @@ pub mod asset_management { /// /// # Parameters /// - `id` - The ID of the asset. - /// - /// # Returns - /// Returns `Ok(())` if successful, or an error if the operation fails. + #[inline] pub fn clear_metadata(id: AssetId) -> Result<()> { build_dispatch(CLEAR_METADATA) .input::() diff --git a/pop-api/src/v0/assets/mod.rs b/pop-api/src/v0/assets/mod.rs index 197db710..2d5ae236 100644 --- a/pop-api/src/v0/assets/mod.rs +++ b/pop-api/src/v0/assets/mod.rs @@ -1,2 +1,3 @@ +/// APIs for fungible assets. #[cfg(feature = "fungibles")] pub mod fungibles; diff --git a/pop-api/src/v0/mod.rs b/pop-api/src/v0/mod.rs index 0fd06c89..a4824327 100644 --- a/pop-api/src/v0/mod.rs +++ b/pop-api/src/v0/mod.rs @@ -6,6 +6,7 @@ use crate::{ }; use ink::env::chain_extension::ChainExtensionMethod; +/// APIs for asset-related use cases. #[cfg(feature = "assets")] pub mod assets; @@ -17,20 +18,20 @@ impl From for Error { } } -/// Helper method to build a dispatch call `ChainExtensionMethod` -/// -/// Parameters: -/// - 'module': The index of the runtime module -/// - 'dispatchable': The index of the module dispatchable functions +// Helper method to build a dispatch call. +// +// Parameters: +// - 'module': The index of the runtime module. +// - 'dispatchable': The index of the module dispatchable functions. fn build_dispatch(module: u8, dispatchable: u8) -> ChainExtensionMethod<(), (), (), false> { build_extension_method(V0, DISPATCH, module, dispatchable) } -/// Helper method to build a dispatch call `ChainExtensionMethod` -/// -/// Parameters: -/// - 'module': The index of the runtime module -/// - 'state_query': The index of the runtime state query +// Helper method to build a call to read state. +// +// Parameters: +// - 'module': The index of the runtime module. +// - 'state_query': The index of the runtime state query. fn build_read_state(module: u8, state_query: u8) -> ChainExtensionMethod<(), (), (), false> { build_extension_method(V0, READ_STATE, module, state_query) } From 7c942847cc6b95c5fa6fef7033ba2978f7fe236d Mon Sep 17 00:00:00 2001 From: Daanvdplas Date: Fri, 16 Aug 2024 14:10:46 +0200 Subject: [PATCH 041/112] refactor: extension --- extension/src/lib.rs | 33 +++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/extension/src/lib.rs b/extension/src/lib.rs index 582f346c..650f73f8 100644 --- a/extension/src/lib.rs +++ b/extension/src/lib.rs @@ -1,9 +1,5 @@ #![cfg_attr(not(feature = "std"), no_std)] -#[cfg(test)] -mod tests; -mod v0; - use codec::Encode; use frame_support::{ dispatch::{GetDispatchInfo, PostDispatchInfo}, @@ -18,6 +14,10 @@ use sp_core::crypto::UncheckedFrom; use sp_runtime::{traits::Dispatchable, DispatchError}; use sp_std::vec::Vec; +#[cfg(test)] +mod tests; +mod v0; + /// Logging target for categorizing messages from the Pop API extension module. const LOG_TARGET: &str = "pop-api::extension"; @@ -113,7 +113,7 @@ where } } -/// Extract (version, function_id, pallet_index, call_index) from the payload bytes. +/// Extract discriminators (version, function_id, pallet_index, call_index) from the encoded call. fn extract_env>(env: &Environment) -> (u8, u8, u8, u8) { // Extract version and function_id from first two bytes. let (version, function_id) = { @@ -136,8 +136,6 @@ fn read_state, StateReader: ReadState>( call_index: u8, mut params: Vec, ) -> Result<(), DispatchError> { - const LOG_PREFIX: &str = " read_state |"; - // Prefix params with version, pallet, index to simplify decoding. params.insert(0, version); params.insert(1, pallet_index); @@ -156,7 +154,7 @@ fn read_state, StateReader: ReadState>( }; log::trace!( target:LOG_TARGET, - "{} result: {:?}.", LOG_PREFIX, result + "{} result: {:?}.", " read_state |", result ); env.write(&result, false, None) } @@ -175,8 +173,6 @@ where E: Ext, Filter: CallFilter::RuntimeCall> + 'static, { - const LOG_PREFIX: &str = " dispatch |"; - // Prefix params with version, pallet, index to simplify decoding. params.insert(0, version); params.insert(1, pallet_index); @@ -185,7 +181,7 @@ where // Contract is the origin by default. let origin: T::RuntimeOrigin = RawOrigin::Signed(env.ext().address().clone()).into(); match call { - VersionedDispatch::V0(call) => dispatch_call::(env, call, origin, LOG_PREFIX), + VersionedDispatch::V0(call) => dispatch_call::(env, call, origin), } } @@ -198,7 +194,6 @@ fn dispatch_call( env: &mut Environment, call: T::RuntimeCall, mut origin: T::RuntimeOrigin, - log_prefix: &str, ) -> Result<(), DispatchError> where T: frame_system::Config< @@ -207,12 +202,14 @@ where E: Ext, Filter: CallFilter::RuntimeCall> + 'static, { + const LOG_PREFIX: &str = " dispatch |"; + let charged_dispatch_weight = env.charge_weight(call.get_dispatch_info().weight)?; - log::debug!(target:LOG_TARGET, "{} Inputted RuntimeCall: {:?}", log_prefix, call); + log::debug!(target:LOG_TARGET, "{} Inputted RuntimeCall: {:?}", LOG_PREFIX, call); origin.add_filter(Filter::contains); match call.dispatch(origin) { Ok(info) => { - log::debug!(target:LOG_TARGET, "{} success, actual weight: {:?}", log_prefix, info.actual_weight); + log::debug!(target:LOG_TARGET, "{} success, actual weight: {:?}", LOG_PREFIX, info.actual_weight); // Refund weight if the actual weight is less than the charged weight. if let Some(actual_weight) = info.actual_weight { env.adjust_weight(charged_dispatch_weight, actual_weight); @@ -220,7 +217,11 @@ where Ok(()) }, Err(err) => { - log::debug!(target:LOG_TARGET, "{} failed: error: {:?}", log_prefix, err.error); + log::debug!(target:LOG_TARGET, "{} failed: error: {:?}", LOG_PREFIX, err.error); + // Refund weight if the actual weight is less than the charged weight. + if let Some(actual_weight) = err.post_info.actual_weight { + env.adjust_weight(charged_dispatch_weight, actual_weight); + } Err(err.error) }, } @@ -275,7 +276,7 @@ impl TryFrom for FuncId { } /// Converts a `DispatchError` to a `u32` status code based on the version of the API the contract uses. -/// The contract calling the chain extension can convert the status code to the descriptive `Error`. +/// The contract calling the chain extension can optionally convert the status code to the descriptive `Error`. /// /// For `Error` see `pop_primitives::::error::Error`. /// From 5934fa8d623462303f032e0a80097eeaf591d62e Mon Sep 17 00:00:00 2001 From: Daanvdplas Date: Fri, 16 Aug 2024 14:36:55 +0200 Subject: [PATCH 042/112] fix: remove old api code from deprecated examples --- pop-api/examples/balance-transfer/lib.rs | 2 +- pop-api/examples/nfts/lib.rs | 2 +- pop-api/examples/place-spot-order/lib.rs | 2 +- pop-api/examples/read-runtime-state/lib.rs | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/pop-api/examples/balance-transfer/lib.rs b/pop-api/examples/balance-transfer/lib.rs index d36dfa53..e75c15b9 100755 --- a/pop-api/examples/balance-transfer/lib.rs +++ b/pop-api/examples/balance-transfer/lib.rs @@ -15,7 +15,7 @@ impl From for ContractError { } } -#[ink::contract(env = pop_api::Environment)] +#[ink::contract] mod balance_transfer { use super::*; diff --git a/pop-api/examples/nfts/lib.rs b/pop-api/examples/nfts/lib.rs index 7920c179..0cd0f313 100755 --- a/pop-api/examples/nfts/lib.rs +++ b/pop-api/examples/nfts/lib.rs @@ -18,7 +18,7 @@ impl From for ContractError { } } -#[ink::contract(env = pop_api::Environment)] +#[ink::contract] mod nfts { use super::*; diff --git a/pop-api/examples/place-spot-order/lib.rs b/pop-api/examples/place-spot-order/lib.rs index 669b9190..965917d1 100755 --- a/pop-api/examples/place-spot-order/lib.rs +++ b/pop-api/examples/place-spot-order/lib.rs @@ -1,7 +1,7 @@ // DEPRECATED #![cfg_attr(not(feature = "std"), no_std, no_main)] -#[ink::contract(env = pop_api::Environment)] +#[ink::contract] mod spot_order { #[ink(storage)] diff --git a/pop-api/examples/read-runtime-state/lib.rs b/pop-api/examples/read-runtime-state/lib.rs index 60ef70f0..092e9f2f 100755 --- a/pop-api/examples/read-runtime-state/lib.rs +++ b/pop-api/examples/read-runtime-state/lib.rs @@ -1,7 +1,7 @@ // DEPRECATED #![cfg_attr(not(feature = "std"), no_std, no_main)] -#[ink::contract(env = pop_api::Environment)] +#[ink::contract] mod read_relay_blocknumber { use pop_api::primitives::storage_keys::{ ParachainSystemKeys::LastRelayChainBlockNumber, RuntimeStateKeys::ParachainSystem, From f2ef7a184c67a80e14291786360a7b115b837c75 Mon Sep 17 00:00:00 2001 From: Daanvdplas Date: Fri, 16 Aug 2024 14:59:40 +0200 Subject: [PATCH 043/112] refactor: runtime devnet --- Cargo.lock | 1 - runtime/devnet/Cargo.toml | 1 - runtime/devnet/src/config/mod.rs | 4 ++-- runtime/devnet/src/lib.rs | 4 ++-- 4 files changed, 4 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 78e5e1d1..3407a210 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -9613,7 +9613,6 @@ dependencies = [ "pop-chain-extension", "pop-primitives", "pop-runtime-common", - "rand", "scale-info", "smallvec", "sp-api", diff --git a/runtime/devnet/Cargo.toml b/runtime/devnet/Cargo.toml index 995af269..3d2f20d0 100644 --- a/runtime/devnet/Cargo.toml +++ b/runtime/devnet/Cargo.toml @@ -92,7 +92,6 @@ parachain-info.workspace = true [dev-dependencies] env_logger = "0.11.2" hex = "0.4.3" -rand = "0.8.5" [features] default = ["std"] diff --git a/runtime/devnet/src/config/mod.rs b/runtime/devnet/src/config/mod.rs index f62ffa76..1dcd44da 100644 --- a/runtime/devnet/src/config/mod.rs +++ b/runtime/devnet/src/config/mod.rs @@ -1,5 +1,5 @@ -pub(crate) mod api; -pub mod assets; +mod api; +mod assets; mod contracts; mod proxy; // Public due to integration tests crate. diff --git a/runtime/devnet/src/lib.rs b/runtime/devnet/src/lib.rs index 4256ac01..e1ef6c6d 100644 --- a/runtime/devnet/src/lib.rs +++ b/runtime/devnet/src/lib.rs @@ -72,7 +72,7 @@ use weights::{BlockExecutionWeight, ExtrinsicBaseWeight, RocksDbWeight}; // XCM Imports use xcm::latest::prelude::BodyId; -pub(crate) use pallet_api::fungibles; +use pallet_api::fungibles; /// Some way of identifying an account on the chain. We intentionally make it equivalent /// to the public key of our transaction signing scheme. @@ -590,7 +590,7 @@ construct_runtime!( mod benches { frame_benchmarking::define_benchmarks!( [frame_system, SystemBench::] - [pallet_api::fungibles, Fungibles] + [fungibles, Fungibles] [pallet_balances, Balances] [pallet_session, SessionBench::] [pallet_timestamp, Timestamp] From b3dd9935cffabc5ccac2a92fe8355822b3275158 Mon Sep 17 00:00:00 2001 From: Daanvdplas Date: Fri, 16 Aug 2024 15:56:50 +0200 Subject: [PATCH 044/112] refactor: fungibles pallet --- pallets/api/Cargo.toml | 2 +- pallets/api/src/fungibles/mod.rs | 232 +++++++++++++++-------------- pallets/api/src/fungibles/tests.rs | 202 +++++++++++++------------ 3 files changed, 226 insertions(+), 210 deletions(-) diff --git a/pallets/api/Cargo.toml b/pallets/api/Cargo.toml index a813a09c..f9a807a3 100644 --- a/pallets/api/Cargo.toml +++ b/pallets/api/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "pallet-api" authors.workspace = true -description = "Api pallet, enabling smart(er) contracts with the power of Polkadot" +description = "API pallet, enabling smart(er) contracts with the power of Polkadot" edition.workspace = true license.workspace = true version = "0.1.0" diff --git a/pallets/api/src/fungibles/mod.rs b/pallets/api/src/fungibles/mod.rs index 7aa9ac00..6ff8ac87 100644 --- a/pallets/api/src/fungibles/mod.rs +++ b/pallets/api/src/fungibles/mod.rs @@ -1,6 +1,11 @@ -/// The fungibles pallet serves as a wrapper around the pallet_assets, offering a streamlined -/// interface for interacting with fungible assets. The goal is to provide a simplified, consistent -/// API that adheres to standards in the smart contract space. +//! The fungibles pallet offers a streamlined interface for interacting with fungible assets. The +//! goal is to provide a simplified, consistent API that adheres to standards in the smart contract +//! space. + +use frame_support::traits::fungibles::{metadata::Inspect as MetadataInspect, Inspect}; +pub use pallet::*; +use pallet_assets::WeightInfo as AssetsWeightInfoTrait; +use weights::WeightInfo; #[cfg(feature = "runtime-benchmarks")] mod benchmarking; @@ -8,11 +13,6 @@ mod benchmarking; mod tests; pub mod weights; -use frame_support::traits::fungibles::{metadata::Inspect as MetadataInspect, Inspect}; -pub use pallet::*; -use pallet_assets::WeightInfo as AssetsWeightInfoTrait; -use weights::WeightInfo; - type AccountIdOf = ::AccountId; type AssetIdOf = > as Inspect< ::AccountId, @@ -41,42 +41,42 @@ pub mod pallet { }; use sp_std::vec::Vec; - /// State reads for the fungibles api with required input. + /// State reads for the fungibles API with required input. #[derive(Encode, Decode, Debug, MaxEncodedLen)] #[repr(u8)] #[allow(clippy::unnecessary_cast)] pub enum Read { - /// Total token supply for a given asset ID. + /// Total token supply for a specified asset. #[codec(index = 0)] TotalSupply(AssetIdOf), - /// Account balance for a given asset ID. + /// Account balance for a specified `asset` and `owner`. #[codec(index = 1)] BalanceOf { - /// The asset ID. - id: AssetIdOf, - /// The account ID of the owner. + /// The asset. + asset: AssetIdOf, + /// The owner of the asset. owner: AccountIdOf, }, - /// Allowance for a spender approved by an owner, for a given asset ID. + /// Allowance for a `spender` approved by an `owner`, for a specified `asset`. #[codec(index = 2)] Allowance { - /// The asset ID. - id: AssetIdOf, - /// The account ID of the owner. + /// The asset. + asset: AssetIdOf, + /// The owner of the asset. owner: AccountIdOf, - /// The account ID of the spender. + /// The spender with an allowance. spender: AccountIdOf, }, - /// Token name for a given asset ID. + /// Name of the specified asset. #[codec(index = 8)] TokenName(AssetIdOf), - /// Token symbol for a given asset ID. + /// Symbol for the specified asset. #[codec(index = 9)] TokenSymbol(AssetIdOf), - /// Token decimals for a given asset ID. + /// Decimals for the specified asset. #[codec(index = 10)] TokenDecimals(AssetIdOf), - /// Check if token with a given asset ID exists. + /// Check if a specified asset exists. #[codec(index = 18)] AssetExists(AssetIdOf), } @@ -101,70 +101,68 @@ pub mod pallet { pub enum Event { /// Event emitted when allowance by `owner` to `spender` changes. Approval { - /// The ID of the asset. - id: AssetIdOf, - /// Account providing allowance. + /// The asset. + asset: AssetIdOf, + /// The owner providing the allowance. owner: AccountIdOf, - /// Allowance beneficiary. + /// The beneficiary of the allowance. spender: AccountIdOf, - /// New allowance amount. + /// The new allowance amount. value: BalanceOf, }, - /// Event emitted when transfer of tokens occurs. + /// Event emitted when an asset transfer occurs. Transfer { - /// The ID of the asset. - id: AssetIdOf, - /// Transfer sender. `None` in case of minting new tokens. + /// The asset. + asset: AssetIdOf, + /// The source of the transfer. `None` when minting. from: Option>, - /// Transfer recipient. `None` in case of burning tokens. + /// The recipient of the transfer. `None` when burning. to: Option>, - /// Amount of tokens transferred (or minted/burned). + /// The amount transferred (or minted/burned). value: BalanceOf, }, - /// Event emitted when a token class is created. + /// Event emitted when an asset is created. Create { - /// The ID of the asset. + /// The asset identifier. id: AssetIdOf, - /// Creator of the asset. + /// The creator of the asset. creator: AccountIdOf, - /// Admin of the asset. + /// The administrator of the asset. admin: AccountIdOf, }, } #[pallet::call] impl Pallet { - /// Transfers `value` amount of tokens from the caller's account to account `to`, with additional - /// `data` in unspecified format. + /// Transfers `value` amount of tokens from the caller's account to account `to`. /// /// # Parameters - /// - `id` - The ID of the asset. + /// - `asset` - The asset to transfer. /// - `to` - The recipient account. /// - `value` - The number of tokens to transfer. #[pallet::call_index(3)] #[pallet::weight(AssetsWeightInfoOf::::transfer_keep_alive())] pub fn transfer( origin: OriginFor, - id: AssetIdOf, + asset: AssetIdOf, to: AccountIdOf, value: BalanceOf, ) -> DispatchResult { + let from = ensure_signed(origin.clone())?; AssetsOf::::transfer_keep_alive( - origin.clone(), - id.clone().into(), + origin, + asset.clone().into(), T::Lookup::unlookup(to.clone()), value, )?; - let from = ensure_signed(origin)?; - Self::deposit_event(Event::Transfer { id, from: Some(from), to: Some(to), value }); + Self::deposit_event(Event::Transfer { asset, from: Some(from), to: Some(to), value }); Ok(()) } - /// Transfers `value` amount tokens on behalf of `from` to account `to` with additional `data` - /// in unspecified format. + /// Transfers `value` amount tokens on behalf of `from` to account `to`. /// /// # Parameters - /// - `id` - The ID of the asset. + /// - `asset` - The asset to transfer. /// - `from` - The account from which the asset balance will be withdrawn. /// - `to` - The recipient account. /// - `value` - The number of tokens to transfer. @@ -172,39 +170,39 @@ pub mod pallet { #[pallet::weight(AssetsWeightInfoOf::::transfer_approved())] pub fn transfer_from( origin: OriginFor, - id: AssetIdOf, + asset: AssetIdOf, from: AccountIdOf, to: AccountIdOf, value: BalanceOf, ) -> DispatchResult { AssetsOf::::transfer_approved( origin, - id.clone().into(), + asset.clone().into(), T::Lookup::unlookup(from.clone()), T::Lookup::unlookup(to.clone()), value, )?; - Self::deposit_event(Event::Transfer { id, from: Some(from), to: Some(to), value }); + Self::deposit_event(Event::Transfer { asset, from: Some(from), to: Some(to), value }); Ok(()) } - /// Approves an account to spend a specified number of tokens on behalf of the caller. + /// Approves `spender` to spend `value` amount of tokens on behalf of the caller. /// /// # Parameters - /// - `id` - The ID of the asset. + /// - `asset` - The asset to approve. /// - `spender` - The account that is allowed to spend the tokens. /// - `value` - The number of tokens to approve. #[pallet::call_index(5)] #[pallet::weight(::WeightInfo::approve(1, 1))] pub fn approve( origin: OriginFor, - id: AssetIdOf, + asset: AssetIdOf, spender: AccountIdOf, value: BalanceOf, ) -> DispatchResultWithPostInfo { let owner = ensure_signed(origin.clone()) .map_err(|e| e.with_weight(Self::weight_approve(0, 0)))?; - let current_allowance = AssetsOf::::allowance(id.clone(), &owner, &spender); + let current_allowance = AssetsOf::::allowance(asset.clone(), &owner, &spender); let weight = match value.cmp(¤t_allowance) { // If the new value is equal to the current allowance, do nothing. @@ -214,7 +212,7 @@ pub mod pallet { Greater => { AssetsOf::::approve_transfer( origin, - id.clone().into(), + asset.clone().into(), T::Lookup::unlookup(spender.clone()), value.saturating_sub(current_allowance), ) @@ -224,37 +222,42 @@ pub mod pallet { // If the new value is less than the current allowance, cancel the approval and // set the new value. Less => { - let id_param: AssetIdParameterOf = id.clone().into(); + let asset_param: AssetIdParameterOf = asset.clone().into(); let spender_source = T::Lookup::unlookup(spender.clone()); AssetsOf::::cancel_approval( origin.clone(), - id_param.clone(), + asset_param.clone(), spender_source.clone(), ) .map_err(|e| e.with_weight(Self::weight_approve(0, 1)))?; if value.is_zero() { Self::weight_approve(0, 1) } else { - AssetsOf::::approve_transfer(origin, id_param, spender_source, value)?; + AssetsOf::::approve_transfer( + origin, + asset_param, + spender_source, + value, + )?; Self::weight_approve(1, 1) } }, }; - Self::deposit_event(Event::Approval { id, owner, spender, value }); + Self::deposit_event(Event::Approval { asset, owner, spender, value }); Ok(Some(weight).into()) } - /// Increases the allowance of a spender. + /// Increases the allowance of `spender` by `value` amount of tokens. /// /// # Parameters - /// - `id` - The ID of the asset. + /// - `asset` - The asset to have an allowance increased. /// - `spender` - The account that is allowed to spend the tokens. /// - `value` - The number of tokens to increase the allowance by. #[pallet::call_index(6)] #[pallet::weight(::WeightInfo::approve(1, 0))] pub fn increase_allowance( origin: OriginFor, - id: AssetIdOf, + asset: AssetIdOf, spender: AccountIdOf, value: BalanceOf, ) -> DispatchResultWithPostInfo { @@ -262,27 +265,27 @@ pub mod pallet { .map_err(|e| e.with_weight(Self::weight_approve(0, 0)))?; AssetsOf::::approve_transfer( origin, - id.clone().into(), + asset.clone().into(), T::Lookup::unlookup(spender.clone()), value, ) .map_err(|e| e.with_weight(AssetsWeightInfoOf::::approve_transfer()))?; - let value = AssetsOf::::allowance(id.clone(), &owner, &spender); - Self::deposit_event(Event::Approval { id, owner, spender, value }); + let value = AssetsOf::::allowance(asset.clone(), &owner, &spender); + Self::deposit_event(Event::Approval { asset, owner, spender, value }); Ok(().into()) } - /// Decreases the allowance of a spender. + /// Decreases the allowance of a `spender` by `value` amount of tokens. /// /// # Parameters - /// - `id` - The ID of the asset. + /// - `asset` - The asset to have an allowance decreased. /// - `spender` - The account that is allowed to spend the tokens. /// - `value` - The number of tokens to decrease the allowance by. #[pallet::call_index(7)] #[pallet::weight(::WeightInfo::approve(1, 1))] pub fn decrease_allowance( origin: OriginFor, - id: AssetIdOf, + asset: AssetIdOf, spender: AccountIdOf, value: BalanceOf, ) -> DispatchResultWithPostInfo { @@ -291,14 +294,14 @@ pub mod pallet { if value.is_zero() { return Ok(Some(Self::weight_approve(0, 0)).into()); } - let current_allowance = AssetsOf::::allowance(id.clone(), &owner, &spender); + let current_allowance = AssetsOf::::allowance(asset.clone(), &owner, &spender); let spender_source = T::Lookup::unlookup(spender.clone()); - let id_param: AssetIdParameterOf = id.clone().into(); + let asset_param: AssetIdParameterOf = asset.clone().into(); // Cancel the approval and set the new value if `new_allowance` is more than zero. AssetsOf::::cancel_approval( origin.clone(), - id_param.clone(), + asset_param.clone(), spender_source.clone(), ) .map_err(|e| e.with_weight(Self::weight_approve(0, 1)))?; @@ -306,17 +309,22 @@ pub mod pallet { let weight = if new_allowance.is_zero() { Self::weight_approve(0, 1) } else { - AssetsOf::::approve_transfer(origin, id_param, spender_source, new_allowance)?; + AssetsOf::::approve_transfer( + origin, + asset_param, + spender_source, + new_allowance, + )?; Self::weight_approve(1, 1) }; - Self::deposit_event(Event::Approval { id, owner, spender, value: new_allowance }); + Self::deposit_event(Event::Approval { asset, owner, spender, value: new_allowance }); Ok(Some(weight).into()) } - /// Create a new token with a given asset ID. + /// Create a new token with a given identifier. /// /// # Parameters - /// - `id` - The ID of the asset. + /// - `id` - The identifier of the asset. /// - `admin` - The account that will administer the asset. /// - `min_balance` - The minimum balance required for accounts holding this asset. #[pallet::call_index(11)] @@ -338,92 +346,90 @@ pub mod pallet { Ok(()) } - /// Start the process of destroying a token with a given asset ID. + /// Start the process of destroying a token. /// /// # Parameters - /// - `id` - The ID of the asset. + /// - `asset` - The asset to be destroyed. #[pallet::call_index(12)] #[pallet::weight(AssetsWeightInfoOf::::start_destroy())] - pub fn start_destroy(origin: OriginFor, id: AssetIdOf) -> DispatchResult { - AssetsOf::::start_destroy(origin, id.into()) + pub fn start_destroy(origin: OriginFor, asset: AssetIdOf) -> DispatchResult { + AssetsOf::::start_destroy(origin, asset.into()) } - /// Set the metadata for a token with a given asset ID. + /// Set the metadata for a token. /// /// # Parameters - /// - `id`: The identifier of the asset to update. - /// - `name`: The user friendly name of this asset. Limited in length by - /// `pallet_assets::Config::StringLimit`. - /// - `symbol`: The exchange symbol for this asset. Limited in length by - /// `pallet_assets::Config::StringLimit`. + /// - `asset`: The asset to update. + /// - `name`: The user friendly name of this asset. + /// - `symbol`: The exchange symbol for this asset. /// - `decimals`: The number of decimals this asset uses to represent one unit. #[pallet::call_index(16)] #[pallet::weight(AssetsWeightInfoOf::::set_metadata(name.len() as u32, symbol.len() as u32))] pub fn set_metadata( origin: OriginFor, - id: AssetIdOf, + asset: AssetIdOf, name: Vec, symbol: Vec, decimals: u8, ) -> DispatchResult { - AssetsOf::::set_metadata(origin, id.into(), name, symbol, decimals) + AssetsOf::::set_metadata(origin, asset.into(), name, symbol, decimals) } - /// Clear the metadata for a token with a given asset ID. + /// Clear the metadata for a token. /// /// # Parameters - /// - `id` - The ID of the asset. + /// - `asset` - The asset to update. #[pallet::call_index(17)] #[pallet::weight(AssetsWeightInfoOf::::clear_metadata())] - pub fn clear_metadata(origin: OriginFor, id: AssetIdOf) -> DispatchResult { - AssetsOf::::clear_metadata(origin, id.into()) + pub fn clear_metadata(origin: OriginFor, asset: AssetIdOf) -> DispatchResult { + AssetsOf::::clear_metadata(origin, asset.into()) } /// Creates `value` amount of tokens and assigns them to `account`, increasing the total supply. /// /// # Parameters - /// - `id` - The ID of the asset. + /// - `asset` - The asset to mint. /// - `account` - The account to be credited with the created tokens. /// - `value` - The number of tokens to mint. #[pallet::call_index(19)] #[pallet::weight(AssetsWeightInfoOf::::mint())] pub fn mint( origin: OriginFor, - id: AssetIdOf, + asset: AssetIdOf, account: AccountIdOf, value: BalanceOf, ) -> DispatchResult { AssetsOf::::mint( origin, - id.clone().into(), + asset.clone().into(), T::Lookup::unlookup(account.clone()), value, )?; - Self::deposit_event(Event::Transfer { id, from: None, to: Some(account), value }); + Self::deposit_event(Event::Transfer { asset, from: None, to: Some(account), value }); Ok(()) } /// Destroys `value` amount of tokens from `account`, reducing the total supply. /// /// # Parameters - /// - `id` - The ID of the asset. + /// - `asset` - the asset to burn. /// - `account` - The account from which the tokens will be destroyed. /// - `value` - The number of tokens to destroy. #[pallet::call_index(20)] #[pallet::weight(AssetsWeightInfoOf::::burn())] pub fn burn( origin: OriginFor, - id: AssetIdOf, + asset: AssetIdOf, account: AccountIdOf, value: BalanceOf, ) -> DispatchResult { AssetsOf::::burn( origin, - id.clone().into(), + asset.clone().into(), T::Lookup::unlookup(account.clone()), value, )?; - Self::deposit_event(Event::Transfer { id, from: Some(account), to: None, value }); + Self::deposit_event(Event::Transfer { asset, from: Some(account), to: None, value }); Ok(()) } } @@ -441,25 +447,25 @@ pub mod pallet { use Read::*; match value { - TotalSupply(id) => AssetsOf::::total_supply(id).encode(), - BalanceOf { id, owner } => AssetsOf::::balance(id, owner).encode(), - Allowance { id, owner, spender } => { - AssetsOf::::allowance(id, &owner, &spender).encode() + TotalSupply(asset) => AssetsOf::::total_supply(asset).encode(), + BalanceOf { asset, owner } => AssetsOf::::balance(asset, owner).encode(), + Allowance { asset, owner, spender } => { + AssetsOf::::allowance(asset, &owner, &spender).encode() }, - TokenName(id) => { - as MetadataInspect>>::name(id).encode() + TokenName(asset) => { + as MetadataInspect>>::name(asset).encode() }, - TokenSymbol(id) => { - as MetadataInspect>>::symbol(id).encode() + TokenSymbol(asset) => { + as MetadataInspect>>::symbol(asset).encode() }, - TokenDecimals(id) => { - as MetadataInspect>>::decimals(id).encode() + TokenDecimals(asset) => { + as MetadataInspect>>::decimals(asset).encode() }, - AssetExists(id) => AssetsOf::::asset_exists(id).encode(), + AssetExists(asset) => AssetsOf::::asset_exists(asset).encode(), } } - pub fn weight_approve(approve: u32, cancel: u32) -> Weight { + fn weight_approve(approve: u32, cancel: u32) -> Weight { ::WeightInfo::approve(cancel, approve) } } diff --git a/pallets/api/src/fungibles/tests.rs b/pallets/api/src/fungibles/tests.rs index ca2a85c9..9610139e 100644 --- a/pallets/api/src/fungibles/tests.rs +++ b/pallets/api/src/fungibles/tests.rs @@ -16,16 +16,16 @@ type Event = crate::fungibles::Event; fn transfer_works() { new_test_ext().execute_with(|| { let value: Balance = 100 * UNIT; - let id = ASSET; + let asset = ASSET; let from = Some(ALICE); let to = Some(BOB); - create_asset_and_mint_to(ALICE, id, ALICE, value * 2); - let balance_before_transfer = Assets::balance(id, &BOB); - assert_ok!(Fungibles::transfer(signed(ALICE), id, BOB, value)); - let balance_after_transfer = Assets::balance(id, &BOB); + create_asset_and_mint_to(ALICE, asset, ALICE, value * 2); + let balance_before_transfer = Assets::balance(asset, &BOB); + assert_ok!(Fungibles::transfer(signed(ALICE), asset, BOB, value)); + let balance_after_transfer = Assets::balance(asset, &BOB); assert_eq!(balance_after_transfer, balance_before_transfer + value); - System::assert_last_event(Event::Transfer { id, from, to, value }.into()); + System::assert_last_event(Event::Transfer { asset, from, to, value }.into()); }); } @@ -33,22 +33,22 @@ fn transfer_works() { fn transfer_from_works() { new_test_ext().execute_with(|| { let value: Balance = 100 * UNIT; - let id = ASSET; + let asset = ASSET; let from = Some(ALICE); let to = Some(BOB); // Approve CHARLIE to transfer up to `value` to BOB. - create_asset_mint_and_approve(ALICE, id, ALICE, value * 2, CHARLIE, value); + create_asset_mint_and_approve(ALICE, asset, ALICE, value * 2, CHARLIE, value); // Successfully call transfer from. - let alice_balance_before_transfer = Assets::balance(id, &ALICE); - let bob_balance_before_transfer = Assets::balance(id, &BOB); - assert_ok!(Fungibles::transfer_from(signed(CHARLIE), id, ALICE, BOB, value)); - let alice_balance_after_transfer = Assets::balance(id, &ALICE); - let bob_balance_after_transfer = Assets::balance(id, &BOB); + let alice_balance_before_transfer = Assets::balance(asset, &ALICE); + let bob_balance_before_transfer = Assets::balance(asset, &BOB); + assert_ok!(Fungibles::transfer_from(signed(CHARLIE), asset, ALICE, BOB, value)); + let alice_balance_after_transfer = Assets::balance(asset, &ALICE); + let bob_balance_after_transfer = Assets::balance(asset, &BOB); // Check that BOB receives the `value` and ALICE `amount` is spent successfully by CHARLIE. assert_eq!(bob_balance_after_transfer, bob_balance_before_transfer + value); assert_eq!(alice_balance_after_transfer, alice_balance_before_transfer - value); - System::assert_last_event(Event::Transfer { id, from, to, value }.into()); + System::assert_last_event(Event::Transfer { asset, from, to, value }.into()); }); } @@ -57,31 +57,37 @@ fn transfer_from_works() { fn approve_works() { new_test_ext().execute_with(|| { let value: Balance = 100 * UNIT; - let id = ASSET; + let asset = ASSET; let owner = ALICE; let spender = BOB; - create_asset_and_mint_to(ALICE, id, ALICE, value); - assert_eq!(0, Assets::allowance(id, &ALICE, &BOB)); - assert_ok!(Fungibles::approve(signed(ALICE), id, BOB, value)); - assert_eq!(Assets::allowance(id, &ALICE, &BOB), value); - System::assert_last_event(Event::Approval { id, owner, spender, value }.into()); + create_asset_and_mint_to(ALICE, asset, ALICE, value); + assert_eq!(0, Assets::allowance(asset, &ALICE, &BOB)); + assert_ok!(Fungibles::approve(signed(ALICE), asset, BOB, value)); + assert_eq!(Assets::allowance(asset, &ALICE, &BOB), value); + System::assert_last_event(Event::Approval { asset, owner, spender, value }.into()); // Approves an value to spend that is lower than the current allowance. - assert_ok!(Fungibles::approve(signed(ALICE), id, BOB, value / 2)); - assert_eq!(Assets::allowance(id, &ALICE, &BOB), value / 2); - System::assert_last_event(Event::Approval { id, owner, spender, value: value / 2 }.into()); + assert_ok!(Fungibles::approve(signed(ALICE), asset, BOB, value / 2)); + assert_eq!(Assets::allowance(asset, &ALICE, &BOB), value / 2); + System::assert_last_event( + Event::Approval { asset, owner, spender, value: value / 2 }.into(), + ); // Approves an value to spend that is higher than the current allowance. - assert_ok!(Fungibles::approve(signed(ALICE), id, BOB, value * 2)); - assert_eq!(Assets::allowance(id, &ALICE, &BOB), value * 2); - System::assert_last_event(Event::Approval { id, owner, spender, value: value * 2 }.into()); + assert_ok!(Fungibles::approve(signed(ALICE), asset, BOB, value * 2)); + assert_eq!(Assets::allowance(asset, &ALICE, &BOB), value * 2); + System::assert_last_event( + Event::Approval { asset, owner, spender, value: value * 2 }.into(), + ); // Approves an value to spend that is equal to the current allowance. - assert_ok!(Fungibles::approve(signed(ALICE), id, BOB, value * 2)); - assert_eq!(Assets::allowance(id, &ALICE, &BOB), value * 2); - System::assert_last_event(Event::Approval { id, owner, spender, value: value * 2 }.into()); + assert_ok!(Fungibles::approve(signed(ALICE), asset, BOB, value * 2)); + assert_eq!(Assets::allowance(asset, &ALICE, &BOB), value * 2); + System::assert_last_event( + Event::Approval { asset, owner, spender, value: value * 2 }.into(), + ); // Sets allowance to zero. - assert_ok!(Fungibles::approve(signed(ALICE), id, BOB, 0)); - assert_eq!(Assets::allowance(id, &ALICE, &BOB), 0); - System::assert_last_event(Event::Approval { id, owner, spender, value: 0 }.into()); + assert_ok!(Fungibles::approve(signed(ALICE), asset, BOB, 0)); + assert_eq!(Assets::allowance(asset, &ALICE, &BOB), 0); + System::assert_last_event(Event::Approval { asset, owner, spender, value: 0 }.into()); }); } @@ -89,19 +95,21 @@ fn approve_works() { fn increase_allowance_works() { new_test_ext().execute_with(|| { let value: Balance = 100 * UNIT; - let id = ASSET; + let asset = ASSET; let owner = ALICE; let spender = BOB; - create_asset_and_mint_to(ALICE, id, ALICE, value); - assert_eq!(0, Assets::allowance(id, &ALICE, &BOB)); - assert_ok!(Fungibles::increase_allowance(signed(ALICE), id, BOB, value)); - assert_eq!(Assets::allowance(id, &ALICE, &BOB), value); - System::assert_last_event(Event::Approval { id, owner, spender, value }.into()); + create_asset_and_mint_to(ALICE, asset, ALICE, value); + assert_eq!(0, Assets::allowance(asset, &ALICE, &BOB)); + assert_ok!(Fungibles::increase_allowance(signed(ALICE), asset, BOB, value)); + assert_eq!(Assets::allowance(asset, &ALICE, &BOB), value); + System::assert_last_event(Event::Approval { asset, owner, spender, value }.into()); // Additive. - assert_ok!(Fungibles::increase_allowance(signed(ALICE), id, BOB, value)); - assert_eq!(Assets::allowance(id, &ALICE, &BOB), value * 2); - System::assert_last_event(Event::Approval { id, owner, spender, value: value * 2 }.into()); + assert_ok!(Fungibles::increase_allowance(signed(ALICE), asset, BOB, value)); + assert_eq!(Assets::allowance(asset, &ALICE, &BOB), value * 2); + System::assert_last_event( + Event::Approval { asset, owner, spender, value: value * 2 }.into(), + ); }); } @@ -109,23 +117,25 @@ fn increase_allowance_works() { fn decrease_allowance_works() { new_test_ext().execute_with(|| { let value: Balance = 100 * UNIT; - let id = ASSET; + let asset = ASSET; let owner = ALICE; let spender = BOB; - create_asset_mint_and_approve(ALICE, id, ALICE, value, BOB, value); - assert_eq!(Assets::allowance(id, &ALICE, &BOB), value); + create_asset_mint_and_approve(ALICE, asset, ALICE, value, BOB, value); + assert_eq!(Assets::allowance(asset, &ALICE, &BOB), value); // Owner balance is not changed if decreased by zero. - assert_ok!(Fungibles::decrease_allowance(signed(ALICE), id, BOB, 0)); - assert_eq!(Assets::allowance(id, &ALICE, &BOB), value); + assert_ok!(Fungibles::decrease_allowance(signed(ALICE), asset, BOB, 0)); + assert_eq!(Assets::allowance(asset, &ALICE, &BOB), value); // Decrease allowance successfully. - assert_ok!(Fungibles::decrease_allowance(signed(ALICE), id, BOB, value / 2)); - assert_eq!(Assets::allowance(id, &ALICE, &BOB), value / 2); - System::assert_last_event(Event::Approval { id, owner, spender, value: value / 2 }.into()); + assert_ok!(Fungibles::decrease_allowance(signed(ALICE), asset, BOB, value / 2)); + assert_eq!(Assets::allowance(asset, &ALICE, &BOB), value / 2); + System::assert_last_event( + Event::Approval { asset, owner, spender, value: value / 2 }.into(), + ); // Saturating if current allowance is decreased more than the owner balance. - assert_ok!(Fungibles::decrease_allowance(signed(ALICE), id, BOB, value)); - assert_eq!(Assets::allowance(id, &ALICE, &BOB), 0); - System::assert_last_event(Event::Approval { id, owner, spender, value: 0 }.into()); + assert_ok!(Fungibles::decrease_allowance(signed(ALICE), asset, BOB, value)); + assert_eq!(Assets::allowance(asset, &ALICE, &BOB), 0); + System::assert_last_event(Event::Approval { asset, owner, spender, value: 0 }.into()); }); } @@ -146,45 +156,45 @@ fn create_works() { #[test] fn start_destroy_works() { new_test_ext().execute_with(|| { - let id = ASSET; + let asset = ASSET; - create_asset(ALICE, id); - assert_ok!(Fungibles::start_destroy(signed(ALICE), id)); + create_asset(ALICE, asset); + assert_ok!(Fungibles::start_destroy(signed(ALICE), asset)); }); } #[test] fn set_metadata_works() { new_test_ext().execute_with(|| { - let id = ASSET; + let asset = ASSET; let name = vec![42]; let symbol = vec![42]; let decimals = 42; - create_asset(ALICE, id); + create_asset(ALICE, asset); assert_ok!(Fungibles::set_metadata( signed(ALICE), - id, + asset, name.clone(), symbol.clone(), decimals )); - assert_eq!(Assets::name(id), name); - assert_eq!(Assets::symbol(id), symbol); - assert_eq!(Assets::decimals(id), decimals); + assert_eq!(Assets::name(asset), name); + assert_eq!(Assets::symbol(asset), symbol); + assert_eq!(Assets::decimals(asset), decimals); }); } #[test] fn clear_metadata_works() { new_test_ext().execute_with(|| { - let id = ASSET; + let asset = ASSET; - create_asset_and_set_metadata(ALICE, id, vec![42], vec![42], 42); - assert_ok!(Fungibles::clear_metadata(signed(ALICE), id)); - assert!(Assets::name(id).is_empty()); - assert!(Assets::symbol(id).is_empty()); - assert!(Assets::decimals(id).is_zero()); + create_asset_and_set_metadata(ALICE, asset, vec![42], vec![42], 42); + assert_ok!(Fungibles::clear_metadata(signed(ALICE), asset)); + assert!(Assets::name(asset).is_empty()); + assert!(Assets::symbol(asset).is_empty()); + assert!(Assets::decimals(asset).is_zero()); }); } @@ -192,16 +202,16 @@ fn clear_metadata_works() { fn mint_works() { new_test_ext().execute_with(|| { let value: Balance = 100 * UNIT; - let id = ASSET; + let asset = ASSET; let from = None; let to = Some(BOB); - create_asset(ALICE, id); - let balance_before_mint = Assets::balance(id, &BOB); - assert_ok!(Fungibles::mint(signed(ALICE), id, BOB, value)); - let balance_after_mint = Assets::balance(id, &BOB); + create_asset(ALICE, asset); + let balance_before_mint = Assets::balance(asset, &BOB); + assert_ok!(Fungibles::mint(signed(ALICE), asset, BOB, value)); + let balance_after_mint = Assets::balance(asset, &BOB); assert_eq!(balance_after_mint, balance_before_mint + value); - System::assert_last_event(Event::Transfer { id, from, to, value }.into()); + System::assert_last_event(Event::Transfer { asset, from, to, value }.into()); }); } @@ -209,16 +219,16 @@ fn mint_works() { fn burn_works() { new_test_ext().execute_with(|| { let value: Balance = 100 * UNIT; - let id = ASSET; + let asset = ASSET; let from = Some(BOB); let to = None; - create_asset_and_mint_to(ALICE, id, BOB, value); - let balance_before_burn = Assets::balance(id, &BOB); - assert_ok!(Fungibles::burn(signed(ALICE), id, BOB, value)); - let balance_after_burn = Assets::balance(id, &BOB); + create_asset_and_mint_to(ALICE, asset, BOB, value); + let balance_before_burn = Assets::balance(asset, &BOB); + assert_ok!(Fungibles::burn(signed(ALICE), asset, BOB, value)); + let balance_after_burn = Assets::balance(asset, &BOB); assert_eq!(balance_after_burn, balance_before_burn - value); - System::assert_last_event(Event::Transfer { id, from, to, value }.into()); + System::assert_last_event(Event::Transfer { asset, from, to, value }.into()); }); } @@ -236,7 +246,7 @@ fn balance_of_works() { create_asset_and_mint_to(ALICE, ASSET, ALICE, 100); assert_eq!( Assets::balance(ASSET, ALICE).encode(), - Fungibles::read_state(BalanceOf { id: ASSET, owner: ALICE }) + Fungibles::read_state(BalanceOf { asset: ASSET, owner: ALICE }) ); }); } @@ -247,7 +257,7 @@ fn allowance_works() { create_asset_mint_and_approve(ALICE, ASSET, BOB, 100, ALICE, 50); assert_eq!( Assets::allowance(ASSET, &ALICE, &BOB).encode(), - Fungibles::read_state(Allowance { id: ASSET, owner: ALICE, spender: BOB }) + Fungibles::read_state(Allowance { asset: ASSET, owner: ALICE, spender: BOB }) ); }); } @@ -277,48 +287,48 @@ fn signed(account: AccountId) -> RuntimeOrigin { RuntimeOrigin::signed(account) } -fn create_asset(owner: AccountId, asset_id: AssetId) { - assert_ok!(Assets::create(signed(owner), asset_id, owner, 1)); +fn create_asset(owner: AccountId, asset_asset: AssetId) { + assert_ok!(Assets::create(signed(owner), asset_asset, owner, 1)); } -fn mint_asset(owner: AccountId, asset_id: AssetId, to: AccountId, value: Balance) { - assert_ok!(Assets::mint(signed(owner), asset_id, to, value)); +fn mint_asset(owner: AccountId, asset_asset: AssetId, to: AccountId, value: Balance) { + assert_ok!(Assets::mint(signed(owner), asset_asset, to, value)); } -fn create_asset_and_mint_to(owner: AccountId, asset_id: AssetId, to: AccountId, value: Balance) { - create_asset(owner, asset_id); - mint_asset(owner, asset_id, to, value) +fn create_asset_and_mint_to(owner: AccountId, asset_asset: AssetId, to: AccountId, value: Balance) { + create_asset(owner, asset_asset); + mint_asset(owner, asset_asset, to, value) } fn create_asset_mint_and_approve( owner: AccountId, - asset_id: AssetId, + asset_asset: AssetId, to: AccountId, mint: Balance, spender: AccountId, approve: Balance, ) { - create_asset_and_mint_to(owner, asset_id, to, mint); - assert_ok!(Assets::approve_transfer(signed(to), asset_id, spender, approve,)); + create_asset_and_mint_to(owner, asset_asset, to, mint); + assert_ok!(Assets::approve_transfer(signed(to), asset_asset, spender, approve,)); } fn create_asset_and_set_metadata( owner: AccountId, - asset_id: AssetId, + asset_asset: AssetId, name: Vec, symbol: Vec, decimals: u8, ) { - assert_ok!(Assets::create(signed(owner), asset_id, owner, 100)); - set_metadata_asset(owner, asset_id, name, symbol, decimals); + assert_ok!(Assets::create(signed(owner), asset_asset, owner, 100)); + set_metadata_asset(owner, asset_asset, name, symbol, decimals); } fn set_metadata_asset( owner: AccountId, - asset_id: AssetId, + asset_asset: AssetId, name: Vec, symbol: Vec, decimals: u8, ) { - assert_ok!(Assets::set_metadata(signed(owner), asset_id, name, symbol, decimals)); + assert_ok!(Assets::set_metadata(signed(owner), asset_asset, name, symbol, decimals)); } From 08115984fb33da05dbd735532f28bd1f464d99ef Mon Sep 17 00:00:00 2001 From: Daanvdplas Date: Mon, 19 Aug 2024 09:29:44 +0200 Subject: [PATCH 045/112] style: fix tests asset_asset parameter --- pallets/api/src/fungibles/tests.rs | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/pallets/api/src/fungibles/tests.rs b/pallets/api/src/fungibles/tests.rs index 9610139e..d881a3c1 100644 --- a/pallets/api/src/fungibles/tests.rs +++ b/pallets/api/src/fungibles/tests.rs @@ -287,48 +287,48 @@ fn signed(account: AccountId) -> RuntimeOrigin { RuntimeOrigin::signed(account) } -fn create_asset(owner: AccountId, asset_asset: AssetId) { - assert_ok!(Assets::create(signed(owner), asset_asset, owner, 1)); +fn create_asset(owner: AccountId, asset: AssetId) { + assert_ok!(Assets::create(signed(owner), asset, owner, 1)); } -fn mint_asset(owner: AccountId, asset_asset: AssetId, to: AccountId, value: Balance) { - assert_ok!(Assets::mint(signed(owner), asset_asset, to, value)); +fn mint_asset(owner: AccountId, asset: AssetId, to: AccountId, value: Balance) { + assert_ok!(Assets::mint(signed(owner), asset, to, value)); } -fn create_asset_and_mint_to(owner: AccountId, asset_asset: AssetId, to: AccountId, value: Balance) { - create_asset(owner, asset_asset); - mint_asset(owner, asset_asset, to, value) +fn create_asset_and_mint_to(owner: AccountId, asset: AssetId, to: AccountId, value: Balance) { + create_asset(owner, asset); + mint_asset(owner, asset, to, value) } fn create_asset_mint_and_approve( owner: AccountId, - asset_asset: AssetId, + asset: AssetId, to: AccountId, mint: Balance, spender: AccountId, approve: Balance, ) { - create_asset_and_mint_to(owner, asset_asset, to, mint); - assert_ok!(Assets::approve_transfer(signed(to), asset_asset, spender, approve,)); + create_asset_and_mint_to(owner, asset, to, mint); + assert_ok!(Assets::approve_transfer(signed(to), asset, spender, approve,)); } fn create_asset_and_set_metadata( owner: AccountId, - asset_asset: AssetId, + asset: AssetId, name: Vec, symbol: Vec, decimals: u8, ) { - assert_ok!(Assets::create(signed(owner), asset_asset, owner, 100)); - set_metadata_asset(owner, asset_asset, name, symbol, decimals); + assert_ok!(Assets::create(signed(owner), asset, owner, 100)); + set_metadata_asset(owner, asset, name, symbol, decimals); } fn set_metadata_asset( owner: AccountId, - asset_asset: AssetId, + asset: AssetId, name: Vec, symbol: Vec, decimals: u8, ) { - assert_ok!(Assets::set_metadata(signed(owner), asset_asset, name, symbol, decimals)); + assert_ok!(Assets::set_metadata(signed(owner), asset, name, symbol, decimals)); } From 6482a437ecd3028a63b307591369b990e3487612 Mon Sep 17 00:00:00 2001 From: Tin Chung <56880684+chungquantin@users.noreply.github.com> Date: Mon, 19 Aug 2024 15:06:50 +0700 Subject: [PATCH 046/112] fix: invalid imported crates & crate visibility (#214) --- pop-api/src/v0/assets/fungibles.rs | 2 +- runtime/devnet/src/config/mod.rs | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/pop-api/src/v0/assets/fungibles.rs b/pop-api/src/v0/assets/fungibles.rs index c881f823..4f270e6b 100644 --- a/pop-api/src/v0/assets/fungibles.rs +++ b/pop-api/src/v0/assets/fungibles.rs @@ -11,9 +11,9 @@ use crate::{ primitives::{AccountId, AssetId, Balance}, Result, StatusCode, }; -pub use asset_management::*; use constants::*; use ink::{env::chain_extension::ChainExtensionMethod, prelude::vec::Vec}; +pub use management::*; pub use metadata::*; // Helper method to build a dispatch call. diff --git a/runtime/devnet/src/config/mod.rs b/runtime/devnet/src/config/mod.rs index 1dcd44da..1ef83bc1 100644 --- a/runtime/devnet/src/config/mod.rs +++ b/runtime/devnet/src/config/mod.rs @@ -1,5 +1,6 @@ mod api; -mod assets; +// Public due to pop api integration tests crate. +pub mod assets; mod contracts; mod proxy; // Public due to integration tests crate. From 1b78c110f3a1a686fa86b5662097b032d2bbd3a2 Mon Sep 17 00:00:00 2001 From: Tin Chung <56880684+chungquantin@users.noreply.github.com> Date: Mon, 26 Aug 2024 20:04:08 +0700 Subject: [PATCH 047/112] ci: add CI script for `pop-api` tests and integration tests (#228) Co-authored-by: Daan van der Plas <93204684+Daanvdplas@users.noreply.github.com> --- .github/workflows/ci.yml | 28 +- Cargo.lock | 945 ++++++++++++++++----------- pop-api/Cargo.toml | 12 +- pop-api/integration-tests/Cargo.toml | 8 +- pop-api/integration-tests/build.rs | 57 ++ 5 files changed, 676 insertions(+), 374 deletions(-) create mode 100644 pop-api/integration-tests/build.rs diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a56a6bfb..283390f3 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -2,9 +2,9 @@ name: ci on: push: - branches: [ main ] + branches: [main] pull_request: - types: [ opened, synchronize, reopened, ready_for_review ] + types: [opened, synchronize, reopened, ready_for_review] jobs: lint: @@ -67,6 +67,28 @@ jobs: - name: Run integration tests run: cargo test --release --locked --package integration-tests + api-tests: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - uses: "./.github/actions/init" + + - name: Run tests + working-directory: pop-api + run: cargo test --release --all-features + + api-integration-tests: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - uses: "./.github/actions/init" + + - name: Run integration tests + working-directory: pop-api/integration-tests + run: cargo test --release + coverage: needs: lint runs-on: ubuntu-latest @@ -86,4 +108,4 @@ jobs: with: token: ${{ secrets.CODECOV_TOKEN }} files: codecov.json - fail_ci_if_error: true \ No newline at end of file + fail_ci_if_error: true diff --git a/Cargo.lock b/Cargo.lock index 3407a210..e2a4bbcd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -36,6 +36,12 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" +[[package]] +name = "adler2" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" + [[package]] name = "aead" version = "0.5.2" @@ -142,9 +148,9 @@ dependencies = [ [[package]] name = "anstream" -version = "0.6.15" +version = "0.6.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64e15c1ab1f89faffbf04a634d5e1962e9074f2741eef6d97f3c4e322426d526" +checksum = "418c75fa768af9c03be99d17643f93f79bbba589895012a80e3452a19ddda15b" dependencies = [ "anstyle", "anstyle-parse", @@ -157,33 +163,33 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.8" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1" +checksum = "038dfcf04a5feb68e9c60b21c9625a54c2c0616e79b72b0fd87075a056ae1d1b" [[package]] name = "anstyle-parse" -version = "0.2.5" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb47de1e80c2b463c735db5b217a0ddc39d612e7ac9e2e96a5aed1f57616c1cb" +checksum = "c03a11a9034d92058ceb6ee011ce58af4a9bf61491aa7e1e59ecd24bd40d22d4" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" -version = "1.1.1" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d36fc52c7f6c869915e99412912f22093507da8d9e942ceaf66fe4b7c14422a" +checksum = "ad186efb764318d35165f1758e7dcef3b10628e26d41a44bc5550652e6804391" dependencies = [ "windows-sys 0.52.0", ] [[package]] name = "anstyle-wincon" -version = "3.0.4" +version = "3.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5bf74e1b6e971609db8ca7a9ce79fd5768ab6ae46441c572e46cf596f59e57f8" +checksum = "61a38449feb7068f52bb06c12759005cf459ee52bb4adc1d5a7c4322d716fb19" dependencies = [ "anstyle", "windows-sys 0.52.0", @@ -215,7 +221,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.66", ] [[package]] @@ -361,9 +367,9 @@ checksum = "5d5dde061bd34119e902bbb2d9b90c5692635cf59fb91d582c2b68043f1b8293" [[package]] name = "arrayref" -version = "0.3.8" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d151e35f61089500b617991b791fc8bfd237ae50cd5950803758a179b41e67a" +checksum = "6b4930d2cb77ce62f89ee5d5289b4ac049559b1c45539271f5ed4fdc7db34545" [[package]] name = "arrayvec" @@ -584,9 +590,9 @@ dependencies = [ [[package]] name = "async-executor" -version = "1.13.0" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7ebdfa2ebdab6b1760375fa7d6f382b9f486eac35fc994625a00e89280bdbb7" +checksum = "c8828ec6e544c02b0d6691d21ed9f9218d0384a82542855073c2a3f58304aaf0" dependencies = [ "async-task", "concurrent-queue", @@ -629,9 +635,9 @@ dependencies = [ [[package]] name = "async-io" -version = "2.3.4" +version = "2.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "444b0228950ee6501b3568d3c93bf1176a1fdbc3b758dcd9475046d30f4dc7e8" +checksum = "0d6baa8f0178795da0e71bc42c9e5d13261aac7ee549853162e66a241ba17964" dependencies = [ "async-lock 3.4.0", "cfg-if", @@ -639,11 +645,11 @@ dependencies = [ "futures-io", "futures-lite 2.3.0", "parking", - "polling 3.7.3", + "polling 3.7.2", "rustix 0.38.34", "slab", "tracing", - "windows-sys 0.59.0", + "windows-sys 0.52.0", ] [[package]] @@ -696,11 +702,11 @@ dependencies = [ [[package]] name = "async-signal" -version = "0.2.10" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "637e00349800c0bdf8bfc21ebbc0b6524abea702b0da4168ac00d070d0c0b9f3" +checksum = "794f185324c2f00e771cd9f1ae8b5ac68be2ca7abb129a87afd6e86d228bc54d" dependencies = [ - "async-io 2.3.4", + "async-io 2.3.3", "async-lock 3.4.0", "atomic-waker", "cfg-if", @@ -709,7 +715,7 @@ dependencies = [ "rustix 0.38.34", "signal-hook-registry", "slab", - "windows-sys 0.59.0", + "windows-sys 0.52.0", ] [[package]] @@ -720,13 +726,13 @@ checksum = "8b75356056920673b02621b35afd0f7dda9306d03c79a30f5c56c44cf256e3de" [[package]] name = "async-trait" -version = "0.1.81" +version = "0.1.80" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e0c28dcc82d7c8ead5cb13beb15405b57b8546e93215673ff8ca0349a028107" +checksum = "c6fa2087f2753a7da8cc1c0dbfcf89579dd57458e36769de5ac750b4671737ca" dependencies = [ "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.66", ] [[package]] @@ -770,8 +776,8 @@ dependencies = [ "cc", "cfg-if", "libc", - "miniz_oxide", - "object 0.36.3", + "miniz_oxide 0.7.3", + "object 0.36.0", "rustc-demangle", ] @@ -851,7 +857,7 @@ dependencies = [ "regex", "rustc-hash", "shlex", - "syn 2.0.74", + "syn 2.0.66", ] [[package]] @@ -881,9 +887,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.6.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" [[package]] name = "bitvec" @@ -953,9 +959,9 @@ dependencies = [ [[package]] name = "blake3" -version = "1.5.3" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9ec96fe9a81b5e365f9db71fe00edc4fe4ca2cc7dcb7861f0603012a7caa210" +checksum = "30cca6d3674597c30ddf2c587bf8d9d65c9a84d2326d941cc79c9842dfe0ef52" dependencies = [ "arrayref", "arrayvec 0.7.4", @@ -1293,9 +1299,9 @@ checksum = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7" [[package]] name = "bytemuck" -version = "1.16.3" +version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "102087e286b4677862ea56cf8fc58bb2cdfa8725c40ffb80fe3a008eb7f2fc83" +checksum = "78834c15cb5d5efe3452d58b1e8ba890dd62d21907f867f383358198e56ebca5" [[package]] name = "byteorder" @@ -1305,9 +1311,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.7.1" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8318a53db07bb3f8dca91a600466bdb3f2eaadeedfdbcf02e1accbad9271ba50" +checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9" [[package]] name = "bzip2-sys" @@ -1364,12 +1370,13 @@ dependencies = [ [[package]] name = "cc" -version = "1.1.10" +version = "1.0.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9e8aabfac534be767c909e0690571677d49f41bd8465ae876fe043d52ba5292" +checksum = "96c51067fd44124faa7f870b4b1c969379ad32b2ba805aa959430ceaa384f695" dependencies = [ "jobserver", "libc", + "once_cell", ] [[package]] @@ -1447,7 +1454,7 @@ dependencies = [ "js-sys", "num-traits", "wasm-bindgen", - "windows-targets 0.52.6", + "windows-targets 0.52.5", ] [[package]] @@ -1505,9 +1512,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.15" +version = "4.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11d8838454fda655dafd3accb2b6e2bea645b9e4078abe84a22ceb947235c5cc" +checksum = "5db83dced34638ad474f39f250d7fea9598bdd239eaced1bdf45d597da0f433f" dependencies = [ "clap_builder", "clap_derive", @@ -1515,9 +1522,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.15" +version = "4.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "216aec2b177652e3846684cbfe25c9964d18ec45234f0f5da5157b207ed1aab6" +checksum = "f7e204572485eb3fbf28f871612191521df159bc3e15a9f5064c66dba3a8c05f" dependencies = [ "anstream", "anstyle", @@ -1528,21 +1535,21 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.13" +version = "4.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "501d359d5f3dcaf6ecdeee48833ae73ec6e42723a1e52419c79abf9507eec0a0" +checksum = "c780290ccf4fb26629baa7a1081e68ced113f1d3ec302fa5948f1c381ebf06c6" dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.66", ] [[package]] name = "clap_lex" -version = "0.7.2" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97" +checksum = "4b82cf0babdbd58558212896d1a4272303a57bdb245c2bf1147185fb45640e70" [[package]] name = "coarsetime" @@ -1583,14 +1590,14 @@ dependencies = [ "nom", "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.66", ] [[package]] name = "colorchoice" -version = "1.0.2" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3fd119d74b830634cea2a0f58bbd0d54540518a14397557951e79340abc28c0" +checksum = "0b6a852b24ab71dffc585bcb46eaf7959d175cb865a7152e35b348d1b2960422" [[package]] name = "comfy-table" @@ -1598,7 +1605,7 @@ version = "7.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b34115915337defe99b2aff5c2ce6771e5fbc4079f4b506301f5cf394c8452f7" dependencies = [ - "strum 0.26.3", + "strum 0.26.2", "strum_macros 0.26.4", "unicode-width", ] @@ -1693,9 +1700,9 @@ dependencies = [ [[package]] name = "core-foundation-sys" -version = "0.8.7" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" +checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" [[package]] name = "core2" @@ -1727,9 +1734,9 @@ dependencies = [ [[package]] name = "cpufeatures" -version = "0.2.13" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51e852e6dc9a5bed1fae92dd2375037bf2b768725bf3be87811edee3249d09ad" +checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" dependencies = [ "libc", ] @@ -2249,7 +2256,7 @@ dependencies = [ "proc-macro-crate 3.1.0", "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.66", ] [[package]] @@ -2569,7 +2576,7 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.66", ] [[package]] @@ -2609,7 +2616,7 @@ dependencies = [ "proc-macro2", "quote", "scratch", - "syn 2.0.74", + "syn 2.0.66", ] [[package]] @@ -2626,7 +2633,7 @@ checksum = "4b2c1c1776b986979be68bb2285da855f8d8a35851a769fca8740df7c3d07877" dependencies = [ "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.66", ] [[package]] @@ -2718,7 +2725,7 @@ checksum = "d65d7ce8132b7c0e54497a4d9a55a1c2a0912a0d786cf894472ba818fba45762" dependencies = [ "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.66", ] [[package]] @@ -2731,7 +2738,7 @@ dependencies = [ "proc-macro2", "quote", "rustc_version", - "syn 2.0.74", + "syn 2.0.66", ] [[package]] @@ -2814,13 +2821,13 @@ dependencies = [ [[package]] name = "displaydoc" -version = "0.2.5" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" +checksum = "487585f4d0c6655fe74905e2504d8ad6908e4db67f744eb140876906c2f3175d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.66", ] [[package]] @@ -2844,9 +2851,9 @@ dependencies = [ "proc-macro2", "quote", "regex", - "syn 2.0.74", + "syn 2.0.66", "termcolor", - "toml 0.8.19", + "toml 0.8.14", "walkdir", ] @@ -2965,9 +2972,9 @@ dependencies = [ [[package]] name = "either" -version = "1.13.0" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" +checksum = "3dca9240753cf90908d7e4aac30f630662b02aebaa1b58a3cadabdb23385b58b" [[package]] name = "elliptic-curve" @@ -3056,18 +3063,18 @@ checksum = "de0d48a183585823424a4ce1aa132d174a6a81bd540895822eb4c8373a8e49e8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.66", ] [[package]] name = "enumn" -version = "0.1.14" +version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f9ed6b3789237c8a0c1c505af1c7eb2c560df6186f01b098c3a1064ea532f38" +checksum = "6fd000fd6988e73bbe993ea3db9b1aa64906ab88766d654973924340c8cddb42" dependencies = [ "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.66", ] [[package]] @@ -3240,7 +3247,7 @@ dependencies = [ "prettyplease 0.2.20", "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.66", ] [[package]] @@ -3337,14 +3344,14 @@ dependencies = [ [[package]] name = "filetime" -version = "0.2.24" +version = "0.2.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf401df4a4e3872c4fe8151134cf483738e74b67fc934d6532c882b3d24a4550" +checksum = "1ee447700ac8aa0b2f2bd7bc4462ad686ba06baa6727ac149a2d6277f0d240fd" dependencies = [ "cfg-if", "libc", - "libredox", - "windows-sys 0.59.0", + "redox_syscall 0.4.1", + "windows-sys 0.52.0", ] [[package]] @@ -3383,13 +3390,13 @@ checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" [[package]] name = "flate2" -version = "1.0.31" +version = "1.0.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f211bbe8e69bbd0cfdea405084f128ae8b4aaa6b0b522fc8f2b009084797920" +checksum = "9c0596c1eac1f9e04ed902702e9878208b336edc9d6fddc8a48387349bab3666" dependencies = [ "crc32fast", "libz-sys", - "miniz_oxide", + "miniz_oxide 0.8.0", ] [[package]] @@ -3515,7 +3522,7 @@ dependencies = [ "proc-macro-crate 3.1.0", "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.66", ] [[package]] @@ -3665,7 +3672,7 @@ dependencies = [ "proc-macro2", "quote", "sp-crypto-hashing", - "syn 2.0.74", + "syn 2.0.66", ] [[package]] @@ -3678,7 +3685,7 @@ dependencies = [ "proc-macro-crate 3.1.0", "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.66", ] [[package]] @@ -3689,7 +3696,7 @@ checksum = "68672b9ec6fe72d259d3879dc212c5e42e977588cdac830c76f54d9f492aeb58" dependencies = [ "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.66", ] [[package]] @@ -3872,7 +3879,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.66", ] [[package]] @@ -4049,7 +4056,7 @@ dependencies = [ "futures-sink", "futures-util", "http", - "indexmap 2.3.0", + "indexmap 2.2.6", "slab", "tokio", "tokio-util", @@ -4276,9 +4283,9 @@ checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" [[package]] name = "hyper" -version = "0.14.30" +version = "0.14.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a152ddd61dfaec7273fe8419ab357f33aee0d914c5f4efbf0d96fa749eea5ec9" +checksum = "f361cde2f109281a220d4307746cdfd5ee3f410da58a70377762396775634b33" dependencies = [ "bytes", "futures-channel", @@ -4325,7 +4332,7 @@ dependencies = [ "iana-time-zone-haiku", "js-sys", "wasm-bindgen", - "windows-core 0.52.0", + "windows-core", ] [[package]] @@ -4337,6 +4344,124 @@ dependencies = [ "cc", ] +[[package]] +name = "icu_collections" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db2fa452206ebee18c4b5c2274dbf1de17008e874b4dc4f0aea9d01ca79e4526" +dependencies = [ + "displaydoc", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_locid" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13acbb8371917fc971be86fc8057c41a64b521c184808a698c02acc242dbf637" +dependencies = [ + "displaydoc", + "litemap", + "tinystr", + "writeable", + "zerovec", +] + +[[package]] +name = "icu_locid_transform" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01d11ac35de8e40fdeda00d9e1e9d92525f3f9d887cdd7aa81d727596788b54e" +dependencies = [ + "displaydoc", + "icu_locid", + "icu_locid_transform_data", + "icu_provider", + "tinystr", + "zerovec", +] + +[[package]] +name = "icu_locid_transform_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdc8ff3388f852bede6b579ad4e978ab004f139284d7b28715f773507b946f6e" + +[[package]] +name = "icu_normalizer" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19ce3e0da2ec68599d193c93d088142efd7f9c5d6fc9b803774855747dc6a84f" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_normalizer_data", + "icu_properties", + "icu_provider", + "smallvec", + "utf16_iter", + "utf8_iter", + "write16", + "zerovec", +] + +[[package]] +name = "icu_normalizer_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8cafbf7aa791e9b22bec55a167906f9e1215fd475cd22adfcf660e03e989516" + +[[package]] +name = "icu_properties" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f8ac670d7422d7f76b32e17a5db556510825b29ec9154f235977c9caba61036" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_locid_transform", + "icu_properties_data", + "icu_provider", + "tinystr", + "zerovec", +] + +[[package]] +name = "icu_properties_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67a8effbc3dd3e4ba1afa8ad918d5684b8868b3b26500753effea8d2eed19569" + +[[package]] +name = "icu_provider" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ed421c8a8ef78d3e2dbc98a973be2f3770cb42b606e3ab18d6237c4dfde68d9" +dependencies = [ + "displaydoc", + "icu_locid", + "icu_provider_macros", + "stable_deref_trait", + "tinystr", + "writeable", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_provider_macros" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.66", +] + [[package]] name = "idna" version = "0.2.3" @@ -4350,12 +4475,14 @@ dependencies = [ [[package]] name = "idna" -version = "0.5.0" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" +checksum = "4716a3a0933a1d01c2f72450e89596eb51dd34ef3c211ccd875acdf1f8fe47ed" dependencies = [ - "unicode-bidi", - "unicode-normalization", + "icu_normalizer", + "icu_properties", + "smallvec", + "utf8_iter", ] [[package]] @@ -4374,7 +4501,7 @@ version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d6b0422c86d7ce0e97169cc42e04ae643caf278874a7a3c87b8150a220dc7e1e" dependencies = [ - "async-io 2.3.4", + "async-io 2.3.3", "core-foundation", "fnv", "futures", @@ -4468,9 +4595,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.3.0" +version = "2.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de3fc2e30ba82dd1b3911c8de1ffc143c74a914a14e99514d7637e3099df5ea0" +checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" dependencies = [ "equivalent", "hashbrown 0.14.5", @@ -4617,9 +4744,9 @@ dependencies = [ [[package]] name = "is_terminal_polyfill" -version = "1.70.1" +version = "1.70.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" +checksum = "f8478577c03552c21db0e2724ffb8986a5ce7af88107e6be5d2ee6e158c12800" [[package]] name = "itertools" @@ -4639,15 +4766,6 @@ dependencies = [ "either", ] -[[package]] -name = "itertools" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" -dependencies = [ - "either", -] - [[package]] name = "itoa" version = "1.0.11" @@ -4656,27 +4774,27 @@ checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" [[package]] name = "jobserver" -version = "0.1.32" +version = "0.1.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48d1dbcbbeb6a7fec7e059840aa538bd62aaccf972c7346c4d9d2059312853d0" +checksum = "d2b099aaa34a9751c5bf0878add70444e1ed2dd73f347be99003d4577277de6e" dependencies = [ "libc", ] [[package]] name = "js-sys" -version = "0.3.70" +version = "0.3.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1868808506b929d7b0cfa8f75951347aa71bb21144b7791bae35d9bccfcfe37a" +checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" dependencies = [ "wasm-bindgen", ] [[package]] name = "jsonrpsee" -version = "0.20.3" +version = "0.20.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "affdc52f7596ccb2d7645231fc6163bb314630c989b64998f3699a28b4d5d4dc" +checksum = "138572befc78a9793240645926f30161f8b4143d2be18d09e44ed9814bd7ee2c" dependencies = [ "jsonrpsee-core", "jsonrpsee-http-client", @@ -4690,9 +4808,9 @@ dependencies = [ [[package]] name = "jsonrpsee-client-transport" -version = "0.20.3" +version = "0.20.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5b005c793122d03217da09af68ba9383363caa950b90d3436106df8cabce935" +checksum = "5c671353e4adf926799107bd7f5724a06b6bc0a333db442a0843c58640bdd0c1" dependencies = [ "futures-util", "http", @@ -4710,9 +4828,9 @@ dependencies = [ [[package]] name = "jsonrpsee-core" -version = "0.20.3" +version = "0.20.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da2327ba8df2fdbd5e897e2b5ed25ce7f299d345b9736b6828814c3dbd1fd47b" +checksum = "f24ea59b037b6b9b0e2ebe2c30a3e782b56bd7c76dcc5d6d70ba55d442af56e3" dependencies = [ "anyhow", "async-lock 2.8.0", @@ -4735,9 +4853,9 @@ dependencies = [ [[package]] name = "jsonrpsee-http-client" -version = "0.20.3" +version = "0.20.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f80c17f62c7653ce767e3d7288b793dfec920f97067ceb189ebdd3570f2bc20" +checksum = "57c7b9f95208927653e7965a98525e7fc641781cab89f0e27c43fa2974405683" dependencies = [ "async-trait", "hyper", @@ -4755,9 +4873,9 @@ dependencies = [ [[package]] name = "jsonrpsee-proc-macros" -version = "0.20.3" +version = "0.20.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29110019693a4fa2dbda04876499d098fa16d70eba06b1e6e2b3f1b251419515" +checksum = "dcc0eba68ba205452bcb4c7b80a79ddcb3bf36c261a841b239433142db632d24" dependencies = [ "heck 0.4.1", "proc-macro-crate 1.1.3", @@ -4768,9 +4886,9 @@ dependencies = [ [[package]] name = "jsonrpsee-server" -version = "0.20.3" +version = "0.20.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82c39a00449c9ef3f50b84fc00fc4acba20ef8f559f07902244abf4c15c5ab9c" +checksum = "a482bc4e25eebd0adb61a3468c722763c381225bd3ec46e926f709df8a8eb548" dependencies = [ "futures-util", "http", @@ -4791,9 +4909,9 @@ dependencies = [ [[package]] name = "jsonrpsee-types" -version = "0.20.3" +version = "0.20.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5be0be325642e850ed0bdff426674d2e66b2b7117c9be23a7caef68a2902b7d9" +checksum = "3264e339143fe37ed081953842ee67bfafa99e3b91559bdded6e4abd8fc8535e" dependencies = [ "anyhow", "beef", @@ -4805,9 +4923,9 @@ dependencies = [ [[package]] name = "jsonrpsee-ws-client" -version = "0.20.3" +version = "0.20.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bca9cb3933ccae417eb6b08c3448eb1cb46e39834e5b503e395e5e5bd08546c0" +checksum = "6d06eeabbb55f0af8405288390a358ebcceb6e79e1390741e6f152309c4d6076" dependencies = [ "http", "jsonrpsee-client-transport", @@ -4890,9 +5008,9 @@ dependencies = [ [[package]] name = "lazy_static" -version = "1.5.0" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "lazycell" @@ -4908,12 +5026,12 @@ checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" [[package]] name = "libloading" -version = "0.8.5" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4979f22fdb869068da03c9f7528f8297c6fd2606bc3a4affe42e6a823fdb8da4" +checksum = "0c2a198fb6b0eada2a8df47933734e6d35d350665a33a3593d7164fa52c75c19" dependencies = [ "cfg-if", - "windows-targets 0.52.6", + "windows-targets 0.52.5", ] [[package]] @@ -5321,9 +5439,8 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.5.0", "libc", - "redox_syscall 0.5.3", ] [[package]] @@ -5391,9 +5508,9 @@ dependencies = [ [[package]] name = "libz-sys" -version = "1.1.19" +version = "1.1.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdc53a7799a7496ebc9fd29f31f7df80e83c9bda5299768af5f9e59eeea74647" +checksum = "c15da26e5af7e25c90b37a2d75cdbf940cf4a55316de9d84c679c9b8bfabf82e" dependencies = [ "cc", "pkg-config", @@ -5463,6 +5580,12 @@ dependencies = [ "keystream", ] +[[package]] +name = "litemap" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "643cb0b8d4fcc284004d5fd0d67ccf61dfffadb7f75e1e71bc420f4688a3a704" + [[package]] name = "lock_api" version = "0.4.12" @@ -5475,9 +5598,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.22" +version = "0.4.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" +checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" [[package]] name = "lru" @@ -5514,9 +5637,9 @@ dependencies = [ [[package]] name = "lz4" -version = "1.26.0" +version = "1.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "958b4caa893816eea05507c20cfe47574a43d9a697138a7872990bba8a0ece68" +checksum = "d6eab492fe7f8651add23237ea56dbf11b3c4ff762ab83d40a47f11433421f91" dependencies = [ "libc", "lz4-sys", @@ -5524,9 +5647,9 @@ dependencies = [ [[package]] name = "lz4-sys" -version = "1.10.0" +version = "1.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "109de74d5d2353660401699a4174a4ff23fcc649caf553df71933c7fb45ad868" +checksum = "e9764018d143cc854c9f17f0b907de70f14393b1f502da6375dce70f00514eb3" dependencies = [ "cc", "libc", @@ -5550,7 +5673,7 @@ dependencies = [ "macro_magic_core", "macro_magic_macros", "quote", - "syn 2.0.74", + "syn 2.0.66", ] [[package]] @@ -5564,7 +5687,7 @@ dependencies = [ "macro_magic_core_macros", "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.66", ] [[package]] @@ -5575,7 +5698,7 @@ checksum = "b02abfe41815b5bd98dbd4260173db2c116dda171dc0fe7838cb206333b83308" dependencies = [ "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.66", ] [[package]] @@ -5586,7 +5709,7 @@ checksum = "73ea28ee64b88876bf45277ed9a5817c1817df061a74f2b988971a12570e5869" dependencies = [ "macro_magic_core", "quote", - "syn 2.0.74", + "syn 2.0.66", ] [[package]] @@ -5627,9 +5750,9 @@ checksum = "2532096657941c2fea9c289d370a250971c689d4f143798ff67113ec042024a5" [[package]] name = "matrixmultiply" -version = "0.3.9" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9380b911e3e96d10c1f415da0876389aaf1b56759054eeb0de7df940c456ba1a" +checksum = "7574c1cf36da4798ab73da5b215bbf444f50718207754cb522201d78d1cd0ff2" dependencies = [ "autocfg", "rawpointer", @@ -5717,23 +5840,31 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] name = "miniz_oxide" -version = "0.7.4" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8a240ddb74feaf34a79a7add65a741f3167852fba007066dcac1ca548d89c08" +checksum = "87dfd01fe195c66b572b37921ad8803d010623c0aca821bea2302239d155cdae" dependencies = [ "adler", ] +[[package]] +name = "miniz_oxide" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2d80299ef12ff69b16a84bb182e3b9df68b5a91574d3d4fa6e41b65deec4df1" +dependencies = [ + "adler2", +] + [[package]] name = "mio" -version = "1.0.2" +version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80e04d1dcff3aae0704555fe5fee3bcfaf3d1fdf8a7e521d5b9d2b42acb52cec" +checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" dependencies = [ - "hermit-abi 0.3.9", "libc", "wasi 0.11.0+wasi-snapshot-preview1", - "windows-sys 0.52.0", + "windows-sys 0.48.0", ] [[package]] @@ -5949,7 +6080,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.66", "synstructure 0.13.1", ] @@ -5991,13 +6122,13 @@ dependencies = [ [[package]] name = "nalgebra-macros" -version = "0.2.2" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "254a5372af8fc138e36684761d3c0cdb758a4410e938babcff1c860ce14ddbfc" +checksum = "91761aed67d03ad966ef783ae962ef9bbaca728d2dd7ceb7939ec110fffad998" dependencies = [ "proc-macro2", "quote", - "syn 2.0.74", + "syn 1.0.109", ] [[package]] @@ -6098,7 +6229,7 @@ version = "0.27.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2eb04e9c688eff1c89d72b407f168cf79bb9e867a9d3323ed6c01519eb9cc053" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.5.0", "cfg-if", "libc", ] @@ -6139,9 +6270,9 @@ checksum = "61807f77802ff30975e01f4f071c8ba10c022052f98b3294119f3e615d13e5be" [[package]] name = "num-bigint" -version = "0.4.6" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" +checksum = "c165a9ab64cf766f73521c0dd2cfdff64f488b8f0b3e621face3462d3db536d7" dependencies = [ "num-integer", "num-traits", @@ -6232,9 +6363,9 @@ dependencies = [ [[package]] name = "object" -version = "0.36.3" +version = "0.36.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "27b64972346851a39438c60b341ebc01bba47464ae329e55cf343eb93964efd9" +checksum = "576dfe1fc8f9df304abb159d767a29d0476f7750fbf8aa7ad07816004a207434" dependencies = [ "memchr", ] @@ -6302,7 +6433,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1344346d5af32c95bbddea91b18a88cc83eac394192d20ef2fc4c40a74332355" dependencies = [ "expander 2.2.1", - "indexmap 2.3.0", + "indexmap 2.2.6", "itertools 0.11.0", "petgraph", "proc-macro-crate 3.1.0", @@ -6808,7 +6939,7 @@ checksum = "3163c6bc21b55a0ccb74c546ba784d9c9e69beb9240c059d28a3052f4cbce509" dependencies = [ "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.66", ] [[package]] @@ -7476,7 +7607,7 @@ dependencies = [ "proc-macro-crate 3.1.0", "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.66", ] [[package]] @@ -7979,9 +8110,9 @@ checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" dependencies = [ "cfg-if", "libc", - "redox_syscall 0.5.3", + "redox_syscall 0.5.2", "smallvec", - "windows-targets 0.52.6", + "windows-targets 0.52.5", ] [[package]] @@ -8147,9 +8278,9 @@ checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "pest" -version = "2.7.11" +version = "2.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd53dff83f26735fdc1ca837098ccf133605d794cdae66acfc2bfac3ec809d95" +checksum = "560131c633294438da9f7c4b08189194b20946c8274c6b9e38881a7874dc8ee8" dependencies = [ "memchr", "thiserror", @@ -8158,9 +8289,9 @@ dependencies = [ [[package]] name = "pest_derive" -version = "2.7.11" +version = "2.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a548d2beca6773b1c244554d36fcf8548a8a58e74156968211567250e48e49a" +checksum = "26293c9193fbca7b1a3bf9b79dc1e388e927e6cacaa78b4a3ab705a1d3d41459" dependencies = [ "pest", "pest_generator", @@ -8168,22 +8299,22 @@ dependencies = [ [[package]] name = "pest_generator" -version = "2.7.11" +version = "2.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c93a82e8d145725dcbaf44e5ea887c8a869efdcc28706df2d08c69e17077183" +checksum = "3ec22af7d3fb470a85dd2ca96b7c577a1eb4ef6f1683a9fe9a8c16e136c04687" dependencies = [ "pest", "pest_meta", "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.66", ] [[package]] name = "pest_meta" -version = "2.7.11" +version = "2.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a941429fea7e08bedec25e4f6785b6ffaacc6b755da98df5ef3e7dcf4a124c4f" +checksum = "d7a240022f37c361ec1878d646fc5b7d7c4d28d5946e1a80ad5a7a4f4ca0bdcd" dependencies = [ "once_cell", "pest", @@ -8197,7 +8328,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4c5cc86750666a3ed20bdaf5ca2a0344f9c67674cae0515bec2da16fbaa47db" dependencies = [ "fixedbitset", - "indexmap 2.3.0", + "indexmap 2.2.6", ] [[package]] @@ -8217,7 +8348,7 @@ checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" dependencies = [ "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.66", ] [[package]] @@ -8240,9 +8371,9 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "piper" -version = "0.2.4" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96c8c490f422ef9a4efd2cb5b42b76c8613d7e7dfc1caf667b8a3350a5acc066" +checksum = "ae1d5c74c9876f070d3e8fd503d748c7d974c3e48da8f41350fa5222ef9b4391" dependencies = [ "atomic-waker", "fastrand 2.1.0", @@ -8426,7 +8557,7 @@ dependencies = [ "fatality", "futures", "futures-timer", - "indexmap 2.3.0", + "indexmap 2.2.6", "parity-scale-codec", "polkadot-erasure-coding", "polkadot-node-network-protocol", @@ -9353,7 +9484,7 @@ dependencies = [ "fatality", "futures", "futures-timer", - "indexmap 2.3.0", + "indexmap 2.2.6", "parity-scale-codec", "polkadot-node-network-protocol", "polkadot-node-primitives", @@ -9391,7 +9522,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6380dbe1fb03ecc74ad55d841cfc75480222d153ba69ddcb00977866cbdabdb8" dependencies = [ "polkavm-derive-impl", - "syn 2.0.74", + "syn 2.0.66", ] [[package]] @@ -9403,7 +9534,7 @@ dependencies = [ "polkavm-common", "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.66", ] [[package]] @@ -9424,9 +9555,9 @@ dependencies = [ [[package]] name = "polling" -version = "3.7.3" +version = "3.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc2790cd301dec6cd3b7a025e4815cf825724a51c98dccfe6a3e55f05ffb6511" +checksum = "a3ed00ed3fbf728b5816498ecd316d1716eecaced9c0c8d2c5a6740ca214985b" dependencies = [ "cfg-if", "concurrent-queue", @@ -9434,7 +9565,7 @@ dependencies = [ "pin-project-lite 0.2.14", "rustix 0.38.34", "tracing", - "windows-sys 0.59.0", + "windows-sys 0.52.0", ] [[package]] @@ -9709,9 +9840,9 @@ dependencies = [ [[package]] name = "portable-atomic" -version = "1.7.0" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da544ee218f0d287a911e9c99a39a8c9bc8fcad3cb8db5959940044ecfc67265" +checksum = "7170ef9988bc169ba16dd36a7fa041e5c4cbeb6a35b76d4c03daded371eae7c0" [[package]] name = "powerfmt" @@ -9721,12 +9852,9 @@ checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" [[package]] name = "ppv-lite86" -version = "0.2.20" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" -dependencies = [ - "zerocopy", -] +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" [[package]] name = "predicates" @@ -9744,15 +9872,15 @@ dependencies = [ [[package]] name = "predicates-core" -version = "1.0.8" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae8177bee8e75d6846599c6b9ff679ed51e882816914eec639944d7c9aa11931" +checksum = "b794032607612e7abeb4db69adb4e33590fa6cf1149e95fd7cb00e634b92f174" [[package]] name = "predicates-tree" -version = "1.0.11" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41b740d195ed3166cd147c8047ec98db0e22ec019eb8eeb76d343b795304fb13" +checksum = "368ba315fb8c5052ab692e68a0eefec6ec57b23a36959c14496f0b0df2c0cecf" dependencies = [ "predicates-core", "termtree", @@ -9775,7 +9903,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5f12335488a2f3b0a83b14edad48dca9879ce89b2edd10e80237e4e852dd645e" dependencies = [ "proc-macro2", - "syn 2.0.74", + "syn 2.0.66", ] [[package]] @@ -9869,14 +9997,14 @@ checksum = "834da187cfe638ae8abb0203f0b33e5ccdb02a28e7199f2f47b3e2754f50edca" dependencies = [ "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.66", ] [[package]] name = "proc-macro2" -version = "1.0.86" +version = "1.0.85" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" +checksum = "22244ce15aa966053a896d1accb3a6e68469b97c7f33f284b99f0d576879fc23" dependencies = [ "unicode-ident", ] @@ -9915,7 +10043,7 @@ checksum = "440f724eba9f6996b75d63681b0a92b06947f1457076d503a4d2e2c8f56442b8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.66", ] [[package]] @@ -9980,10 +10108,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "81bddcdb20abf9501610992b6759a4c888aef7d1a7247ef75e2404275ac24af1" dependencies = [ "anyhow", - "itertools 0.12.1", + "itertools 0.11.0", "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.66", ] [[package]] @@ -10193,11 +10321,20 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.5.3" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" +dependencies = [ + "bitflags 1.3.2", +] + +[[package]] +name = "redox_syscall" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a908a6e00f1fdd0dfd9c0eb08ce85126f6d8bbda50017e74bc4a4b7d4a926a4" +checksum = "c82cf8cff14456045f55ec4241383baeff27af886adb72ffb2162f99911de0fd" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.5.0", ] [[package]] @@ -10240,7 +10377,7 @@ checksum = "bcc303e793d3734489387d205e9b186fac9c6cfacedd98cbb2e8a5943595f3e6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.66", ] [[package]] @@ -10257,9 +10394,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.10.6" +version = "1.10.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4219d74c6b67a3654a9fbebc4b419e22126d13d2f3c4a07ee0cb61ff79a79619" +checksum = "b91213439dad192326a0d7c6ee3955910425f441d7038e0d6933b0aec5c4517f" dependencies = [ "aho-corasick", "memchr", @@ -10605,7 +10742,7 @@ version = "0.38.34" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.5.0", "errno", "libc", "linux-raw-sys 0.4.14", @@ -10836,7 +10973,7 @@ dependencies = [ "proc-macro-crate 3.1.0", "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.66", ] [[package]] @@ -11850,7 +11987,7 @@ dependencies = [ "proc-macro-crate 3.1.0", "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.66", ] [[package]] @@ -12069,11 +12206,11 @@ dependencies = [ [[package]] name = "security-framework" -version = "2.11.1" +version = "2.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" +checksum = "c627723fd09706bacdb5cf41499e95098555af3c3c29d014dc3c458ef6be11c0" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.5.0", "core-foundation", "core-foundation-sys", "libc", @@ -12082,9 +12219,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.11.1" +version = "2.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75da29fe9b9b08fe9d6b22b5b4bcbc75d8db3aa31e639aa56bb62e9d46bfceaf" +checksum = "317936bbbd05227752583946b9e66d7ce3b489f84e11a94a510b4437fef407d7" dependencies = [ "core-foundation-sys", "libc", @@ -12116,9 +12253,9 @@ checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" [[package]] name = "serde" -version = "1.0.207" +version = "1.0.203" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5665e14a49a4ea1b91029ba7d3bca9f299e1f7cfa194388ccc20f14743e784f2" +checksum = "7253ab4de971e72fb7be983802300c30b5a7f0c2e56fab8abfc6a214307c0094" dependencies = [ "serde_derive", ] @@ -12134,41 +12271,40 @@ dependencies = [ [[package]] name = "serde_bytes" -version = "0.11.15" +version = "0.11.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "387cc504cb06bb40a96c8e04e951fe01854cf6bc921053c954e4a606d9675c6a" +checksum = "8b8497c313fd43ab992087548117643f6fcd935cbf36f176ffda0aacf9591734" dependencies = [ "serde", ] [[package]] name = "serde_derive" -version = "1.0.207" +version = "1.0.203" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6aea2634c86b0e8ef2cfdc0c340baede54ec27b1e46febd7f80dffb2aa44a00e" +checksum = "500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5ba" dependencies = [ "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.66", ] [[package]] name = "serde_json" -version = "1.0.124" +version = "1.0.117" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "66ad62847a56b3dba58cc891acd13884b9c61138d330c0d7b6181713d4fce38d" +checksum = "455182ea6142b14f93f4bc5320a2b31c1f266b66a4a5c858b013302a5d8cbfc3" dependencies = [ "itoa", - "memchr", "ryu", "serde", ] [[package]] name = "serde_spanned" -version = "0.6.7" +version = "0.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb5b1b31579f3811bf615c144393417496f152e12ac8b7663bf664f4a815306d" +checksum = "79e674e01f999af37c49f70a6ede167a8a60b2503e56c5599532a65baa5969a0" dependencies = [ "serde", ] @@ -12655,7 +12791,7 @@ dependencies = [ "proc-macro-crate 3.1.0", "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.66", ] [[package]] @@ -12907,7 +13043,7 @@ checksum = "b85d0f1f1e44bd8617eb2a48203ee854981229e3e79e6f468c7175d5fd37489b" dependencies = [ "quote", "sp-crypto-hashing", - "syn 2.0.74", + "syn 2.0.66", ] [[package]] @@ -12928,7 +13064,7 @@ checksum = "48d09fa0a5f7299fb81ee25ae3853d26200f7a348148aed6de76be905c007dbe" dependencies = [ "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.66", ] [[package]] @@ -13177,7 +13313,7 @@ dependencies = [ "proc-macro-crate 3.1.0", "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.66", ] [[package]] @@ -13384,7 +13520,7 @@ dependencies = [ "parity-scale-codec", "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.66", ] [[package]] @@ -13637,9 +13773,9 @@ dependencies = [ [[package]] name = "strum" -version = "0.26.3" +version = "0.26.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fec0f0aef304996cf250b31b5a10dee7980c85da9d759361292b8bca5a18f06" +checksum = "5d8cec3501a5194c432b2b7976db6b7d10ec95c253208b45f83f7136aa985e29" [[package]] name = "strum_macros" @@ -13664,7 +13800,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.74", + "syn 2.0.66", ] [[package]] @@ -13765,7 +13901,7 @@ dependencies = [ "sp-maybe-compressed-blob", "strum 0.24.1", "tempfile", - "toml 0.8.19", + "toml 0.8.14", "walkdir", "wasm-opt", ] @@ -13801,9 +13937,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.74" +version = "2.0.66" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fceb41e3d546d0bd83421d3409b1460cc7444cd389341a4c880fe7a042cb3d7" +checksum = "c42f3f41a2de00b01c0aaad383c5a45241efc8b2d1eda5661812fda5f3cdcff5" dependencies = [ "proc-macro2", "quote", @@ -13830,7 +13966,7 @@ checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" dependencies = [ "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.66", ] [[package]] @@ -13876,21 +14012,20 @@ checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" [[package]] name = "target-lexicon" -version = "0.12.16" +version = "0.12.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1" +checksum = "e1fc403891a21bcfb7c37834ba66a547a8f402146eba7265b5a6d88059c9ff2f" [[package]] name = "tempfile" -version = "3.12.0" +version = "3.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04cbcdd0c794ebb0d4cf35e88edd2f7d2c4c3e9a5a6dab322839b321c6a87a64" +checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" dependencies = [ "cfg-if", "fastrand 2.1.0", - "once_cell", "rustix 0.38.34", - "windows-sys 0.59.0", + "windows-sys 0.52.0", ] [[package]] @@ -13920,9 +14055,9 @@ checksum = "3369f5ac52d5eb6ab48c6b4ffdc8efbcad6b89c765749064ba298f2c68a16a76" [[package]] name = "thiserror" -version = "1.0.63" +version = "1.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724" +checksum = "c546c80d6be4bc6a00c0f01730c08df82eaa7a7a61f11d656526506112cc1709" dependencies = [ "thiserror-impl", ] @@ -13944,18 +14079,18 @@ checksum = "e4c60d69f36615a077cc7663b9cb8e42275722d23e58a7fa3d2c7f2915d09d04" dependencies = [ "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.66", ] [[package]] name = "thiserror-impl" -version = "1.0.63" +version = "1.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261" +checksum = "46c3384250002a6d5af4d114f2845d37b57521033f30d5c3f46c4d70e1197533" dependencies = [ "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.66", ] [[package]] @@ -14057,11 +14192,21 @@ dependencies = [ "crunchy", ] +[[package]] +name = "tinystr" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f" +dependencies = [ + "displaydoc", + "zerovec", +] + [[package]] name = "tinyvec" -version = "1.8.0" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "445e881f4f6d382d5f27c034e25eb92edd7c784ceab92a0937db7f2e9471b938" +checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" dependencies = [ "tinyvec_macros", ] @@ -14074,31 +14219,32 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.39.2" +version = "1.38.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "daa4fb1bc778bd6f04cbfc4bb2d06a7396a8f299dc33ea1900cedaa316f467b1" +checksum = "ba4f4a02a7a80d6f274636f0aa95c7e383b912d41fe721a31f29e29698585a4a" dependencies = [ "backtrace", "bytes", "libc", "mio", + "num_cpus", "parking_lot 0.12.3", "pin-project-lite 0.2.14", "signal-hook-registry", "socket2 0.5.7", "tokio-macros", - "windows-sys 0.52.0", + "windows-sys 0.48.0", ] [[package]] name = "tokio-macros" -version = "2.4.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" +checksum = "5f5ae998a069d4b5aba8ee9dad856af7d520c3699e6159b185c2acd48155d39a" dependencies = [ "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.66", ] [[package]] @@ -14159,21 +14305,21 @@ dependencies = [ [[package]] name = "toml" -version = "0.8.19" +version = "0.8.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1ed1f98e3fdc28d6d910e6737ae6ab1a93bf1985935a1193e68f93eeb68d24e" +checksum = "6f49eb2ab21d2f26bd6db7bf383edc527a7ebaee412d17af4d40fdccd442f335" dependencies = [ "serde", "serde_spanned", "toml_datetime", - "toml_edit 0.22.20", + "toml_edit 0.22.14", ] [[package]] name = "toml_datetime" -version = "0.6.8" +version = "0.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" +checksum = "4badfd56924ae69bcc9039335b2e017639ce3f9b001c393c1b2d1ef846ce2cbf" dependencies = [ "serde", ] @@ -14184,7 +14330,7 @@ version = "0.20.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "70f427fce4d84c72b5b732388bf4a9f4531b53f74e2887e3ecb2481f68f66d81" dependencies = [ - "indexmap 2.3.0", + "indexmap 2.2.6", "toml_datetime", "winnow 0.5.40", ] @@ -14195,22 +14341,22 @@ version = "0.21.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a8534fd7f78b5405e860340ad6575217ce99f38d4d5c8f2442cb5ecb50090e1" dependencies = [ - "indexmap 2.3.0", + "indexmap 2.2.6", "toml_datetime", "winnow 0.5.40", ] [[package]] name = "toml_edit" -version = "0.22.20" +version = "0.22.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "583c44c02ad26b0c3f3066fe629275e50627026c51ac2e595cca4c230ce1ce1d" +checksum = "f21c7aaf97f1bd9ca9d4f9e73b0a6c74bd5afef56f2bc931943a6e1c37e04e38" dependencies = [ - "indexmap 2.3.0", + "indexmap 2.2.6", "serde", "serde_spanned", "toml_datetime", - "winnow 0.6.18", + "winnow 0.6.13", ] [[package]] @@ -14234,7 +14380,7 @@ version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "61c5bb1d698276a2443e5ecfabc1008bf15a36c12e6a7176e7bf089ea9131140" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.5.0", "bytes", "futures-core", "futures-util", @@ -14278,7 +14424,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.66", ] [[package]] @@ -14323,7 +14469,7 @@ dependencies = [ "proc-macro-crate 3.1.0", "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.66", ] [[package]] @@ -14619,15 +14765,27 @@ checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" [[package]] name = "url" -version = "2.5.2" +version = "2.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22784dbdf76fdde8af1aeda5622b546b422b6fc585325248a2bf9f5e41e94d6c" +checksum = "f7c25da092f0a868cdf09e8674cd3b7ef3a7d92a24253e663a2fb85e2496de56" dependencies = [ "form_urlencoded", - "idna 0.5.0", + "idna 1.0.0", "percent-encoding", ] +[[package]] +name = "utf16_iter" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8232dd3cdaed5356e0f716d285e4b40b932ac434100fe9b7e0e8e935b9e6246" + +[[package]] +name = "utf8_iter" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" + [[package]] name = "utf8parse" version = "0.2.2" @@ -14648,9 +14806,9 @@ checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" [[package]] name = "version_check" -version = "0.9.5" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" [[package]] name = "void" @@ -14730,35 +14888,34 @@ dependencies = [ [[package]] name = "wasm-bindgen" -version = "0.2.93" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a82edfc16a6c469f5f44dc7b571814045d60404b55a0ee849f9bcfa2e63dd9b5" +checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" dependencies = [ "cfg-if", - "once_cell", "wasm-bindgen-macro", ] [[package]] name = "wasm-bindgen-backend" -version = "0.2.93" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9de396da306523044d3302746f1208fa71d7532227f15e347e2d93e4145dd77b" +checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.66", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.43" +version = "0.4.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61e9300f63a621e96ed275155c108eb6f843b6a26d053f122ab69724559dc8ed" +checksum = "76bc14366121efc8dbb487ab05bcc9d346b3b5ec0eaa76e46594cabbe51762c0" dependencies = [ "cfg-if", "js-sys", @@ -14768,9 +14925,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.93" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "585c4c91a46b072c92e908d99cb1dcdf95c5218eeb6f3bf1efa991ee7a68cccf" +checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -14778,22 +14935,22 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.93" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afc340c74d9005395cf9dd098506f7f44e38f2b4a21c6aaacf9a105ea5e1e836" +checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.66", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.93" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c62a0a307cb4a311d3a07867860911ca130c3494e8c2719593806c08bc5d0484" +checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" [[package]] name = "wasm-instrument" @@ -15106,9 +15263,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.70" +version = "0.3.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26fdeaafd9bd129f65e7c031593c24d62186301e0c72c8978fa1678be7d532c0" +checksum = "77afa9a11836342370f4817622a2f0f418b134426d91a82dfb48f532d2ec13ef" dependencies = [ "js-sys", "wasm-bindgen", @@ -15272,9 +15429,9 @@ dependencies = [ [[package]] name = "wide" -version = "0.7.28" +version = "0.7.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b828f995bf1e9622031f8009f8481a85406ce1f4d4588ff746d872043e855690" +checksum = "8a040b111774ab63a19ef46bbc149398ab372b4ccdcfd719e9814dbd7dfd76c8" dependencies = [ "bytemuck", "safe_arch", @@ -15304,11 +15461,11 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" -version = "0.1.9" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" +checksum = "4d4cc384e1e73b93bafa6fb4f1df8c41695c8a91cf9c4c64358067d15a7b6c6b" dependencies = [ - "windows-sys 0.59.0", + "windows-sys 0.52.0", ] [[package]] @@ -15323,7 +15480,7 @@ version = "0.51.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ca229916c5ee38c2f2bc1e9d8f04df975b4bd93f9955dc69fabb5d91270045c9" dependencies = [ - "windows-core 0.51.1", + "windows-core", "windows-targets 0.48.5", ] @@ -15336,15 +15493,6 @@ dependencies = [ "windows-targets 0.48.5", ] -[[package]] -name = "windows-core" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" -dependencies = [ - "windows-targets 0.52.6", -] - [[package]] name = "windows-sys" version = "0.45.0" @@ -15369,16 +15517,7 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets 0.52.6", -] - -[[package]] -name = "windows-sys" -version = "0.59.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" -dependencies = [ - "windows-targets 0.52.6", + "windows-targets 0.52.5", ] [[package]] @@ -15413,18 +15552,18 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.52.6" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb" dependencies = [ - "windows_aarch64_gnullvm 0.52.6", - "windows_aarch64_msvc 0.52.6", - "windows_i686_gnu 0.52.6", + "windows_aarch64_gnullvm 0.52.5", + "windows_aarch64_msvc 0.52.5", + "windows_i686_gnu 0.52.5", "windows_i686_gnullvm", - "windows_i686_msvc 0.52.6", - "windows_x86_64_gnu 0.52.6", - "windows_x86_64_gnullvm 0.52.6", - "windows_x86_64_msvc 0.52.6", + "windows_i686_msvc 0.52.5", + "windows_x86_64_gnu 0.52.5", + "windows_x86_64_gnullvm 0.52.5", + "windows_x86_64_msvc 0.52.5", ] [[package]] @@ -15441,9 +15580,9 @@ checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] name = "windows_aarch64_gnullvm" -version = "0.52.6" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" +checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263" [[package]] name = "windows_aarch64_msvc" @@ -15459,9 +15598,9 @@ checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] name = "windows_aarch64_msvc" -version = "0.52.6" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" +checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6" [[package]] name = "windows_i686_gnu" @@ -15477,15 +15616,15 @@ checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] name = "windows_i686_gnu" -version = "0.52.6" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" +checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670" [[package]] name = "windows_i686_gnullvm" -version = "0.52.6" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" +checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9" [[package]] name = "windows_i686_msvc" @@ -15501,9 +15640,9 @@ checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] name = "windows_i686_msvc" -version = "0.52.6" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" +checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf" [[package]] name = "windows_x86_64_gnu" @@ -15519,9 +15658,9 @@ checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] name = "windows_x86_64_gnu" -version = "0.52.6" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" +checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9" [[package]] name = "windows_x86_64_gnullvm" @@ -15537,9 +15676,9 @@ checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] name = "windows_x86_64_gnullvm" -version = "0.52.6" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" +checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596" [[package]] name = "windows_x86_64_msvc" @@ -15555,9 +15694,9 @@ checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] name = "windows_x86_64_msvc" -version = "0.52.6" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" +checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" [[package]] name = "winnow" @@ -15570,9 +15709,9 @@ dependencies = [ [[package]] name = "winnow" -version = "0.6.18" +version = "0.6.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68a9bda4691f099d435ad181000724da8e5899daa10713c2d432552b9ccd3a6f" +checksum = "59b5e5f6c299a3c7890b876a2a587f3115162487e704907d9b6cd29473052ba1" dependencies = [ "memchr", ] @@ -15587,6 +15726,18 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "write16" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1890f4022759daae28ed4fe62859b1236caebfc61ede2f63ed4e695f3f6d936" + +[[package]] +name = "writeable" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51" + [[package]] name = "wyz" version = "0.5.1" @@ -15681,7 +15832,7 @@ dependencies = [ "Inflector", "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.66", ] [[package]] @@ -15707,25 +15858,69 @@ dependencies = [ "time", ] +[[package]] +name = "yoke" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c5b1314b079b0930c31e3af543d8ee1757b1951ae1e1565ec704403a7240ca5" +dependencies = [ + "serde", + "stable_deref_trait", + "yoke-derive", + "zerofrom", +] + +[[package]] +name = "yoke-derive" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28cc31741b18cb6f1d5ff12f5b7523e3d6eb0852bbbad19d73905511d9849b95" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.66", + "synstructure 0.13.1", +] + [[package]] name = "zerocopy" -version = "0.7.35" +version = "0.7.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" +checksum = "ae87e3fcd617500e5d106f0380cf7b77f3c6092aae37191433159dda23cfb087" dependencies = [ - "byteorder", "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.7.35" +version = "0.7.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" +checksum = "15e934569e47891f7d9411f1a451d947a60e000ab3bd24fbb970f000387d1b3b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.66", +] + +[[package]] +name = "zerofrom" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91ec111ce797d0e0784a1116d0ddcdbea84322cd79e5d5ad173daeba4f93ab55" +dependencies = [ + "zerofrom-derive", +] + +[[package]] +name = "zerofrom-derive" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ea7b4a3637ea8669cedf0f1fd5c286a17f3de97b8dd5a70a6c167a1730e63a5" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.66", + "synstructure 0.13.1", ] [[package]] @@ -15745,7 +15940,29 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.66", +] + +[[package]] +name = "zerovec" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa2b893d79df23bfb12d5461018d408ea19dfafe76c2c7ef6d4eba614f8ff079" +dependencies = [ + "yoke", + "zerofrom", + "zerovec-derive", +] + +[[package]] +name = "zerovec-derive" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.66", ] [[package]] @@ -15788,9 +16005,9 @@ dependencies = [ [[package]] name = "zstd-sys" -version = "2.0.13+zstd.1.5.6" +version = "2.0.11+zstd.1.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38ff0f21cfee8f97d94cef41359e0c89aa6113028ab0291aa8ca0038995a95aa" +checksum = "75652c55c0b6f3e6f12eb786fe1bc960396bf05a1eb3bf1f3691c3610ac2e6d4" dependencies = [ "cc", "pkg-config", diff --git a/pop-api/Cargo.toml b/pop-api/Cargo.toml index 9946abf7..05dd9715 100644 --- a/pop-api/Cargo.toml +++ b/pop-api/Cargo.toml @@ -7,7 +7,11 @@ edition = "2021" [dependencies] ink = { version = "5.0.0", default-features = false } -sp-io = { version = "31.0.0", default-features = false, features = ["disable_panic_handler", "disable_oom", "disable_allocator"] } +sp-io = { version = "31.0.0", default-features = false, features = [ + "disable_panic_handler", + "disable_oom", + "disable_allocator", +] } pop-primitives = { path = "../primitives", default-features = false } @@ -18,10 +22,6 @@ crate-type = ["rlib"] [features] default = ["std"] -std = [ - "ink/std", - "pop-primitives/std", - "sp-io/std", -] +std = ["ink/std", "pop-primitives/std", "sp-io/std"] assets = [] fungibles = ["assets"] diff --git a/pop-api/integration-tests/Cargo.toml b/pop-api/integration-tests/Cargo.toml index cc56630a..7ab2d0fb 100644 --- a/pop-api/integration-tests/Cargo.toml +++ b/pop-api/integration-tests/Cargo.toml @@ -2,10 +2,16 @@ name = "integration-tests" version = "0.1.0" edition = "2021" +build = "build.rs" + +[build-dependencies] +contract-build = "4.1.1" [dev-dependencies] env_logger = "0.11.2" -scale = { package = "parity-scale-codec", version = "3.0.0", default-features = false, features = ["derive"] } +scale = { package = "parity-scale-codec", version = "3.0.0", default-features = false, features = [ + "derive", +] } frame-support = { version = "29.0.0", default-features = false } frame-system = { version = "29.0.0", default-features = false } pallet-balances = { version = "29.0.2", default-features = false } diff --git a/pop-api/integration-tests/build.rs b/pop-api/integration-tests/build.rs new file mode 100644 index 00000000..5b969a9f --- /dev/null +++ b/pop-api/integration-tests/build.rs @@ -0,0 +1,57 @@ +use contract_build::{ + execute, BuildArtifacts, BuildMode, BuildResult, ExecuteArgs, ManifestPath, OutputType, + Verbosity, +}; +use std::{ + fs, + path::{Path, PathBuf}, + process, +}; + +fn main() { + let contracts_dir = PathBuf::from("./contracts/"); + let contract_dirs = match get_subcontract_directories(&contracts_dir) { + Ok(dirs) => dirs, + Err(e) => { + eprintln!("Failed to read contracts directory: {}", e); + process::exit(1); + }, + }; + + for contract in contract_dirs { + if let Err(e) = build_contract(&contract) { + eprintln!("Failed to build contract {}: {}", contract.display(), e); + process::exit(1); + } + } +} + +// Function to retrieve all subdirectories in a given directory. +fn get_subcontract_directories(contracts_dir: &Path) -> Result, String> { + fs::read_dir(contracts_dir) + .map_err(|e| format!("Could not read directory '{}': {}", contracts_dir.display(), e))? + .filter_map(|entry| match entry { + Ok(entry) if entry.path().is_dir() => Some(Ok(entry.path())), + Ok(_) => None, + Err(e) => Some(Err(format!("Error reading directory entry: {}", e))), + }) + .collect() +} + +// Function to build a contract given its directory. +fn build_contract(contract_dir: &Path) -> Result { + let manifest_path = ManifestPath::new(contract_dir.join("Cargo.toml")).map_err(|e| { + format!("Could not retrieve manifest path for {}: {}", contract_dir.display(), e) + })?; + + let args = ExecuteArgs { + build_artifact: BuildArtifacts::CodeOnly, + build_mode: BuildMode::Debug, + manifest_path, + output_type: OutputType::HumanReadable, + verbosity: Verbosity::Default, + ..Default::default() + }; + + execute(args).map_err(|e| format!("Build failed for {}: {}", contract_dir.display(), e)) +} From 8d1c0850c03da6e0d62181133eeb7ca35a680385 Mon Sep 17 00:00:00 2001 From: Tin Chung <56880684+chungquantin@users.noreply.github.com> Date: Mon, 26 Aug 2024 22:40:15 +0700 Subject: [PATCH 048/112] fix: mutable `self` required for dispatchable ink! methods (#235) --- pop-api/examples/fungibles/lib.rs | 10 ++++---- .../contracts/fungibles/lib.rs | 25 +++++++++++-------- 2 files changed, 20 insertions(+), 15 deletions(-) diff --git a/pop-api/examples/fungibles/lib.rs b/pop-api/examples/fungibles/lib.rs index 1b42fec4..a6328c37 100755 --- a/pop-api/examples/fungibles/lib.rs +++ b/pop-api/examples/fungibles/lib.rs @@ -60,13 +60,13 @@ mod fungibles { } #[ink(message)] - pub fn transfer(&self, id: AssetId, to: AccountId, value: Balance) -> Result<()> { + pub fn transfer(&mut self, id: AssetId, to: AccountId, value: Balance) -> Result<()> { api::transfer(id, to, value) } #[ink(message)] pub fn transfer_from( - &self, + &mut self, id: AssetId, from: AccountId, to: AccountId, @@ -78,13 +78,13 @@ mod fungibles { } #[ink(message)] - pub fn approve(&self, id: AssetId, spender: AccountId, value: Balance) -> Result<()> { + pub fn approve(&mut self, id: AssetId, spender: AccountId, value: Balance) -> Result<()> { api::approve(id, spender, value) } #[ink(message)] pub fn increase_allowance( - &self, + &mut self, id: AssetId, spender: AccountId, value: Balance, @@ -94,7 +94,7 @@ mod fungibles { #[ink(message)] pub fn decrease_allowance( - &self, + &mut self, id: AssetId, spender: AccountId, value: Balance, diff --git a/pop-api/integration-tests/contracts/fungibles/lib.rs b/pop-api/integration-tests/contracts/fungibles/lib.rs index 239d3a2d..2b33ce04 100755 --- a/pop-api/integration-tests/contracts/fungibles/lib.rs +++ b/pop-api/integration-tests/contracts/fungibles/lib.rs @@ -60,13 +60,13 @@ mod fungibles { } #[ink(message)] - pub fn transfer(&self, id: AssetId, to: AccountId, value: Balance) -> Result<()> { + pub fn transfer(&mut self, id: AssetId, to: AccountId, value: Balance) -> Result<()> { api::transfer(id, to, value) } #[ink(message)] pub fn transfer_from( - &self, + &mut self, id: AssetId, from: AccountId, to: AccountId, @@ -78,13 +78,13 @@ mod fungibles { } #[ink(message)] - pub fn approve(&self, id: AssetId, spender: AccountId, value: Balance) -> Result<()> { + pub fn approve(&mut self, id: AssetId, spender: AccountId, value: Balance) -> Result<()> { api::approve(id, spender, value) } #[ink(message)] pub fn increase_allowance( - &self, + &mut self, id: AssetId, spender: AccountId, value: Balance, @@ -94,7 +94,7 @@ mod fungibles { #[ink(message)] pub fn decrease_allowance( - &self, + &mut self, id: AssetId, spender: AccountId, value: Balance, @@ -130,18 +130,23 @@ mod fungibles { /// - asset_exists #[ink(message)] - pub fn create(&self, id: AssetId, admin: AccountId, min_balance: Balance) -> Result<()> { + pub fn create( + &mut self, + id: AssetId, + admin: AccountId, + min_balance: Balance, + ) -> Result<()> { api::create(id, admin, min_balance) } #[ink(message)] - pub fn start_destroy(&self, id: AssetId) -> Result<()> { + pub fn start_destroy(&mut self, id: AssetId) -> Result<()> { api::start_destroy(id) } #[ink(message)] pub fn set_metadata( - &self, + &mut self, id: AssetId, name: Vec, symbol: Vec, @@ -165,12 +170,12 @@ mod fungibles { /// - burn #[ink(message)] - pub fn mint(&self, id: AssetId, account: AccountId, amount: Balance) -> Result<()> { + pub fn mint(&mut self, id: AssetId, account: AccountId, amount: Balance) -> Result<()> { api::mint(id, account, amount) } #[ink(message)] - pub fn burn(&self, id: AssetId, account: AccountId, amount: Balance) -> Result<()> { + pub fn burn(&mut self, id: AssetId, account: AccountId, amount: Balance) -> Result<()> { api::burn(id, account, amount) } } From 479dbb0b509e17cd32c050673a9822c4c6527c4d Mon Sep 17 00:00:00 2001 From: Frank Bell <60948618+evilrobot-01@users.noreply.github.com> Date: Fri, 6 Sep 2024 17:22:52 +0100 Subject: [PATCH 049/112] refactor: generic extension (#218) Co-authored-by: Tin Chung <56880684+chungquantin@users.noreply.github.com> --- .github/workflows/ci.yml | 8 +- .gitignore | 5 +- Cargo.lock | 524 +++++++++++++++-- Cargo.toml | 6 +- extension/Cargo.toml | 43 +- extension/contract/Cargo.toml | 16 + extension/contract/lib.rs | 51 ++ extension/src/decoding.rs | 297 ++++++++++ extension/src/environment.rs | 193 +++++++ extension/src/functions.rs | 534 ++++++++++++++++++ extension/src/lib.rs | 466 ++++++--------- extension/src/matching.rs | 84 +++ extension/src/mock.rs | 373 ++++++++++++ extension/src/tests.rs | 321 +++++++---- extension/src/v0.rs | 298 ---------- integration-tests/src/lib.rs | 37 +- node/src/command.rs | 5 +- pallets/api/Cargo.toml | 5 + pallets/api/src/extension.rs | 180 ++++++ pallets/api/src/fungibles/mod.rs | 106 +++- pallets/api/src/fungibles/tests.rs | 25 +- pallets/api/src/lib.rs | 25 + pop-api/integration-tests/Cargo.toml | 1 + .../integration-tests/src/fungibles/mod.rs | 127 +++-- pop-api/integration-tests/src/lib.rs | 1 + pop-api/src/v0/assets/fungibles.rs | 27 +- pop-api/src/v0/mod.rs | 2 +- primitives/src/lib.rs | 75 ++- runtime/devnet/src/config/api.rs | 68 --- runtime/devnet/src/config/api/mod.rs | 213 +++++++ runtime/devnet/src/config/api/versioning.rs | 218 +++++++ runtime/devnet/src/config/contracts.rs | 4 +- runtime/devnet/src/config/proxy.rs | 108 ++-- runtime/devnet/src/config/xcm.rs | 4 +- runtime/devnet/src/lib.rs | 8 +- runtime/testnet/src/config/proxy.rs | 108 ++-- runtime/testnet/src/config/xcm.rs | 4 +- runtime/testnet/src/extensions.rs | 2 +- runtime/testnet/src/lib.rs | 8 +- 39 files changed, 3483 insertions(+), 1097 deletions(-) create mode 100755 extension/contract/Cargo.toml create mode 100755 extension/contract/lib.rs create mode 100644 extension/src/decoding.rs create mode 100644 extension/src/environment.rs create mode 100644 extension/src/functions.rs create mode 100644 extension/src/matching.rs create mode 100644 extension/src/mock.rs delete mode 100644 extension/src/v0.rs create mode 100644 pallets/api/src/extension.rs delete mode 100644 runtime/devnet/src/config/api.rs create mode 100644 runtime/devnet/src/config/api/mod.rs create mode 100644 runtime/devnet/src/config/api/versioning.rs diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 283390f3..c8e2b2cc 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -2,9 +2,9 @@ name: ci on: push: - branches: [main] + branches: [ main ] pull_request: - types: [opened, synchronize, reopened, ready_for_review] + types: [ opened, synchronize, reopened, ready_for_review ] jobs: lint: @@ -13,7 +13,9 @@ jobs: - uses: actions/checkout@v4 - name: Check formatting - run: cargo +stable fmt --all -- --check + run: | + rustup toolchain install nightly --profile minimal --component rustfmt + cargo +nightly fmt --all -- --check check: needs: lint diff --git a/.gitignore b/.gitignore index 52e0800a..b99b862b 100644 --- a/.gitignore +++ b/.gitignore @@ -12,4 +12,7 @@ .idea # Binaries -**/bin/ \ No newline at end of file +**/bin/ + +# Cargo.lock +**/Cargo.lock \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock index e2a4bbcd..26fb5d46 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -805,6 +805,12 @@ version = "0.21.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" +[[package]] +name = "base64" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" + [[package]] name = "base64ct" version = "1.6.0" @@ -1001,6 +1007,50 @@ dependencies = [ "piper", ] +[[package]] +name = "bollard" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0aed08d3adb6ebe0eff737115056652670ae290f177759aac19c30456135f94c" +dependencies = [ + "base64 0.22.1", + "bollard-stubs", + "bytes", + "futures-core", + "futures-util", + "hex", + "http 1.1.0", + "http-body-util", + "hyper 1.4.1", + "hyper-named-pipe", + "hyper-util", + "hyperlocal-next", + "log", + "pin-project-lite 0.2.14", + "serde", + "serde_derive", + "serde_json", + "serde_repr", + "serde_urlencoded", + "thiserror", + "tokio", + "tokio-util", + "tower-service", + "url", + "winapi", +] + +[[package]] +name = "bollard-stubs" +version = "1.44.0-rc.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "709d9aa1c37abb89d40f19f5d0ad6f0d88cb1581264e571c9350fc5bb89cf1c5" +dependencies = [ + "serde", + "serde_repr", + "serde_with", +] + [[package]] name = "bounded-collections" version = "0.2.0" @@ -1368,6 +1418,20 @@ dependencies = [ "thiserror", ] +[[package]] +name = "cargo_metadata" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d886547e41f740c616ae73108f6eb70afe6d940c7bc697cb30f13daec073037" +dependencies = [ + "camino", + "cargo-platform", + "semver 1.0.23", + "serde", + "serde_json", + "thiserror", +] + [[package]] name = "cc" version = "1.0.99" @@ -1453,8 +1517,9 @@ dependencies = [ "iana-time-zone", "js-sys", "num-traits", + "serde", "wasm-bindgen", - "windows-targets 0.52.5", + "windows-targets 0.52.6", ] [[package]] @@ -1599,6 +1664,16 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b6a852b24ab71dffc585bcb46eaf7959d175cb865a7152e35b348d1b2960422" +[[package]] +name = "colored" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cbf2150cce219b664a8a70df7a1f933836724b503f8a413af9365b4dcc4d90b8" +dependencies = [ + "lazy_static", + "windows-sys 0.48.0", +] + [[package]] name = "comfy-table" version = "7.1.1" @@ -1682,6 +1757,60 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cd7e35aee659887cbfb97aaf227ac12cad1a9d7c71e55ff3376839ed4e282d08" +[[package]] +name = "contract-build" +version = "4.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d30f629d8cb26692c4e5f4155e8ab37649f1b2fd0abab64a4c1b3c95c9bcf3df" +dependencies = [ + "anyhow", + "blake2 0.10.6", + "bollard", + "cargo_metadata 0.18.1", + "clap", + "colored", + "contract-metadata", + "crossterm", + "duct", + "heck 0.5.0", + "hex", + "impl-serde", + "parity-scale-codec", + "parity-wasm", + "regex", + "rustc_version", + "semver 1.0.23", + "serde", + "serde_json", + "strum 0.26.2", + "tempfile", + "term_size", + "tokio", + "tokio-stream", + "toml 0.8.14", + "tracing", + "url", + "uzers", + "walkdir", + "wasm-opt", + "which 6.0.3", + "zip", +] + +[[package]] +name = "contract-metadata" +version = "4.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd54ed69476dc2076d6ebda17351babe1c2f33751170877f66719e8129078d3a" +dependencies = [ + "anyhow", + "impl-serde", + "semver 1.0.23", + "serde", + "serde_json", + "url", +] + [[package]] name = "convert_case" version = "0.4.0" @@ -1882,6 +2011,31 @@ version = "0.8.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" +[[package]] +name = "crossterm" +version = "0.27.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f476fe445d41c9e991fd07515a6f463074b782242ccf4a5b7b1d1012e70824df" +dependencies = [ + "bitflags 2.5.0", + "crossterm_winapi", + "libc", + "mio", + "parking_lot 0.12.3", + "signal-hook", + "signal-hook-mio", + "winapi", +] + +[[package]] +name = "crossterm_winapi" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acdd7c62a3665c7f6830a51635d9ac9b23ed385797f70a83bb8bafe9c572ab2b" +dependencies = [ + "winapi", +] + [[package]] name = "crunchy" version = "0.2.2" @@ -2693,6 +2847,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" dependencies = [ "powerfmt", + "serde", ] [[package]] @@ -2875,6 +3030,18 @@ version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dcbb2bf8e87535c23f7a8a321e364ce21462d0ff10cb6407820e8e96dfff6653" +[[package]] +name = "duct" +version = "0.13.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4ab5718d1224b63252cd0c6f74f6480f9ffeb117438a2e0f5cf6d9a4798929c" +dependencies = [ + "libc", + "once_cell", + "os_pipe", + "shared_child", +] + [[package]] name = "dyn-clonable" version = "0.9.0" @@ -4055,7 +4222,7 @@ dependencies = [ "futures-core", "futures-sink", "futures-util", - "http", + "http 0.2.12", "indexmap 2.2.6", "slab", "tokio", @@ -4246,6 +4413,17 @@ dependencies = [ "itoa", ] +[[package]] +name = "http" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + [[package]] name = "http-body" version = "0.4.6" @@ -4253,7 +4431,30 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" dependencies = [ "bytes", - "http", + "http 0.2.12", + "pin-project-lite 0.2.14", +] + +[[package]] +name = "http-body" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" +dependencies = [ + "bytes", + "http 1.1.0", +] + +[[package]] +name = "http-body-util" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "793429d76616a256bcb62c2a2ec2bed781c8307e797e2598c50010f2bee2544f" +dependencies = [ + "bytes", + "futures-util", + "http 1.1.0", + "http-body 1.0.1", "pin-project-lite 0.2.14", ] @@ -4292,8 +4493,8 @@ dependencies = [ "futures-core", "futures-util", "h2", - "http", - "http-body", + "http 0.2.12", + "http-body 0.4.6", "httparse", "httpdate", "itoa", @@ -4305,6 +4506,40 @@ dependencies = [ "want", ] +[[package]] +name = "hyper" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50dfd22e0e76d0f662d429a5f80fcaf3855009297eab6a0a9f8543834744ba05" +dependencies = [ + "bytes", + "futures-channel", + "futures-util", + "http 1.1.0", + "http-body 1.0.1", + "httparse", + "itoa", + "pin-project-lite 0.2.14", + "smallvec", + "tokio", + "want", +] + +[[package]] +name = "hyper-named-pipe" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73b7d8abf35697b81a825e386fc151e0d503e8cb5fcb93cc8669c376dfd6f278" +dependencies = [ + "hex", + "hyper 1.4.1", + "hyper-util", + "pin-project-lite 0.2.14", + "tokio", + "tower-service", + "winapi", +] + [[package]] name = "hyper-rustls" version = "0.24.2" @@ -4312,8 +4547,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590" dependencies = [ "futures-util", - "http", - "hyper", + "http 0.2.12", + "hyper 0.14.29", "log", "rustls 0.21.12", "rustls-native-certs", @@ -4321,6 +4556,41 @@ dependencies = [ "tokio-rustls", ] +[[package]] +name = "hyper-util" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cde7055719c54e36e95e8719f95883f22072a48ede39db7fc17a4e1d5281e9b9" +dependencies = [ + "bytes", + "futures-channel", + "futures-util", + "http 1.1.0", + "http-body 1.0.1", + "hyper 1.4.1", + "pin-project-lite 0.2.14", + "socket2 0.5.7", + "tokio", + "tower", + "tower-service", + "tracing", +] + +[[package]] +name = "hyperlocal-next" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acf569d43fa9848e510358c07b80f4adf34084ddc28c6a4a651ee8474c070dcc" +dependencies = [ + "hex", + "http-body-util", + "hyper 1.4.1", + "hyper-util", + "pin-project-lite 0.2.14", + "tokio", + "tower-service", +] + [[package]] name = "iana-time-zone" version = "0.1.60" @@ -4601,6 +4871,7 @@ checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" dependencies = [ "equivalent", "hashbrown 0.14.5", + "serde", ] [[package]] @@ -4813,7 +5084,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5c671353e4adf926799107bd7f5724a06b6bc0a333db442a0843c58640bdd0c1" dependencies = [ "futures-util", - "http", + "http 0.2.12", "jsonrpsee-core", "pin-project", "rustls-native-certs", @@ -4838,7 +5109,7 @@ dependencies = [ "beef", "futures-timer", "futures-util", - "hyper", + "hyper 0.14.29", "jsonrpsee-types", "parking_lot 0.12.3", "rand", @@ -4858,7 +5129,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "57c7b9f95208927653e7965a98525e7fc641781cab89f0e27c43fa2974405683" dependencies = [ "async-trait", - "hyper", + "hyper 0.14.29", "hyper-rustls", "jsonrpsee-core", "jsonrpsee-types", @@ -4891,8 +5162,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a482bc4e25eebd0adb61a3468c722763c381225bd3ec46e926f709df8a8eb548" dependencies = [ "futures-util", - "http", - "hyper", + "http 0.2.12", + "hyper 0.14.29", "jsonrpsee-core", "jsonrpsee-types", "route-recognizer", @@ -4927,7 +5198,7 @@ version = "0.20.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6d06eeabbb55f0af8405288390a358ebcceb6e79e1390741e6f152309c4d6076" dependencies = [ - "http", + "http 0.2.12", "jsonrpsee-client-transport", "jsonrpsee-core", "jsonrpsee-types", @@ -5031,7 +5302,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c2a198fb6b0eada2a8df47933734e6d35d350665a33a3593d7164fa52c75c19" dependencies = [ "cfg-if", - "windows-targets 0.52.5", + "windows-targets 0.48.5", ] [[package]] @@ -5863,6 +6134,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" dependencies = [ "libc", + "log", "wasi 0.11.0+wasi-snapshot-preview1", "windows-sys 0.48.0", ] @@ -6451,6 +6723,16 @@ dependencies = [ "num-traits", ] +[[package]] +name = "os_pipe" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ffd2b0a5634335b135d5728d84c5e0fd726954b87111f7506a61c502280d982" +dependencies = [ + "libc", + "windows-sys 0.59.0", +] + [[package]] name = "pallet-api" version = "0.1.0" @@ -6458,9 +6740,11 @@ dependencies = [ "frame-benchmarking", "frame-support", "frame-system", + "log", "pallet-assets", "pallet-balances", "parity-scale-codec", + "pop-chain-extension", "scale-info", "sp-core", "sp-io", @@ -8112,7 +8396,7 @@ dependencies = [ "libc", "redox_syscall 0.5.2", "smallvec", - "windows-targets 0.52.5", + "windows-targets 0.52.6", ] [[package]] @@ -9595,14 +9879,20 @@ dependencies = [ name = "pop-chain-extension" version = "0.1.0" dependencies = [ + "contract-build", + "env_logger 0.11.5", "frame-support", "frame-system", + "impl-trait-for-tuples", "log", + "pallet-balances", "pallet-contracts", + "pallet-timestamp", "parity-scale-codec", - "pop-primitives", "rand", + "scale-info", "sp-core", + "sp-io", "sp-runtime", "sp-std", ] @@ -10085,7 +10375,7 @@ dependencies = [ "regex", "syn 1.0.109", "tempfile", - "which", + "which 4.4.2", ] [[package]] @@ -11660,7 +11950,7 @@ dependencies = [ "fnv", "futures", "futures-timer", - "hyper", + "hyper 0.14.29", "hyper-rustls", "libp2p", "log", @@ -11754,7 +12044,7 @@ version = "12.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "691440bbaddd3bc2675309c965cc75f8bf694f51e0a28039bfc9658299fbc394" dependencies = [ - "http", + "http 0.2.12", "jsonrpsee", "log", "serde_json", @@ -12300,6 +12590,17 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_repr" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.66", +] + [[package]] name = "serde_spanned" version = "0.6.6" @@ -12309,6 +12610,35 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_urlencoded" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +dependencies = [ + "form_urlencoded", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "serde_with" +version = "3.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69cecfa94848272156ea67b2b1a53f20fc7bc638c4a46d2f8abde08f05f4b857" +dependencies = [ + "base64 0.22.1", + "chrono", + "hex", + "indexmap 1.9.3", + "indexmap 2.2.6", + "serde", + "serde_derive", + "serde_json", + "time", +] + [[package]] name = "sha-1" version = "0.9.8" @@ -12376,12 +12706,43 @@ dependencies = [ "lazy_static", ] +[[package]] +name = "shared_child" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09fa9338aed9a1df411814a5b2252f7cd206c55ae9bf2fa763f8de84603aa60c" +dependencies = [ + "libc", + "windows-sys 0.59.0", +] + [[package]] name = "shlex" version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" +[[package]] +name = "signal-hook" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8621587d4798caf8eb44879d42e56b9a93ea5dcd315a6487c357130095b62801" +dependencies = [ + "libc", + "signal-hook-registry", +] + +[[package]] +name = "signal-hook-mio" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34db1a06d485c9142248b7a054f034b349b212551f3dfd19c94d45a754a217cd" +dependencies = [ + "libc", + "mio", + "signal-hook", +] + [[package]] name = "signal-hook-registry" version = "1.4.2" @@ -12750,7 +13111,7 @@ dependencies = [ "bytes", "flate2", "futures", - "http", + "http 0.2.12", "httparse", "log", "rand", @@ -13776,6 +14137,9 @@ name = "strum" version = "0.26.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5d8cec3501a5194c432b2b7976db6b7d10ec95c253208b45f83f7136aa985e29" +dependencies = [ + "strum_macros 0.26.4", +] [[package]] name = "strum_macros" @@ -13848,7 +14212,7 @@ version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0d8fe06b03b8a291c09507c42f92a2c2c10dd3d62975d02c7f64a92d87bfe09b" dependencies = [ - "hyper", + "hyper 0.14.29", "log", "prometheus", "thiserror", @@ -13894,7 +14258,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4a39a20e17c24ede36b5bd5e7543a4cef8d8a0daf6e1a046dc31832b837a54a0" dependencies = [ "build-helper", - "cargo_metadata", + "cargo_metadata 0.15.4", "console", "filetime", "parity-wasm", @@ -14028,6 +14392,16 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "term_size" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e4129646ca0ed8f45d09b929036bafad5377103edd06e50bf574b353d2b08d9" +dependencies = [ + "libc", + "winapi", +] + [[package]] name = "termcolor" version = "1.4.1" @@ -14369,6 +14743,7 @@ dependencies = [ "futures-util", "pin-project", "pin-project-lite 0.2.14", + "tokio", "tower-layer", "tower-service", "tracing", @@ -14384,8 +14759,8 @@ dependencies = [ "bytes", "futures-core", "futures-util", - "http", - "http-body", + "http 0.2.12", + "http-body 0.4.6", "http-range-header", "pin-project-lite 0.2.14", "tower-layer", @@ -14772,6 +15147,7 @@ dependencies = [ "form_urlencoded", "idna 1.0.0", "percent-encoding", + "serde", ] [[package]] @@ -14792,6 +15168,16 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" +[[package]] +name = "uzers" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76d283dc7e8c901e79e32d077866eaf599156cbf427fffa8289aecc52c5c3f63" +dependencies = [ + "libc", + "log", +] + [[package]] name = "valuable" version = "0.1.0" @@ -15427,6 +15813,18 @@ dependencies = [ "rustix 0.38.34", ] +[[package]] +name = "which" +version = "6.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4ee928febd44d98f2f459a4a79bd4d928591333a494a10a868418ac1b39cf1f" +dependencies = [ + "either", + "home", + "rustix 0.38.34", + "winsafe", +] + [[package]] name = "wide" version = "0.7.24" @@ -15517,7 +15915,16 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets 0.52.5", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets 0.52.6", ] [[package]] @@ -15552,18 +15959,18 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ - "windows_aarch64_gnullvm 0.52.5", - "windows_aarch64_msvc 0.52.5", - "windows_i686_gnu 0.52.5", + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", "windows_i686_gnullvm", - "windows_i686_msvc 0.52.5", - "windows_x86_64_gnu 0.52.5", - "windows_x86_64_gnullvm 0.52.5", - "windows_x86_64_msvc 0.52.5", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", ] [[package]] @@ -15580,9 +15987,9 @@ checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] name = "windows_aarch64_gnullvm" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" [[package]] name = "windows_aarch64_msvc" @@ -15598,9 +16005,9 @@ checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] name = "windows_aarch64_msvc" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" [[package]] name = "windows_i686_gnu" @@ -15616,15 +16023,15 @@ checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] name = "windows_i686_gnu" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" [[package]] name = "windows_i686_gnullvm" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" [[package]] name = "windows_i686_msvc" @@ -15640,9 +16047,9 @@ checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] name = "windows_i686_msvc" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" [[package]] name = "windows_x86_64_gnu" @@ -15658,9 +16065,9 @@ checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] name = "windows_x86_64_gnu" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" [[package]] name = "windows_x86_64_gnullvm" @@ -15676,9 +16083,9 @@ checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] name = "windows_x86_64_gnullvm" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" [[package]] name = "windows_x86_64_msvc" @@ -15694,9 +16101,9 @@ checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] name = "windows_x86_64_msvc" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "winnow" @@ -15726,6 +16133,12 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "winsafe" +version = "0.0.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d135d17ab770252ad95e9a872d365cf3090e3be864a34ab46f48555993efc904" + [[package]] name = "write16" version = "1.0.0" @@ -15965,6 +16378,17 @@ dependencies = [ "syn 2.0.66", ] +[[package]] +name = "zip" +version = "0.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "760394e246e4c28189f19d488c058bf16f564016aefac5d32bb1f3b51d5e9261" +dependencies = [ + "byteorder", + "crc32fast", + "crossbeam-utils", +] + [[package]] name = "zstd" version = "0.11.2+zstd.1.5.2" diff --git a/Cargo.toml b/Cargo.toml index f037f6b7..7027423c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,7 +23,7 @@ members = [ "pallets/*", "primitives", ] -exclude = ["pop-api", "tests/contracts"] +exclude = ["extension/contract", "pop-api", "tests/contracts"] resolver = "2" @@ -31,7 +31,10 @@ resolver = "2" codec = { package = "parity-scale-codec", version = "3.0.0", default-features = false, features = [ "derive", ] } +contract-build = "4.1.1" +env_logger = "0.11.5" hex-literal = "0.4.1" +impl-trait-for-tuples = "0.2.2" log = { version = "0.4.20", default-features = false } scale-info = { version = "2.10.0", default-features = false, features = [ "derive", @@ -41,6 +44,7 @@ serde = "1.0.195" clap = { version = "4.4.18", features = ["derive"] } jsonrpsee = { version = "0.20.3", features = ["server"] } futures = "0.3.28" +rand = "0.8.5" serde_json = "1.0.111" tracing-subscriber = { version = "0.3", default-features = false } subxt = "0.34.0" diff --git a/extension/Cargo.toml b/extension/Cargo.toml index 03b4221a..268365be 100644 --- a/extension/Cargo.toml +++ b/extension/Cargo.toml @@ -14,11 +14,9 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] codec.workspace = true +impl-trait-for-tuples.workspace = true log.workspace = true -# Local -pop-primitives.workspace = true - # Substrate frame-support.workspace = true frame-system.workspace = true @@ -28,24 +26,35 @@ sp-runtime.workspace = true sp-std.workspace = true [dev-dependencies] -rand = "0.8.5" +contract-build.workspace = true +env_logger.workspace = true +pallet-balances.workspace = true +pallet-contracts.workspace = true +pallet-timestamp.workspace = true +rand.workspace = true +scale-info.workspace = true +sp-io.workspace = true [features] default = ["std"] std = [ - "log/std", - "codec/std", - "frame-support/std", - "frame-system/std", - "pallet-contracts/std", - "pop-primitives/std", - "sp-runtime/std", - "sp-core/std", - "sp-std/std", + "log/std", + "codec/std", + "frame-support/std", + "frame-system/std", + "pallet-balances/std", + "pallet-contracts/std", + "pallet-timestamp/std", + "sp-runtime/std", + "sp-core/std", + "sp-io/std", + "sp-std/std", ] runtime-benchmarks = [ - "frame-support/runtime-benchmarks", - "frame-system/runtime-benchmarks", - "pallet-contracts/runtime-benchmarks", - "sp-runtime/runtime-benchmarks", + "frame-support/runtime-benchmarks", + "frame-system/runtime-benchmarks", + "pallet-balances/runtime-benchmarks", + "pallet-contracts/runtime-benchmarks", + "pallet-timestamp/runtime-benchmarks", + "sp-runtime/runtime-benchmarks", ] diff --git a/extension/contract/Cargo.toml b/extension/contract/Cargo.toml new file mode 100755 index 00000000..97ecabf9 --- /dev/null +++ b/extension/contract/Cargo.toml @@ -0,0 +1,16 @@ +[package] +authors = ["R0GUE "] +name = "proxy" +description = "Simple contract for proxying a call to a chain extension." +version = "0.1.0" +edition = "2021" + +[dependencies] +ink = { version = "5.0.0", default-features = false } + +[lib] +path = "lib.rs" + +[features] +default = ["std"] +std = ["ink/std"] diff --git a/extension/contract/lib.rs b/extension/contract/lib.rs new file mode 100755 index 00000000..181ba28c --- /dev/null +++ b/extension/contract/lib.rs @@ -0,0 +1,51 @@ +#![cfg_attr(not(feature = "std"), no_std, no_main)] + +use ink::{ + env::chain_extension::{ChainExtensionMethod, FromStatusCode}, + prelude::vec::Vec, +}; + +#[ink::contract] +mod contract { + use super::*; + + // Simple contract for proxying a call to a chain extension. + #[ink(storage)] + #[derive(Default)] + pub struct Proxy; + + impl Proxy { + #[ink(constructor)] + pub fn new() -> Self { + ink::env::debug_println!("Proxy::new()"); + Default::default() + } + + #[ink(message)] + pub fn call(&self, func_id: u32, input: Vec) -> Result, StatusCode> { + ink::env::debug_println!("Proxy::call() func_id={func_id}, input={input:?}"); + ChainExtensionMethod::build(func_id) + .input::>() + .output::, StatusCode>, true>() + .handle_error_code::() + .call(&input) + } + } +} + +#[ink::scale_derive(Encode, Decode, TypeInfo)] +pub struct StatusCode(u32); +impl FromStatusCode for StatusCode { + fn from_status_code(status_code: u32) -> Result<(), Self> { + match status_code { + 0 => Ok(()), + _ => Err(StatusCode(status_code)), + } + } +} + +impl From for StatusCode { + fn from(_: ink::scale::Error) -> Self { + StatusCode(u32::MAX) + } +} diff --git a/extension/src/decoding.rs b/extension/src/decoding.rs new file mode 100644 index 00000000..9405aa5b --- /dev/null +++ b/extension/src/decoding.rs @@ -0,0 +1,297 @@ +use super::*; +use sp_runtime::DispatchError; +use sp_std::vec::Vec; + +/// Trait for decoding data read from contract memory. +pub trait Decode { + /// The output type to be decoded. + type Output: codec::Decode; + /// An optional processor, for performing any additional processing on data read from the + /// contract before decoding. + type Processor: Processor>; + /// The error to return if decoding fails. + type Error: Get; + + /// The log target. + const LOG_TARGET: &'static str; + + /// Decodes data read from contract memory. + /// + /// # Parameters + /// - `env` - The current execution environment. + fn decode(env: &mut E) -> Result; +} + +/// Trait for processing a value based on additional information available from the environment. +pub trait Processor { + /// The type of value to be processed. + type Value; + + /// The log target. + const LOG_TARGET: &'static str; + + /// Processes the provided value. + /// + /// # Parameters + /// - `value` - The value to be processed. + /// - `env` - The current execution environment. + fn process(value: Self::Value, env: &impl Environment) -> Self::Value; +} + +/// Default processor implementation which just passes through the value unchanged. +pub struct Identity(PhantomData); +impl Processor for Identity { + type Value = Value; + const LOG_TARGET: &'static str = ""; + + fn process(value: Self::Value, _env: &impl Environment) -> Self::Value { + value + } +} + +/// Default implementation for decoding data read from contract memory. +pub struct Decodes>, L = ()>(PhantomData<(O, W, E, P, L)>); +impl< + Output: codec::Decode, + Weight: WeightInfo, + Error: Get, + ValueProcessor: Processor>, + Logger: LogTarget, + > Decode for Decodes +{ + type Output = Output; + type Processor = ValueProcessor; + type Error = Error; + const LOG_TARGET: &'static str = Logger::LOG_TARGET; + + /// Decodes data read from contract memory. + /// + /// # Parameters + /// - `env` - The current execution environment. + fn decode(env: &mut E) -> Result { + // Charge appropriate weight for copying from contract, based on input length, prior to + // decoding. reference: https://github.com/paritytech/polkadot-sdk/pull/4233/files#:~:text=CopyToContract(len)%20%3D%3E%20T%3A%3AWeightInfo%3A%3Aseal_return(len)%2C + let len = env.in_len(); + let weight = Weight::seal_return(len); + let charged = env.charge_weight(weight)?; + log::debug!(target: Self::LOG_TARGET, "pre-decode weight charged: len={len}, weight={weight}, charged={charged:?}"); + // Read encoded input supplied by contract for buffer. + let mut input = env.read(len)?; + log::debug!(target: Self::LOG_TARGET, "input read: input={input:?}"); + // Perform any additional processing required. Any implementation is expected to charge + // weight as appropriate. + input = Self::Processor::process(input, env); + // Finally decode and return. + Output::decode(&mut &input[..]).map_err(|_| { + log::error!(target: Self::LOG_TARGET, "decoding failed: unable to decode input into output type. input={input:?}"); + Error::get() + }) + } +} + +/// Error to be returned when decoding fails. +pub struct DecodingFailed(PhantomData); +impl Get for DecodingFailed { + fn get() -> DispatchError { + pallet_contracts::Error::::DecodingFailed.into() + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::{ + extension::read_from_buffer_weight, + mock::{MockEnvironment, RemoveFirstByte, Test}, + }; + use codec::{Decode as OriginalDecode, Encode}; + use frame_support::assert_ok; + + type EnumDecodes = Decodes, DecodingFailed>; + + #[test] + fn identity_processor_works() { + let env = MockEnvironment::default(); + assert_eq!(Identity::process(42, &env), 42); + assert_eq!(Identity::process(vec![0, 1, 2, 3, 4], &env), vec![0, 1, 2, 3, 4]); + } + + #[test] + fn remove_first_byte_processor_works() { + let env = MockEnvironment::default(); + let result = RemoveFirstByte::process(vec![0, 1, 2, 3, 4], &env); + assert_eq!(result, vec![1, 2, 3, 4]) + } + + #[test] + fn decode_works() { + test_cases().into_iter().for_each(|t| { + let (input, output) = (t.0, t.1); + println!("input: {:?} -> output: {:?}", input, output); + let mut env = MockEnvironment::new(0, input); + // Decode `input` to `output`. + assert_eq!(EnumDecodes::decode(&mut env), Ok(output)); + }); + } + + #[test] + fn decode_charges_weight() { + test_cases().into_iter().for_each(|t| { + let (input, output) = (t.0, t.1); + println!("input: {:?} -> output: {:?}", input, output); + let mut env = MockEnvironment::new(0, input.clone()); + // Decode `input` to `output`. + assert_ok!(EnumDecodes::decode(&mut env)); + // Decode charges weight based on the length of the input. + assert_eq!(env.charged(), read_from_buffer_weight(input.len() as u32)); + }); + } + + #[test] + fn decoding_failed_error_type_works() { + assert_eq!( + DecodingFailed::::get(), + pallet_contracts::Error::::DecodingFailed.into() + ) + } + + #[test] + fn decode_failure_returns_decoding_failed_error() { + let input = vec![100]; + let mut env = MockEnvironment::new(0, input.clone()); + let result = EnumDecodes::decode(&mut env); + assert_eq!(result, Err(pallet_contracts::Error::::DecodingFailed.into())); + } + + #[test] + fn decode_failure_charges_weight() { + let input = vec![100]; + let mut env = MockEnvironment::new(0, input.clone()); + assert!(EnumDecodes::decode(&mut env).is_err()); + // Decode charges weight based on the length of the input, also when decoding fails. + assert_eq!(env.charged(), ContractWeightsOf::::seal_return(input.len() as u32)); + } + + #[derive(Debug, Clone, PartialEq, Encode, OriginalDecode)] + enum ComprehensiveEnum { + SimpleVariant, + DataVariant(u8), + NamedFields { w: u8 }, + NestedEnum(InnerEnum), + OptionVariant(Option), + VecVariant(Vec), + TupleVariant(u8, u8), + NestedStructVariant(NestedStruct), + NestedEnumStructVariant(NestedEnumStruct), + } + + #[derive(Debug, Clone, PartialEq, Encode, OriginalDecode)] + enum InnerEnum { + A, + B { inner_data: u8 }, + C(u8), + } + + #[derive(Debug, Clone, PartialEq, Encode, OriginalDecode)] + struct NestedStruct { + x: u8, + y: u8, + } + + #[derive(Debug, Clone, PartialEq, Encode, OriginalDecode)] + struct NestedEnumStruct { + inner_enum: InnerEnum, + } + + // Creating a set of byte data input and the decoded enum variant. + fn test_cases() -> Vec<(Vec, ComprehensiveEnum)> { + vec![ + (vec![0, 0, 0, 0], ComprehensiveEnum::SimpleVariant), + (vec![1, 42, 0, 0], ComprehensiveEnum::DataVariant(42)), + (vec![2, 42, 0, 0], ComprehensiveEnum::NamedFields { w: 42 }), + (vec![3, 0, 0, 0], ComprehensiveEnum::NestedEnum(InnerEnum::A)), + (vec![3, 1, 42, 0], ComprehensiveEnum::NestedEnum(InnerEnum::B { inner_data: 42 })), + (vec![3, 2, 42, 0], ComprehensiveEnum::NestedEnum(InnerEnum::C(42))), + (vec![4, 1, 42, 0], ComprehensiveEnum::OptionVariant(Some(42))), + (vec![4, 0, 0, 0], ComprehensiveEnum::OptionVariant(None)), + (vec![5, 12, 1, 2, 3], ComprehensiveEnum::VecVariant(vec![1, 2, 3])), + (vec![5, 16, 1, 2, 3, 4], ComprehensiveEnum::VecVariant(vec![1, 2, 3, 4])), + (vec![5, 20, 1, 2, 3, 4, 5], ComprehensiveEnum::VecVariant(vec![1, 2, 3, 4, 5])), + (vec![6, 42, 43, 0], ComprehensiveEnum::TupleVariant(42, 43)), + ( + vec![7, 42, 43, 0], + ComprehensiveEnum::NestedStructVariant(NestedStruct { x: 42, y: 43 }), + ), + ( + vec![8, 1, 42, 0], + ComprehensiveEnum::NestedEnumStructVariant(NestedEnumStruct { + inner_enum: InnerEnum::B { inner_data: 42 }, + }), + ), + ] + } + + // Test showing all the different type of variants and its encoding. + #[test] + fn encoding_of_enum() { + // Creating each possible variant for an enum. + let enum_simple = ComprehensiveEnum::SimpleVariant; + let enum_data = ComprehensiveEnum::DataVariant(42); + let enum_named = ComprehensiveEnum::NamedFields { w: 42 }; + let enum_nested = ComprehensiveEnum::NestedEnum(InnerEnum::B { inner_data: 42 }); + let enum_option = ComprehensiveEnum::OptionVariant(Some(42)); + let enum_vec = ComprehensiveEnum::VecVariant(vec![1, 2, 3, 4, 5]); + let enum_tuple = ComprehensiveEnum::TupleVariant(42, 42); + let enum_nested_struct = + ComprehensiveEnum::NestedStructVariant(NestedStruct { x: 42, y: 42 }); + let enum_nested_enum_struct = + ComprehensiveEnum::NestedEnumStructVariant(NestedEnumStruct { + inner_enum: InnerEnum::C(42), + }); + + // Encode and print each variant individually to see their encoded values. + println!("{:?} -> {:?}", enum_simple, enum_simple.encode()); + println!("{:?} -> {:?}", enum_data, enum_data.encode()); + println!("{:?} -> {:?}", enum_named, enum_named.encode()); + println!("{:?} -> {:?}", enum_nested, enum_nested.encode()); + println!("{:?} -> {:?}", enum_option, enum_option.encode()); + println!("{:?} -> {:?}", enum_vec, enum_vec.encode()); + println!("{:?} -> {:?}", enum_tuple, enum_tuple.encode()); + println!("{:?} -> {:?}", enum_nested_struct, enum_nested_struct.encode()); + println!("{:?} -> {:?}", enum_nested_enum_struct, enum_nested_enum_struct.encode()); + } + + #[test] + fn encoding_decoding_dispatch_error() { + use sp_runtime::{ArithmeticError, DispatchError, ModuleError, TokenError}; + + let error = DispatchError::Module(ModuleError { + index: 255, + error: [2, 0, 0, 0], + message: Some("error message"), + }); + let encoded = error.encode(); + let decoded = DispatchError::decode(&mut &encoded[..]).unwrap(); + // DispatchError::Module index is 3 + assert_eq!(encoded, vec![3, 255, 2, 0, 0, 0]); + assert_eq!( + decoded, + // `message` is skipped for encoding. + DispatchError::Module(ModuleError { index: 255, error: [2, 0, 0, 0], message: None }) + ); + + // Example DispatchError::Token + let error = DispatchError::Token(TokenError::UnknownAsset); + let encoded = error.encode(); + let decoded = DispatchError::decode(&mut &encoded[..]).unwrap(); + assert_eq!(encoded, vec![7, 4]); + assert_eq!(decoded, error); + + // Example DispatchError::Arithmetic + let error = DispatchError::Arithmetic(ArithmeticError::Overflow); + let encoded = error.encode(); + let decoded = DispatchError::decode(&mut &encoded[..]).unwrap(); + assert_eq!(encoded, vec![8, 1]); + assert_eq!(decoded, error); + } +} diff --git a/extension/src/environment.rs b/extension/src/environment.rs new file mode 100644 index 00000000..e5eff083 --- /dev/null +++ b/extension/src/environment.rs @@ -0,0 +1,193 @@ +use crate::AccountIdOf; +use core::fmt::Debug; +use frame_support::pallet_prelude::Weight; +use pallet_contracts::chain_extension::{BufInBufOutState, ChargedAmount, Result, State}; +use sp_std::vec::Vec; + +/// Provides access to the parameters passed to a chain extension and its execution environment. +/// +/// A wrapper trait for `pallet_contracts::chain_extension::Environment`. All comments have been +/// copied solely for consistent developer experience in line with the wrapped type. +pub trait Environment { + /// The account identifier type for the runtime. + type AccountId; + /// The charged weight type. + type ChargedAmount: Debug; + + /// The function id within the `id` passed by a contract. + /// + /// It returns the two least significant bytes of the `id` passed by a contract as the other + /// two bytes represent the chain extension itself (the code which is calling this function). + fn func_id(&self) -> u16; + + /// The chain extension id within the `id` passed by a contract. + /// + /// It returns the two most significant bytes of the `id` passed by a contract which represent + /// the chain extension itself (the code which is calling this function). + fn ext_id(&self) -> u16; + + /// Charge the passed `amount` of weight from the overall limit. + /// + /// It returns `Ok` when there the remaining weight budget is larger than the passed + /// `weight`. It returns `Err` otherwise. In this case the chain extension should + /// abort the execution and pass through the error. + /// + /// The returned value can be used to with [`Self::adjust_weight`]. Other than that + /// it has no purpose. + /// + /// # Note + /// + /// Weight is synonymous with gas in substrate. + fn charge_weight(&mut self, amount: Weight) -> Result; + + /// Adjust a previously charged amount down to its actual amount. + /// + /// This is when a maximum a priori amount was charged and then should be partially + /// refunded to match the actual amount. + fn adjust_weight(&mut self, charged: Self::ChargedAmount, actual_weight: Weight); + + /// Grants access to the execution environment of the current contract call. + /// + /// Consult the functions on the returned type before re-implementing those functions. + // TODO: improve the return type to &mut + fn ext(&mut self) -> impl Ext; +} + +/// A wrapper type for `pallet_contracts::chain_extension::Environment`. +pub(crate) struct Env<'a, 'b, E: pallet_contracts::chain_extension::Ext, S: State>( + pub(crate) pallet_contracts::chain_extension::Environment<'a, 'b, E, S>, +); + +impl<'a, 'b, E: pallet_contracts::chain_extension::Ext, S: State> Environment + for Env<'a, 'b, E, S> +{ + type AccountId = AccountIdOf; + type ChargedAmount = ChargedAmount; + + fn func_id(&self) -> u16 { + self.0.func_id() + } + + fn ext_id(&self) -> u16 { + self.0.ext_id() + } + + fn charge_weight(&mut self, amount: Weight) -> Result { + self.0.charge_weight(amount) + } + + fn adjust_weight(&mut self, charged: Self::ChargedAmount, actual_weight: Weight) { + self.0.adjust_weight(charged, actual_weight) + } + + fn ext(&mut self) -> impl Ext { + ExternalEnvironment(self.0.ext()) + } +} + +/// A state that uses a buffer as input. +/// +/// A wrapper trait for `pallet_contracts::chain_extension::BufIn` related function available on +/// `pallet_contracts::chain_extension::Environment`. All comments have been copied solely for +/// consistent developer experience in line with the wrapped type. +pub trait BufIn { + /// The length of the input as passed in as `input_len`. + /// + /// A chain extension would use this value to calculate the dynamic part of its + /// weight. For example a chain extension that calculates the hash of some passed in + /// bytes would use `in_len` to charge the costs of hashing that amount of bytes. + /// This also subsumes the act of copying those bytes as a benchmarks measures both. + fn in_len(&self) -> u32; + /// Reads `min(max_len, in_len)` from contract memory. + /// + /// This does **not** charge any weight. The caller must make sure that the an + /// appropriate amount of weight is charged **before** reading from contract memory. + /// The reason for that is that usually the costs for reading data and processing + /// said data cannot be separated in a benchmark. Therefore a chain extension would + /// charge the overall costs either using `max_len` (worst case approximation) or using + /// [`in_len()`](Self::in_len). + fn read(&self, max_len: u32) -> Result>; +} + +impl<'a, 'b, E: pallet_contracts::chain_extension::Ext> BufIn for Env<'a, 'b, E, BufInBufOutState> { + fn in_len(&self) -> u32 { + self.0.in_len() + } + + fn read(&self, max_len: u32) -> Result> { + self.0.read(max_len) + } +} + +/// A state that uses a buffer as output. +/// +/// A wrapper trait for `pallet_contracts::chain_extension::BufOut` related function available on +/// `pallet_contracts::chain_extension::Environment`. All comments have been copied solely for +/// consistent developer experience in line with the wrapped type. +pub trait BufOut { + /// Write the supplied buffer to contract memory. + /// + /// If the contract supplied buffer is smaller than the passed `buffer` an `Err` is returned. + /// If `allow_skip` is set to true the contract is allowed to skip the copying of the buffer + /// by supplying the guard value of `pallet-contracts::SENTINEL` as `out_ptr`. The + /// `weight_per_byte` is only charged when the write actually happens and is not skipped or + /// failed due to a too small output buffer. + fn write( + &mut self, + buffer: &[u8], + allow_skip: bool, + weight_per_byte: Option, + ) -> Result<()>; +} + +impl<'a, 'b, E: pallet_contracts::chain_extension::Ext> BufOut + for Env<'a, 'b, E, BufInBufOutState> +{ + fn write( + &mut self, + buffer: &[u8], + allow_skip: bool, + weight_per_byte: Option, + ) -> Result<()> { + self.0.write(buffer, allow_skip, weight_per_byte) + } +} + +/// An interface that provides access to the external environment in which the smart-contract is +/// executed. +/// +/// This interface is specialized to an account of the executing code, so all operations are +/// implicitly performed on that account. +/// +/// A wrapper trait for `pallet_contracts::chain_extension::Ext`. All comments have been copied +/// solely for consistent developer experience in line with the wrapped type. +pub trait Ext { + /// The account identifier type for the runtime. + type AccountId; + + /// Returns a reference to the account id of the current contract. + fn address(&self) -> &Self::AccountId; +} + +impl Ext for () { + type AccountId = (); + + fn address(&self) -> &Self::AccountId { + &() + } +} + +/// A wrapper type for a type implementing `pallet_contracts::chain_extension::Ext`. +pub(crate) struct ExternalEnvironment<'a, T: pallet_contracts::chain_extension::Ext>(&'a mut T); + +impl<'a, E: pallet_contracts::chain_extension::Ext> Ext for ExternalEnvironment<'a, E> { + type AccountId = AccountIdOf; + fn address(&self) -> &Self::AccountId { + self.0.address() + } +} + +#[test] +fn default_ext_works() { + assert_eq!(().address(), &()) +} diff --git a/extension/src/functions.rs b/extension/src/functions.rs new file mode 100644 index 00000000..16ca1f1c --- /dev/null +++ b/extension/src/functions.rs @@ -0,0 +1,534 @@ +use super::*; +use core::fmt::Debug; + +/// A chain extension function. +pub trait Function { + /// The configuration of the contracts module. + type Config: pallet_contracts::Config; + /// Optional error conversion. + type Error: ErrorConverter; + + /// Executes the function. + /// + /// # Parameters + /// - `env` - The current execution environment. + fn execute( + env: &mut (impl Environment> + BufIn + BufOut), + ) -> Result; +} + +/// A function for dispatching a runtime call. +pub struct DispatchCall(PhantomData<(M, C, D, F, E, L)>); +impl< + Matcher: Matches, + Config: pallet_contracts::Config + + frame_system::Config< + RuntimeCall: GetDispatchInfo + Dispatchable, + >, + Decoder: Decode>>, + Filter: Contains> + 'static, + Error: ErrorConverter, + Logger: LogTarget, + > Function for DispatchCall +{ + /// The configuration of the contracts module. + type Config = Config; + /// Optional error conversion. + type Error = Error; + + /// Executes the function. + /// + /// # Parameters + /// - `env` - The current execution environment. + fn execute( + env: &mut (impl Environment + BufIn), + ) -> Result { + // Decode runtime call. + let call = Decoder::decode(env)?.into(); + log::debug!(target: Logger::LOG_TARGET, "decoded: call={call:?}"); + // Charge weight before dispatch. + let dispatch_info = call.get_dispatch_info(); + log::debug!(target: Logger::LOG_TARGET, "pre-dispatch info: dispatch_info={dispatch_info:?}"); + let charged = env.charge_weight(dispatch_info.weight)?; + log::debug!(target: Logger::LOG_TARGET, "pre-dispatch weight charged: charged={charged:?}"); + // Contract is the origin by default. + let origin = RawOrigin::Signed(env.ext().address().clone()); + log::debug!(target: Logger::LOG_TARGET, "contract origin: origin={origin:?}"); + let mut origin: Config::RuntimeOrigin = origin.into(); + // Ensure call allowed. + origin.add_filter(Filter::contains); + // Dispatch call. + let result = call.dispatch(origin); + log::debug!(target: Logger::LOG_TARGET, "dispatched: result={result:?}"); + // Adjust weight. + let weight = frame_support::dispatch::extract_actual_weight(&result, &dispatch_info); + env.adjust_weight(charged, weight); + log::debug!(target: Logger::LOG_TARGET, "weight adjusted: weight={weight:?}"); + match result { + Ok(_) => Ok(Converging(0)), + Err(e) => Error::convert(e.error, env), + } + } +} + +impl Matches for DispatchCall { + fn matches(env: &impl Environment) -> bool { + M::matches(env) + } +} + +/// A function for reading runtime state. +pub struct ReadState::Result>, E = (), L = ()>( + PhantomData<(M, C, R, D, F, RC, E, L)>, +); +impl< + Matcher: Matches, + Config: pallet_contracts::Config, + Read: Readable + Debug, + Decoder: Decode>, + Filter: Contains, + ResultConverter: Converter>>, + Error: ErrorConverter, + Logger: LogTarget, + > Function for ReadState +{ + /// The configuration of the contracts module. + type Config = Config; + /// Optional error conversion. + type Error = Error; + + /// Executes the function. + /// + /// # Parameters + /// - `env` - The current execution environment. + fn execute(env: &mut (impl Environment + BufIn + BufOut)) -> Result { + // Decode runtime state read + let read = Decoder::decode(env)?.into(); + log::debug!(target: Logger::LOG_TARGET, "decoded: read={read:?}"); + // Charge weight before read + let weight = read.weight(); + let charged = env.charge_weight(weight)?; + log::trace!(target: Logger::LOG_TARGET, "pre-read weight charged: weight={weight}, charged={charged:?}"); + // Ensure read allowed + ensure!(Filter::contains(&read), frame_system::Error::::CallFiltered); + let result = read.read(); + log::debug!(target: Logger::LOG_TARGET, "read: result={result:?}"); + // Perform any final conversion. Any implementation is expected to charge weight as + // appropriate. + let result = ResultConverter::convert(result, env).into(); + log::debug!(target: Logger::LOG_TARGET, "converted: result={result:?}"); + // Charge appropriate weight for writing to contract, based on result length. + let weight = ContractWeightsOf::::seal_input(result.len() as u32); + let charged = env.charge_weight(weight)?; + log::trace!(target: Logger::LOG_TARGET, "return result to contract: weight={weight}, charged={charged:?}"); + env.write(&result, false, None)?; // weight charged above + Ok(Converging(0)) + } +} + +impl Matches for ReadState { + fn matches(env: &impl Environment) -> bool { + M::matches(env) + } +} + +/// Trait to be implemented for a type handling a read of runtime state. +pub trait Readable { + /// The corresponding type carrying the result of the runtime state read. + type Result: Debug; + + /// Determines the weight of the read, used to charge the appropriate weight before the read is + /// performed. + fn weight(&self) -> Weight; + + /// Performs the read and returns the result. + fn read(self) -> Self::Result; +} + +/// Trait for converting a value based on additional information available from the environment. +pub trait Converter { + /// The type of value to be converted. + type Source; + /// The target type. + type Target; + /// The log target. + const LOG_TARGET: &'static str; + + /// Converts the provided value. + /// + /// # Parameters + /// - `value` - The value to be converted. + /// - `env` - The current execution environment. + fn convert(value: Self::Source, env: &impl Environment) -> Self::Target; +} + +/// A default converter, for converting (encoding) from some type into a byte array. +pub struct DefaultConverter(PhantomData); +impl>> Converter for DefaultConverter { + type Source = T; + type Target = Vec; + const LOG_TARGET: &'static str = ""; + + fn convert(value: Self::Source, _env: &impl Environment) -> Self::Target { + value.into() + } +} + +/// Trait for error conversion. +pub trait ErrorConverter { + /// The log target. + const LOG_TARGET: &'static str; + + /// Converts the provided error. + /// + /// # Parameters + /// - `error` - The error to be converted. + /// - `env` - The current execution environment. + fn convert(error: DispatchError, env: &impl Environment) -> Result; +} + +impl ErrorConverter for () { + const LOG_TARGET: &'static str = "pop-chain-extension::converters::error"; + + fn convert(error: DispatchError, _env: &impl Environment) -> Result { + Err(error) + } +} + +// Support tuples of at least one function (required for type resolution) and a maximum of ten. +#[impl_trait_for_tuples::impl_for_tuples(1, 10)] +#[tuple_types_custom_trait_bound(Function + Matches)] +impl Function for Tuple { + for_tuples!( where #( Tuple: Function )* ); + type Config = Runtime; + type Error = (); + + fn execute( + env: &mut (impl Environment> + BufIn + BufOut), + ) -> Result { + // Attempts to match a specified extension/function identifier to its corresponding + // function, as configured by the runtime. + for_tuples!( #( + if Tuple::matches(env) { + return Tuple::execute(env) + } + )* ); + + // Otherwise returns error indicating an unmatched request. + log::error!("no function could be matched"); + Err(pallet_contracts::Error::::DecodingFailed.into()) + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::{ + extension::{read_from_buffer_weight, write_to_contract_weight}, + matching::WithFuncId, + mock::{Noop, NoopFuncId, INVALID_FUNC_ID}, + }; + use codec::Encode; + use frame_support::traits::{Everything, Nothing}; + use frame_system::Call; + use mock::{new_test_ext, Functions, MockEnvironment, RuntimeCall, RuntimeRead, Test}; + use sp_core::ConstU32; + + type FuncId = ConstU32<42>; + + enum AtLeastOneByte {} + impl Contains> for AtLeastOneByte { + fn contains(input: &Vec) -> bool { + input.len() > 0 + } + } + + enum LargerThan100 {} + impl Contains for LargerThan100 { + fn contains(input: &u8) -> bool { + *input > 100 + } + } + + enum MustBeEven {} + impl Contains for MustBeEven { + fn contains(input: &u8) -> bool { + *input % 2 == 0 + } + } + + #[test] + fn contains_works() { + fn contains, T>(input: T, expected: bool) { + assert_eq!(C::contains(&input), expected); + } + contains::(42, true); + contains::>(vec![1, 2, 3, 4], true); + contains::(42, false); + contains::>(vec![1, 2, 3, 4], false); + contains::>(vec![], false); + contains::>(vec![1], true); + contains::>(vec![1, 2, 3, 4], true); + contains::(100, false); + contains::(101, true); + contains::(100, true); + contains::(101, false); + } + + mod dispatch_call { + use super::*; + + type DispatchCall = DispatchCallWithFilter; + type DispatchCallWithFilter = super::DispatchCall< + WithFuncId, + Test, + Decodes, DecodingFailed>, + Filter, + >; + + #[test] + fn dispatch_call_filtering_works() { + let call = + RuntimeCall::System(Call::remark_with_event { remark: "pop".as_bytes().to_vec() }); + let mut env = MockEnvironment::new(FuncId::get(), call.encode()); + let error = frame_system::Error::::CallFiltered.into(); + let expected = <() as ErrorConverter>::convert(error, &mut env).err(); + assert_eq!(DispatchCallWithFilter::::execute(&mut env).err(), expected); + } + + #[test] + fn dispatch_call_filtered_charges_weight() { + let call = + RuntimeCall::System(Call::remark_with_event { remark: "pop".as_bytes().to_vec() }); + let encoded_call = call.encode(); + let mut env = MockEnvironment::new(FuncId::get(), encoded_call.clone()); + assert!(DispatchCallWithFilter::::execute(&mut env).is_err()); + assert_eq!( + env.charged(), + read_from_buffer_weight(encoded_call.len() as u32) + + call.get_dispatch_info().weight + ); + } + + #[test] + fn dispatch_call_works() { + new_test_ext().execute_with(|| { + let call = RuntimeCall::System(Call::remark_with_event { + remark: "pop".as_bytes().to_vec(), + }); + let mut env = MockEnvironment::new(FuncId::get(), call.encode()); + assert!(matches!(DispatchCall::execute(&mut env), Ok(Converging(0)))); + }) + } + + #[test] + fn dispatch_call_returns_error() { + new_test_ext().execute_with(|| { + let call = RuntimeCall::System(Call::set_code { code: "pop".as_bytes().to_vec() }); + let mut env = MockEnvironment::new(FuncId::get(), call.encode()); + let error = DispatchCall::execute(&mut env).err(); + let expected = + <() as ErrorConverter>::convert(DispatchError::BadOrigin, &env).err(); + assert_eq!(error, expected); + }) + } + + #[test] + fn dispatch_call_charges_weight() { + new_test_ext().execute_with(|| { + let call = RuntimeCall::System(Call::remark_with_event { + remark: "pop".as_bytes().to_vec(), + }); + let encoded_call = call.encode(); + let mut env = MockEnvironment::new(FuncId::get(), encoded_call.clone()); + assert!(DispatchCall::execute(&mut env).is_ok()); + assert_eq!( + env.charged(), + read_from_buffer_weight(encoded_call.len() as u32) + + call.get_dispatch_info().weight + ); + }) + } + + #[test] + fn dispatch_call_adjusts_weight() { + new_test_ext().execute_with(|| { + // Attempt to perform non-existent migration with additional weight limit specified. + let weight_limit = Weight::from_parts(123456789, 12345); + let call = RuntimeCall::Contracts(pallet_contracts::Call::migrate { weight_limit }); + let encoded_call = call.encode(); + let mut env = MockEnvironment::new(FuncId::get(), encoded_call.clone()); + let expected: DispatchError = + pallet_contracts::Error::::NoMigrationPerformed.into(); + assert_eq!(DispatchCall::execute(&mut env).err().unwrap(), expected); + assert_eq!( + env.charged(), + read_from_buffer_weight(encoded_call.len() as u32) + + // Weight limit subtracted from pre-dispatch weight charged on failure. + call.get_dispatch_info().weight - + weight_limit + ); + }) + } + + #[test] + fn dispatch_call_with_invalid_input_returns_error() { + // Invalid encoded runtime call. + let input = vec![0, 99]; + let mut env = MockEnvironment::new(FuncId::get(), input.clone()); + let error = pallet_contracts::Error::::DecodingFailed.into(); + let expected = <() as ErrorConverter>::convert(error, &mut env).err(); + assert_eq!(DispatchCall::execute(&mut env).err(), expected); + } + + #[test] + fn dispatch_call_with_invalid_input_charges_weight() { + // Invalid encoded runtime call. + let input = vec![0, 99]; + let mut env = MockEnvironment::new(FuncId::get(), input.clone()); + assert!(DispatchCall::execute(&mut env).is_err()); + assert_eq!(env.charged(), read_from_buffer_weight(input.len() as u32,)); + } + } + + mod read_state { + use super::*; + use crate::mock::{RuntimeResult, UppercaseConverter}; + + type ReadState = ReadStateWithFilter; + type ReadStateWithFilter = super::ReadState< + WithFuncId, + Test, + RuntimeRead, + Decodes, DecodingFailed>, + Filter, + >; + type ReadStateWithResultConverter = super::ReadState< + WithFuncId, + Test, + RuntimeRead, + Decodes, DecodingFailed>, + Everything, + ResultConverter, + >; + + #[test] + fn read_state_filtering_works() { + let read = RuntimeRead::Ping; + let mut env = MockEnvironment::new(FuncId::get(), read.encode()); + let error = frame_system::Error::::CallFiltered.into(); + let expected = <() as ErrorConverter>::convert(error, &mut env).err(); + assert_eq!(ReadStateWithFilter::::execute(&mut env).err(), expected); + } + + #[test] + fn read_state_filtered_charges_weight() { + let read = RuntimeRead::Ping; + let encoded_read = read.encode(); + let mut env = MockEnvironment::new(FuncId::get(), encoded_read.clone()); + assert!(ReadStateWithFilter::::execute(&mut env).is_err()); + assert_eq!( + env.charged(), + read_from_buffer_weight(encoded_read.len() as u32) + read.weight() + ); + } + + #[test] + fn read_state_works() { + let read = RuntimeRead::Ping; + let expected = "pop".as_bytes().encode(); + let mut env = MockEnvironment::new(FuncId::get(), read.encode()); + assert!(matches!(ReadState::execute(&mut env), Ok(Converging(0)))); + // Check if the contract environment buffer is written correctly. + assert_eq!(env.buffer, expected); + } + + #[test] + fn read_state_result_conversion_works() { + let read = RuntimeRead::Ping; + let expected = RuntimeResult::Pong("pop".to_string()); + let mut env = MockEnvironment::new(FuncId::get(), read.encode()); + assert!(matches!( + ReadStateWithResultConverter::::execute(&mut env), + Ok(Converging(0)) + )); + // Check if the contract environment buffer is written correctly. + assert_eq!(env.buffer, UppercaseConverter::convert(expected, &env)); + } + + #[test] + fn read_state_charges_weight() { + let read = RuntimeRead::Ping; + let encoded_read = read.encode(); + let mut env = MockEnvironment::new(FuncId::get(), encoded_read.clone()); + assert!(ReadState::execute(&mut env).is_ok()); + let expected = "pop".as_bytes().encode(); + assert_eq!( + env.charged(), + read_from_buffer_weight(encoded_read.len() as u32) + + read.weight() + write_to_contract_weight(expected.len() as u32) + ); + } + + #[test] + fn read_state_with_invalid_input_returns_error() { + // Invalid encoded runtime state read. + let input = vec![0]; + let mut env = MockEnvironment::new(FuncId::get(), input.clone()); + let error = pallet_contracts::Error::::DecodingFailed.into(); + let expected = <() as ErrorConverter>::convert(error, &mut env).err(); + assert_eq!(ReadState::execute(&mut env).err(), expected); + } + + #[test] + fn read_state_with_invalid_input_charges_weight() { + // Invalid encoded runtime state read. + let input = vec![0]; + let mut env = MockEnvironment::new(FuncId::get(), input.clone()); + assert!(ReadState::execute(&mut env).is_err()); + assert_eq!(env.charged(), read_from_buffer_weight(input.len() as u32)); + } + } + + #[test] + fn execute_tuple_matches_and_executes_function() { + type Functions = (Noop, Test>,); + let mut env = MockEnvironment::new(NoopFuncId::get(), vec![]); + assert!(matches!(Functions::execute(&mut env), Ok(Converging(0)))); + } + + #[test] + fn execute_tuple_with_invalid_function_fails() { + let input = vec![]; + let mut env = MockEnvironment::new(INVALID_FUNC_ID, input.clone()); + let error = pallet_contracts::Error::::DecodingFailed.into(); + let expected = <() as ErrorConverter>::convert(error, &mut env).err(); + assert_eq!(Functions::execute(&mut env).err(), expected); + } + + #[test] + fn execute_tuple_with_invalid_function_does_not_charge_weight() { + let input = vec![]; + let mut env = MockEnvironment::new(INVALID_FUNC_ID, input.clone()); + assert!(Functions::execute(&mut env).is_err()); + // No weight charged as no function in the `Functions` tuple is matched to charge weight. + // See extension tests for extension call weight charges. + assert_eq!(env.charged(), Weight::default()); + } + + #[test] + fn default_error_conversion_works() { + let env = MockEnvironment::default(); + assert!(matches!( + <() as ErrorConverter>::convert(DispatchError::BadOrigin, &env), + Err(DispatchError::BadOrigin) + )); + } + + #[test] + fn default_conversion_works() { + let env = MockEnvironment::default(); + let source = "pop".to_string(); + assert_eq!(DefaultConverter::convert(source.clone(), &env), source.as_bytes()); + } +} diff --git a/extension/src/lib.rs b/extension/src/lib.rs index 650f73f8..875867f8 100644 --- a/extension/src/lib.rs +++ b/extension/src/lib.rs @@ -1,324 +1,228 @@ #![cfg_attr(not(feature = "std"), no_std)] -use codec::Encode; +use core::marker::PhantomData; +pub use decoding::{Decode, Decodes, DecodingFailed, Identity, Processor}; +pub use environment::{BufIn, BufOut, Environment, Ext}; use frame_support::{ - dispatch::{GetDispatchInfo, PostDispatchInfo}, - pallet_prelude::*, - traits::OriginTrait, + dispatch::{GetDispatchInfo, PostDispatchInfo, RawOrigin}, + ensure, + traits::{Contains, OriginTrait}, + weights::Weight, }; -use frame_system::RawOrigin; -use pallet_contracts::chain_extension::{ - BufInBufOutState, ChainExtension, Environment, Ext, InitState, RetVal, +pub use functions::{ + Converter, DefaultConverter, DispatchCall, ErrorConverter, Function, ReadState, Readable, }; -use sp_core::crypto::UncheckedFrom; +pub use matching::{Equals, FunctionId, Matches}; +pub use pallet_contracts::chain_extension::{Result, RetVal, State}; +use pallet_contracts::{ + chain_extension::{ChainExtension, InitState, RetVal::Converging}, + WeightInfo, +}; +use sp_core::Get; use sp_runtime::{traits::Dispatchable, DispatchError}; use sp_std::vec::Vec; +mod decoding; +mod environment; +mod functions; +mod matching; +// Mock runtime/environment for unit/integration testing. +#[cfg(test)] +mod mock; +// Integration tests using proxy contract and mock runtime. #[cfg(test)] mod tests; -mod v0; - -/// Logging target for categorizing messages from the Pop API extension module. -const LOG_TARGET: &str = "pop-api::extension"; - -const DECODING_FAILED_ERROR: DispatchError = DispatchError::Other("DecodingFailed"); -// TODO: issue #93, we can also encode the `pop_primitives::Error::UnknownCall` which means we do use -// `Error` in the runtime and it should stay in primitives. Perhaps issue #91 will also influence -// here. Should be looked at together. -const DECODING_FAILED_ERROR_ENCODED: [u8; 4] = [255u8, 0, 0, 0]; -const UNKNOWN_CALL_ERROR: DispatchError = DispatchError::Other("UnknownCall"); -// TODO: see above. -const UNKNOWN_CALL_ERROR_ENCODED: [u8; 4] = [254u8, 0, 0, 0]; - -type ContractSchedule = ::Schedule; - -/// Type of the state reader. -pub trait ReadState { - /// Query of the state read operations. - type StateQuery: Decode; - - /// Check if a state query is allowed. - fn contains(c: &Self::StateQuery) -> bool; - - /// Reads state using the provided query, returning the result as a byte vector. - fn read(read: Self::StateQuery) -> Vec; - - /// Decodes parameters into state query. - fn decode(params: &mut &[u8]) -> Result { - decode_checked(params) - } -} - -/// Type of the dispatch call filter. -pub trait CallFilter { - /// Query of the dispatch calls operations. - type Call: Decode; - /// Check if runtime call is allowed. - fn contains(t: &Self::Call) -> bool; -} +type AccountIdOf = ::AccountId; +pub type ContractWeightsOf = ::WeightInfo; +type RuntimeCallOf = ::RuntimeCall; -/// Pop API chain extension. +/// A configurable chain extension. #[derive(Default)] -pub struct ApiExtension(PhantomData); - -impl ChainExtension for ApiExtension +pub struct Extension(PhantomData); +impl ChainExtension for Extension where - T: pallet_contracts::Config + Runtime: pallet_contracts::Config + frame_system::Config< RuntimeCall: GetDispatchInfo + Dispatchable, >, - T::AccountId: UncheckedFrom + AsRef<[u8]>, - // Bound the type by the two traits which need to be implemented by the runtime. - I: ReadState + CallFilter::RuntimeCall> + 'static, + Config: self::Config> + 'static, { - fn call>( + /// Call the chain extension logic. + /// + /// # Parameters + /// - `env`: Access to the remaining arguments and the execution environment. + fn call>( &mut self, - env: Environment, - ) -> Result { - log::debug!(target:LOG_TARGET, " extension called "); - let mut env = env.buf_in_buf_out(); - // Charge weight for making a call from a contract to the runtime. - // `debug_message` weight is a good approximation of the additional overhead of going - // from contract layer to substrate layer. - // reference: https://github.com/paritytech/ink-examples/blob/b8d2caa52cf4691e0ddd7c919e4462311deb5ad0/psp22-extension/runtime/psp22-extension-example.rs#L236 - let contract_host_weight = ContractSchedule::::get().host_fn_weights; - env.charge_weight(contract_host_weight.debug_message)?; - - let (version, function_id, pallet_index, call_index) = extract_env(&env); - - let result = match FuncId::try_from(function_id) { - // Read encoded parameters from buffer and calculate weight for reading `len` bytes`. - Ok(function_id) => { - // reference: https://github.com/paritytech/polkadot-sdk/blob/117a9433dac88d5ac00c058c9b39c511d47749d2/substrate/frame/contracts/src/wasm/runtime.rs#L267 - let len = env.in_len(); - env.charge_weight(contract_host_weight.return_per_byte.saturating_mul(len.into()))?; - let params = env.read(len)?; - match function_id { - FuncId::Dispatch => { - dispatch::(&mut env, version, pallet_index, call_index, params) - }, - FuncId::ReadState => { - read_state::(&mut env, version, pallet_index, call_index, params) - }, - } - }, - Err(e) => Err(e), - }; + env: pallet_contracts::chain_extension::Environment, + ) -> Result { + let mut env = environment::Env(env.buf_in_buf_out()); + self.call(&mut env) + } +} - match result { - Ok(_) => Ok(RetVal::Converging(0)), - Err(e) => Ok(RetVal::Converging(convert_to_status_code(e, version))), - } +impl< + Runtime: pallet_contracts::Config, + Config: self::Config>, + > Extension +{ + fn call( + &mut self, + env: &mut (impl Environment + BufIn + BufOut), + ) -> Result { + log::trace!(target: Config::LOG_TARGET, "extension called"); + // Charge weight for making a call from a contract to the runtime. + // `debug_message` weight is a good approximation of the additional overhead of going from + // contract layer to substrate layer. reference: https://github.com/paritytech/polkadot-sdk/pull/4233/files#:~:text=DebugMessage(len)%20%3D%3E%20T%3A%3AWeightInfo%3A%3Aseal_debug_message(len)%2C + let len = env.in_len(); + let overhead = ContractWeightsOf::::seal_debug_message(len); + let charged = env.charge_weight(overhead)?; + log::debug!(target: Config::LOG_TARGET, "extension call weight charged: len={len}, weight={overhead}, charged={charged:?}"); + // Execute the function + Config::Functions::execute(env) } } -/// Extract discriminators (version, function_id, pallet_index, call_index) from the encoded call. -fn extract_env>(env: &Environment) -> (u8, u8, u8, u8) { - // Extract version and function_id from first two bytes. - let (version, function_id) = { - let bytes = env.func_id().to_le_bytes(); - (bytes[0], bytes[1]) - }; - // Extract pallet index and call / key index from last two bytes. - let (pallet_index, call_index) = { - let bytes = env.ext_id().to_le_bytes(); - (bytes[0], bytes[1]) - }; +/// Trait for configuration of the chain extension. +pub trait Config { + /// The function(s) available with the chain extension. + type Functions: Function; - (version, function_id, pallet_index, call_index) + /// The log target. + const LOG_TARGET: &'static str; } -fn read_state, StateReader: ReadState>( - env: &mut Environment, - version: u8, - pallet_index: u8, - call_index: u8, - mut params: Vec, -) -> Result<(), DispatchError> { - // Prefix params with version, pallet, index to simplify decoding. - params.insert(0, version); - params.insert(1, pallet_index); - params.insert(2, call_index); - let (mut encoded_version, mut encoded_read) = (¶ms[..1], ¶ms[1..]); - let version = decode_checked::(&mut encoded_version)?; - - // Charge weight for doing one storage read. - env.charge_weight(T::DbWeight::get().reads(1_u64))?; - let result = match version { - VersionedStateRead::V0 => { - let read = StateReader::decode(&mut encoded_read)?; - ensure!(StateReader::contains(&read), UNKNOWN_CALL_ERROR); - StateReader::read(read) - }, - }; - log::trace!( - target:LOG_TARGET, - "{} result: {:?}.", " read_state |", result - ); - env.write(&result, false, None) +/// Trait to enable specification of a log target. +pub trait LogTarget { + /// The log target. + const LOG_TARGET: &'static str; } -fn dispatch( - env: &mut Environment, - version: u8, - pallet_index: u8, - call_index: u8, - mut params: Vec, -) -> Result<(), DispatchError> -where - T: frame_system::Config< - RuntimeCall: GetDispatchInfo + Dispatchable, - >, - E: Ext, - Filter: CallFilter::RuntimeCall> + 'static, -{ - // Prefix params with version, pallet, index to simplify decoding. - params.insert(0, version); - params.insert(1, pallet_index); - params.insert(2, call_index); - let call = decode_checked::>(&mut ¶ms[..])?; - // Contract is the origin by default. - let origin: T::RuntimeOrigin = RawOrigin::Signed(env.ext().address().clone()).into(); - match call { - VersionedDispatch::V0(call) => dispatch_call::(env, call, origin), - } +impl LogTarget for () { + const LOG_TARGET: &'static str = "pop-chain-extension"; } -/// Helper method to decode the byte data to a provided type and throws error if failed. -fn decode_checked(params: &mut &[u8]) -> Result { - T::decode(params).map_err(|_| DECODING_FAILED_ERROR) +#[test] +fn default_log_target_works() { + assert!(matches!(<() as LogTarget>::LOG_TARGET, "pop-chain-extension")); } -fn dispatch_call( - env: &mut Environment, - call: T::RuntimeCall, - mut origin: T::RuntimeOrigin, -) -> Result<(), DispatchError> -where - T: frame_system::Config< - RuntimeCall: GetDispatchInfo + Dispatchable, - >, - E: Ext, - Filter: CallFilter::RuntimeCall> + 'static, -{ - const LOG_PREFIX: &str = " dispatch |"; +#[cfg(test)] +mod extension { + use super::*; + use crate::mock::{ + new_test_ext, DispatchExtFuncId, MockEnvironment, NoopFuncId, ReadExtFuncId, RuntimeCall, + RuntimeRead, Test, INVALID_FUNC_ID, + }; + use codec::Encode; + use frame_system::Call; + + #[test] + fn call_works() { + let input = vec![2, 2]; + let mut env = MockEnvironment::new(NoopFuncId::get(), input.clone()); + let mut extension = Extension::::default(); + assert!(matches!(extension.call(&mut env), Ok(Converging(0)))); + // Charges weight. + assert_eq!(env.charged(), overhead_weight(input.len() as u32)) + } - let charged_dispatch_weight = env.charge_weight(call.get_dispatch_info().weight)?; - log::debug!(target:LOG_TARGET, "{} Inputted RuntimeCall: {:?}", LOG_PREFIX, call); - origin.add_filter(Filter::contains); - match call.dispatch(origin) { - Ok(info) => { - log::debug!(target:LOG_TARGET, "{} success, actual weight: {:?}", LOG_PREFIX, info.actual_weight); - // Refund weight if the actual weight is less than the charged weight. - if let Some(actual_weight) = info.actual_weight { - env.adjust_weight(charged_dispatch_weight, actual_weight); - } - Ok(()) - }, - Err(err) => { - log::debug!(target:LOG_TARGET, "{} failed: error: {:?}", LOG_PREFIX, err.error); - // Refund weight if the actual weight is less than the charged weight. - if let Some(actual_weight) = err.post_info.actual_weight { - env.adjust_weight(charged_dispatch_weight, actual_weight); - } - Err(err.error) - }, + #[test] + fn calling_unknown_function_fails() { + let input = vec![2, 2]; + // No function registered for id 0. + let mut env = MockEnvironment::new(INVALID_FUNC_ID, input.clone()); + let mut extension = Extension::::default(); + assert!(matches!( + extension.call(&mut env), + Err(error) if error == pallet_contracts::Error::::DecodingFailed.into() + )); + // Charges weight. + assert_eq!(env.charged(), overhead_weight(input.len() as u32)) } -} -/// Wrapper to enable versioning of runtime state reads. -#[derive(Decode, Debug)] -enum VersionedStateRead { - /// Version zero of state reads. - #[codec(index = 0)] - V0, -} + #[test] + fn dispatch_call_works() { + new_test_ext().execute_with(|| { + let call = + RuntimeCall::System(Call::remark_with_event { remark: "pop".as_bytes().to_vec() }); + let encoded_call = call.encode(); + let mut env = MockEnvironment::new(DispatchExtFuncId::get(), encoded_call.clone()); + let mut extension = Extension::::default(); + assert!(matches!(extension.call(&mut env), Ok(Converging(0)))); + // Charges weight. + assert_eq!( + env.charged(), + overhead_weight(encoded_call.len() as u32) + + read_from_buffer_weight(encoded_call.len() as u32) + + call.get_dispatch_info().weight + ); + }); + } -/// Wrapper to enable versioning of runtime calls. -#[derive(Decode, Debug)] -enum VersionedDispatch { - /// Version zero of dispatch calls. - #[codec(index = 0)] - V0(RuntimeCall), -} + #[test] + fn dispatch_call_with_invalid_input_returns_error() { + // Invalid encoded runtime call. + let input = vec![0u8, 99]; + let mut env = MockEnvironment::new(DispatchExtFuncId::get(), input.clone()); + let mut extension = Extension::::default(); + assert!(extension.call(&mut env).is_err()); + // Charges weight. + assert_eq!( + env.charged(), + overhead_weight(input.len() as u32) + read_from_buffer_weight(input.len() as u32) + ); + } -/// Function identifiers used in the Pop API. -/// -/// The `FuncId` specifies the available functions that can be called through the Pop API. Each -/// variant corresponds to a specific functionality provided by the API, facilitating the -/// interaction between smart contracts and the runtime. -#[derive(Debug)] -pub enum FuncId { - /// Represents a function call to dispatch a runtime call. - Dispatch, - /// Represents a function call to read the state from the runtime. - ReadState, -} + #[test] + fn read_state_works() { + let read = RuntimeRead::Ping; + let encoded_read = read.encode(); + let expected = "pop".as_bytes().encode(); + let mut env = MockEnvironment::new(ReadExtFuncId::get(), encoded_read.clone()); + let mut extension = Extension::::default(); + assert!(matches!(extension.call(&mut env), Ok(Converging(0)))); + // Charges weight. + assert_eq!( + env.charged(), + overhead_weight(encoded_read.len() as u32) + + read_from_buffer_weight(encoded_read.len() as u32) + + read.weight() + + write_to_contract_weight(expected.len() as u32) + ); + // Check if the contract environment buffer is written correctly. + assert_eq!(env.buffer, expected); + } -impl TryFrom for FuncId { - type Error = DispatchError; + #[test] + fn read_state_with_invalid_input_returns_error() { + let input = vec![0u8, 99]; + let mut env = MockEnvironment::new( + ReadExtFuncId::get(), + // Invalid runtime state read. + input.clone(), + ); + let mut extension = Extension::::default(); + assert!(extension.call(&mut env).is_err()); + // Charges weight. + assert_eq!( + env.charged(), + overhead_weight(input.len() as u32) + read_from_buffer_weight(input.len() as u32) + ); + } - /// Attempts to convert a `u8` value to its corresponding `FuncId` variant. - /// - /// If the `u8` value does not match any known function identifier, it returns a - /// `DispatchError::Other` indicating an unknown function ID. - fn try_from(func_id: u8) -> Result { - let id = match func_id { - 0 => Self::Dispatch, - 1 => Self::ReadState, - _ => { - return Err(UNKNOWN_CALL_ERROR); - }, - }; - Ok(id) + // Weight charged for calling into the runtime from a contract. + fn overhead_weight(input_len: u32) -> Weight { + ContractWeightsOf::::seal_debug_message(input_len) } -} -/// Converts a `DispatchError` to a `u32` status code based on the version of the API the contract uses. -/// The contract calling the chain extension can optionally convert the status code to the descriptive `Error`. -/// -/// For `Error` see `pop_primitives::::error::Error`. -/// -/// The error encoding can vary per version, allowing for flexible and backward-compatible error handling. -/// As a result, contracts maintain compatibility across different versions of the runtime. -/// -/// # Parameters -/// -/// - `error`: The `DispatchError` encountered during contract execution. -/// - `version`: The version of the chain extension, used to determine the known errors. -pub(crate) fn convert_to_status_code(error: DispatchError, version: u8) -> u32 { - let mut encoded_error: [u8; 4] = match error { - // "UnknownCall" and "DecodingFailed" are mapped to specific errors in the API and will - // never change. - UNKNOWN_CALL_ERROR => UNKNOWN_CALL_ERROR_ENCODED, - DECODING_FAILED_ERROR => DECODING_FAILED_ERROR_ENCODED, - _ => { - let mut encoded_error = error.encode(); - // Resize the encoded value to 4 bytes in order to decode the value in a u32 (4 bytes). - encoded_error.resize(4, 0); - encoded_error.try_into().expect("qed, resized to 4 bytes line above") - }, - }; - match version { - // If an unknown variant of the `DispatchError` is detected the error needs to be converted - // into the encoded value of `Error::Other`. This conversion is performed by shifting the bytes one - // position forward (discarding the last byte as it is not used) and setting the first byte to the - // encoded value of `Other` (0u8). This ensures the error is correctly categorized as an `Other` - // variant which provides all the necessary information to debug which error occurred in the runtime. - // - // Byte layout explanation: - // - Byte 0: index of the variant within `Error` - // - Byte 1: - // - Must be zero for `UNIT_ERRORS`. - // - Represents the nested error in `SINGLE_NESTED_ERRORS`. - // - Represents the first level of nesting in `DOUBLE_NESTED_ERRORS`. - // - Byte 2: - // - Represents the second level of nesting in `DOUBLE_NESTED_ERRORS`. - // - Byte 3: - // - Unused or represents further nested information. - 0 => v0::handle_unknown_error(&mut encoded_error), - _ => encoded_error = UNKNOWN_CALL_ERROR_ENCODED, + // Weight charged for reading function call input from buffer. + pub(crate) fn read_from_buffer_weight(input_len: u32) -> Weight { + ContractWeightsOf::::seal_return(input_len) + } + + // Weight charged for writing to contract memory. + pub(crate) fn write_to_contract_weight(len: u32) -> Weight { + ContractWeightsOf::::seal_input(len) } - u32::from_le_bytes(encoded_error) } diff --git a/extension/src/matching.rs b/extension/src/matching.rs new file mode 100644 index 00000000..5966b9ff --- /dev/null +++ b/extension/src/matching.rs @@ -0,0 +1,84 @@ +use super::*; + +/// Trait for matching a function. +pub trait Matches { + /// Determines whether a function is a match. + /// + /// # Parameters + /// - `env` - The current execution environment. + fn matches(env: &impl Environment) -> bool; +} + +/// Matches an extension and function identifier. +pub struct Equals(PhantomData<(E, F)>); +impl, FuncId: Get> Matches for Equals { + fn matches(env: &impl Environment) -> bool { + env.ext_id() == ExtId::get() && env.func_id() == FuncId::get() + } +} + +/// Matches a function identifier only. +pub struct FunctionId(PhantomData); +impl> Matches for FunctionId { + fn matches(env: &impl Environment) -> bool { + env.func_id() == T::get() + } +} + +/// Matches a `u32` function identifier. +pub struct WithFuncId(PhantomData); +impl> Matches for WithFuncId { + fn matches(env: &impl Environment) -> bool { + let ext_id: [u8; 2] = env.ext_id().to_le_bytes(); + let func_id: [u8; 2] = env.func_id().to_le_bytes(); + u32::from_le_bytes([func_id[0], func_id[1], ext_id[0], ext_id[1]]) == T::get() + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::mock::MockEnvironment; + use sp_core::{ConstU16, ConstU32}; + + #[test] + fn equals_matches() { + let env = MockEnvironment::new(u32::from_be_bytes([0u8, 1, 0, 2]), vec![]); + assert!(Equals::, ConstU16<2>>::matches(&env)); + } + + #[test] + fn equals_does_not_match() { + // Fails due to the invalid function id. + let env = MockEnvironment::new(u32::from_be_bytes([0u8, 1, 0, 3]), vec![]); + assert!(!Equals::, ConstU16<2>>::matches(&env)); + + // Fails due to the invalid extension id. + let env = MockEnvironment::new(u32::from_be_bytes([0u8, 2, 0, 2]), vec![]); + assert!(!Equals::, ConstU16<2>>::matches(&env)); + } + + #[test] + fn function_id_matches() { + let env = MockEnvironment::new(u32::from_be_bytes([0u8, 1, 0, 2]), vec![]); + assert!(FunctionId::>::matches(&env)); + } + + #[test] + fn function_id_does_not_match() { + let env = MockEnvironment::new(u32::from_be_bytes([0u8, 1, 0, 3]), vec![]); + assert!(!FunctionId::>::matches(&env)); + } + + #[test] + fn func_id_matches() { + let env = MockEnvironment::default(); + assert!(WithFuncId::>::matches(&env)); + } + + #[test] + fn func_id_does_not_match() { + let env = MockEnvironment::new(1, vec![]); + assert!(!WithFuncId::>::matches(&env)); + } +} diff --git a/extension/src/mock.rs b/extension/src/mock.rs new file mode 100644 index 00000000..688bad51 --- /dev/null +++ b/extension/src/mock.rs @@ -0,0 +1,373 @@ +use crate::{ + decoding::Identity, environment, matching::WithFuncId, AccountIdOf, ContractWeightsOf, + Converter, Decodes, DecodingFailed, DefaultConverter, DispatchCall, Extension, Function, + Matches, Processor, ReadState, Readable, +}; +use codec::{Decode, Encode}; +use frame_support::{ + derive_impl, + pallet_prelude::Weight, + parameter_types, + traits::{fungible::Inspect, ConstU32, Everything, Nothing}, +}; +use frame_system::pallet_prelude::BlockNumberFor; +use pallet_contracts::{chain_extension::RetVal, DefaultAddressGenerator, Frame, Schedule}; +use sp_runtime::{BuildStorage, Perbill}; +use std::marker::PhantomData; + +pub(crate) const ALICE: u64 = 1; +pub(crate) const DEBUG_OUTPUT: pallet_contracts::DebugInfo = + pallet_contracts::DebugInfo::UnsafeDebug; +pub(crate) const GAS_LIMIT: Weight = Weight::from_parts(500_000_000_000, 3 * 1024 * 1024); +pub(crate) const INIT_AMOUNT: ::Balance = 100_000_000; +pub(crate) const INVALID_FUNC_ID: u32 = 0; + +pub(crate) type AccountId = AccountIdOf; +pub(crate) type Balance = + <::Currency as Inspect>>::Balance; +type DispatchCallWith>> = DispatchCall< + // Registered with func id 1 + WithFuncId, + // Runtime config + Test, + // Decode inputs to the function as runtime calls + Decodes, DecodingFailed, Processor>, + // Accept any filtering + Filter, +>; +pub(crate) type EventRecord = + frame_system::EventRecord<::RuntimeEvent, HashOf>; +type HashOf = ::Hash; +pub(crate) type MockEnvironment = Environment; +type ReadStateWith>> = ReadState< + // Registered with func id 1 + WithFuncId, + // Runtime config + Test, + // The runtime state reads available. + RuntimeRead, + // Decode inputs to the function as runtime calls + Decodes, DecodingFailed, Processor>, + // Accept any filtering + Filter, + // Convert the result of a read into the expected result + DefaultConverter, +>; + +frame_support::construct_runtime!( + pub enum Test { + System: frame_system, + Balances: pallet_balances, + Timestamp: pallet_timestamp, + Contracts: pallet_contracts, + } +); + +#[derive_impl(frame_system::config_preludes::TestDefaultConfig as frame_system::DefaultConfig)] +impl frame_system::Config for Test { + type AccountId = u64; + type AccountData = pallet_balances::AccountData; + type Block = frame_system::mocking::MockBlock; +} + +#[derive_impl(pallet_balances::config_preludes::TestDefaultConfig as pallet_balances::DefaultConfig)] +impl pallet_balances::Config for Test { + type AccountStore = System; + type ReserveIdentifier = [u8; 8]; +} + +#[derive_impl(pallet_timestamp::config_preludes::TestDefaultConfig as pallet_timestamp::DefaultConfig)] +impl pallet_timestamp::Config for Test {} + +impl pallet_contracts::Config for Test { + type Time = Timestamp; + type Randomness = Test; + type Currency = Balances; + type RuntimeEvent = RuntimeEvent; + type RuntimeCall = RuntimeCall; + type CallFilter = (); //TestFilter; + type CallStack = [Frame; 5]; + type WeightPrice = (); //Self; + type WeightInfo = (); + type ChainExtension = Extension; + type Schedule = MySchedule; + type DepositPerByte = DepositPerByte; + type DepositPerItem = DepositPerItem; + type DefaultDepositLimit = DefaultDepositLimit; + type AddressGenerator = DefaultAddressGenerator; + type MaxCodeLen = ConstU32<{ 100 * 1024 }>; + type MaxStorageKeyLen = ConstU32<128>; + type UnsafeUnstableInterface = (); //UnstableInterface; + type MaxDebugBufferLen = ConstU32<{ 2 * 1024 * 1024 }>; + type RuntimeHoldReason = RuntimeHoldReason; + type Migrations = (); //crate::migration::codegen::BenchMigrations; + type CodeHashLockupDepositPercent = CodeHashLockupDepositPercent; + type MaxDelegateDependencies = MaxDelegateDependencies; + type Debug = (); //TestDebug; + type Environment = (); + type Xcm = (); +} + +parameter_types! { + pub MySchedule: Schedule = { + let schedule = >::default(); + schedule + }; + pub static DepositPerByte: ::Balance = 1; + pub const DepositPerItem: ::Balance = 2; + pub static MaxDelegateDependencies: u32 = 32; + pub static MaxTransientStorageSize: u32 = 4 * 1024; + pub static CodeHashLockupDepositPercent: Perbill = Perbill::from_percent(0); + pub static DefaultDepositLimit: ::Balance = 10_000_000; +} + +impl frame_support::traits::Randomness, BlockNumberFor> for Test { + fn random(_subject: &[u8]) -> (HashOf, BlockNumberFor) { + (Default::default(), Default::default()) + } +} + +parameter_types! { + // IDs for functions for extension tests. + pub const DispatchExtFuncId : u32 = 1; + pub const ReadExtFuncId : u32 = 2; + // IDs for functions for contract tests. + pub const DispatchContractFuncId : u32 = 3; + pub const ReadContractFuncId : u32 = 4; + // IDs for function for contract tests but do nothing. + pub const DispatchContractNoopFuncId : u32 = 5; + pub const ReadContractNoopFuncId : u32 = 6; + // ID for function that does nothing + pub const NoopFuncId : u32 = u32::MAX; +} + +/// A query of mock runtime state. +#[derive(Encode, Decode, Debug)] +#[repr(u8)] +pub enum RuntimeRead { + #[codec(index = 1)] + Ping, +} +impl Readable for RuntimeRead { + /// The corresponding type carrying the result of the query for mock runtime state. + type Result = RuntimeResult; + + /// Determines the weight of the read, used to charge the appropriate weight before the read is + /// performed. + fn weight(&self) -> Weight { + match self { + RuntimeRead::Ping => Weight::from_parts(1_000u64, 1u64), + } + } + + /// Performs the read and returns the result. + fn read(self) -> Self::Result { + match self { + RuntimeRead::Ping => RuntimeResult::Pong("pop".to_string()), + } + } +} + +/// The result of a mock runtime state read. +#[derive(Debug, Decode, Encode)] +pub enum RuntimeResult { + #[codec(index = 1)] + Pong(String), +} + +impl Into> for RuntimeResult { + fn into(self) -> Vec { + match self { + RuntimeResult::Pong(value) => value.encode(), + } + } +} + +pub(crate) type Functions = ( + // Functions that allow everything for extension testing. + DispatchCallWith, + ReadStateWith, + // Functions that allow everything for contract testing. + DispatchCallWith, + ReadStateWith, + // Functions that allow nothing for contract testing. + DispatchCallWith, + ReadStateWith, + // Function that does nothing. + Noop, Test>, +); + +#[derive(Default)] +pub struct Config; +impl super::Config for Config { + type Functions = Functions; + const LOG_TARGET: &'static str = "pop-chain-extension"; +} + +// Removes first bytes of the encoded call, added by the chain extension call within the proxy +// contract. +pub struct RemoveFirstByte; +impl Processor for RemoveFirstByte { + type Value = Vec; + const LOG_TARGET: &'static str = ""; + + fn process(mut value: Self::Value, _env: &impl crate::Environment) -> Self::Value { + if !value.is_empty() { + value.remove(0); + } + value + } +} + +// A function that does nothing. +pub struct Noop(PhantomData<(M, C)>); +impl Function for Noop { + type Config = Config; + type Error = (); + + fn execute( + _env: &mut (impl environment::Environment + crate::BufIn), + ) -> pallet_contracts::chain_extension::Result { + Ok(RetVal::Converging(0)) + } +} +impl Matches for Noop { + fn matches(env: &impl crate::Environment) -> bool { + M::matches(env) + } +} + +/// A mocked chain extension environment. +pub(crate) struct Environment { + func_id: u16, + ext_id: u16, + charged: Vec, + pub(crate) buffer: Vec, + ext: E, +} + +impl Default for Environment { + fn default() -> Self { + Self::new(0, [].to_vec()) + } +} + +impl Environment { + pub(crate) fn new(id: u32, buffer: Vec) -> Self { + Self { + func_id: (id & 0x0000FFFF) as u16, + ext_id: (id >> 16) as u16, + charged: Vec::new(), + buffer, + ext: E::default(), + } + } + + pub(crate) fn charged(&self) -> Weight { + self.charged.iter().fold(Weight::zero(), |acc, b| acc.saturating_add(*b)) + } +} + +impl> + Clone> environment::Environment + for Environment +{ + type AccountId = E::AccountId; + type ChargedAmount = Weight; + + fn func_id(&self) -> u16 { + self.func_id + } + + fn ext_id(&self) -> u16 { + self.ext_id + } + + fn charge_weight( + &mut self, + amount: Weight, + ) -> pallet_contracts::chain_extension::Result { + self.charged.push(amount); + Ok(amount) + } + + fn adjust_weight(&mut self, charged: Self::ChargedAmount, actual_weight: Weight) { + let last = self + .charged + .iter() + .enumerate() + .filter_map(|(i, c)| (c == &charged).then_some(i)) + .last() + .unwrap(); + self.charged.remove(last); + self.charged.insert(last, actual_weight) + } + + fn ext(&mut self) -> impl environment::Ext { + self.ext.clone() + } +} + +impl environment::BufIn for Environment { + fn in_len(&self) -> u32 { + self.buffer.len() as u32 + } + + fn read(&self, _max_len: u32) -> pallet_contracts::chain_extension::Result> { + // TODO: handle max_len + Ok(self.buffer.clone()) + } +} + +impl environment::BufOut for Environment { + fn write( + &mut self, + buffer: &[u8], + _allow_skip: bool, + _weight_per_byte: Option, + ) -> pallet_contracts::chain_extension::Result<()> { + self.buffer = buffer.to_vec(); + Ok(()) + } +} + +/// A mocked smart contract environment. +#[derive(Clone, Default)] +pub(crate) struct MockExt { + pub(crate) address: AccountIdOf, +} +impl environment::Ext for MockExt { + type AccountId = AccountIdOf; + + fn address(&self) -> &Self::AccountId { + &self.address + } +} + +/// Test externalities. +pub(crate) fn new_test_ext() -> sp_io::TestExternalities { + let _ = env_logger::try_init(); + + let mut t = frame_system::GenesisConfig::::default().build_storage().unwrap(); + + pallet_balances::GenesisConfig:: { balances: vec![(ALICE, INIT_AMOUNT)] } + .assimilate_storage(&mut t) + .unwrap(); + + let mut ext = sp_io::TestExternalities::new(t); + ext.execute_with(|| System::set_block_number(1)); + ext +} + +/// A converter for converting string results to uppercase. +pub(crate) struct UppercaseConverter; +impl Converter for UppercaseConverter { + type Source = RuntimeResult; + type Target = Vec; + const LOG_TARGET: &'static str = ""; + + fn convert(value: Self::Source, _env: &impl crate::Environment) -> Self::Target { + match value { + RuntimeResult::Pong(value) => value.to_uppercase().encode(), + } + } +} diff --git a/extension/src/tests.rs b/extension/src/tests.rs index a47feef9..8d527df6 100644 --- a/extension/src/tests.rs +++ b/extension/src/tests.rs @@ -1,135 +1,230 @@ -use codec::{Decode, Encode}; - -// Test ensuring `func_id()` and `ext_id()` work as expected, i.e. extracting the first two -// bytes and the last two bytes, respectively, from a 4 byte array. -#[test] -fn test_byte_extraction() { - use rand::Rng; +use core::fmt::Debug; +use std::{path::Path, sync::LazyLock}; - // Helper functions - fn func_id(id: u32) -> u16 { - (id & 0x0000FFFF) as u16 - } - fn ext_id(id: u32) -> u16 { - (id >> 16) as u16 +use crate::{ + mock::{self, *}, + ErrorConverter, +}; +use codec::{Decode, Encode}; +use frame_support::weights::Weight; +use frame_system::Call; +use pallet_contracts::{Code, CollectEvents, ContractExecResult, Determinism, StorageDeposit}; +use sp_runtime::{ + DispatchError::{self, BadOrigin, Module}, + ModuleError, +}; + +static CONTRACT: LazyLock> = + LazyLock::new(|| initialize_contract("contract/target/ink/proxy.wasm")); + +mod dispatch_call { + use super::*; + + #[test] + fn dispatch_call_works() { + new_test_ext().execute_with(|| { + // Instantiate a new contract. + let contract = instantiate(); + let dispatch_result = call( + contract, + DispatchContractFuncId::get(), + RuntimeCall::System(Call::remark_with_event { remark: "pop".as_bytes().to_vec() }), + GAS_LIMIT, + ); + // Successfully return data. + let return_value = dispatch_result.result.unwrap(); + let decoded = , u32>>::decode(&mut &return_value.data[..]).unwrap(); + assert!(decoded.unwrap().is_empty()); + // Successfully emit event. + assert!(dispatch_result.events.unwrap().iter().any(|e| matches!(e.event, + RuntimeEvent::System(frame_system::Event::::Remarked { sender, .. }) + if sender == contract))); + assert_eq!(dispatch_result.storage_deposit, StorageDeposit::Charge(0)); + }); } - // Number of test iterations - let test_iterations = 1_000_000; - - // Create a random number generator - let mut rng = rand::thread_rng(); - - // Run the test for a large number of random 4-byte arrays - for _ in 0..test_iterations { - // Generate a random 4-byte array - let bytes: [u8; 4] = rng.gen(); - - // Convert the 4-byte array to a u32 value - let value = u32::from_le_bytes(bytes); - - // Extract the first two bytes (least significant 2 bytes) - let first_two_bytes = func_id(value); - - // Extract the last two bytes (most significant 2 bytes) - let last_two_bytes = ext_id(value); - - // Check if the first two bytes match the expected value - assert_eq!([bytes[0], bytes[1]], first_two_bytes.to_le_bytes()); + #[test] + fn dispatch_call_filtering_works() { + new_test_ext().execute_with(|| { + // Instantiate a new contract. + let contract = instantiate(); + let dispatch_result = call( + contract, + DispatchContractNoopFuncId::get(), + RuntimeCall::System(Call::remark_with_event { remark: "pop".as_bytes().to_vec() }), + GAS_LIMIT, + ); + assert_eq!( + dispatch_result.result, + Err(Module(ModuleError { + index: 0, + error: [5, 0, 0, 0], + message: Some("CallFiltered") + })) + ); + }); + } - // Check if the last two bytes match the expected value - assert_eq!([bytes[2], bytes[3]], last_two_bytes.to_le_bytes()); + #[test] + fn dispatch_call_returns_error() { + new_test_ext().execute_with(|| { + // Instantiate a new contract. + let contract = instantiate(); + let dispatch_result = call( + contract, + DispatchContractFuncId::get(), + // `set_code` requires root origin, expect throwing error. + RuntimeCall::System(Call::set_code { code: "pop".as_bytes().to_vec() }), + GAS_LIMIT, + ); + assert_eq!(dispatch_result.result.err(), Some(BadOrigin)) + }) } } -// Test showing all the different type of variants and its encoding. -#[test] -fn encoding_of_enum() { - #[derive(Debug, PartialEq, Encode, Decode)] - enum ComprehensiveEnum { - SimpleVariant, - DataVariant(u8), - NamedFields { w: u8 }, - NestedEnum(InnerEnum), - OptionVariant(Option), - VecVariant(Vec), - TupleVariant(u8, u8), - NestedStructVariant(NestedStruct), - NestedEnumStructVariant(NestedEnumStruct), +mod read_state { + use super::*; + + #[test] + fn read_state_works() { + new_test_ext().execute_with(|| { + // Instantiate a new contract. + let contract = instantiate(); + // Successfully return data. + let read_result = + call(contract, ReadContractFuncId::get(), RuntimeRead::Ping, GAS_LIMIT); + let return_value = read_result.result.unwrap(); + let decoded = , u32>>::decode(&mut &return_value.data[1..]).unwrap(); + let result = Ok("pop".as_bytes().to_vec()); + assert_eq!(decoded, result); + }); } - #[derive(Debug, PartialEq, Encode, Decode)] - enum InnerEnum { - A, - B { inner_data: u8 }, - C(u8), + #[test] + fn read_state_filtering_works() { + new_test_ext().execute_with(|| { + // Instantiate a new contract. + let contract = instantiate(); + // Successfully return data. + let read_result = + call(contract, ReadContractNoopFuncId::get(), RuntimeRead::Ping, GAS_LIMIT); + assert_eq!( + read_result.result, + Err(Module(ModuleError { + index: 0, + error: [5, 0, 0, 0], + message: Some("CallFiltered") + })) + ); + }); } - #[derive(Debug, PartialEq, Encode, Decode)] - struct NestedStruct { - x: u8, - y: u8, + #[test] + fn read_state_with_invalid_input_returns_error() { + new_test_ext().execute_with(|| { + // Instantiate a new contract. + let contract = instantiate(); + let read_result = call(contract, ReadExtFuncId::get(), 99u8, GAS_LIMIT); + let expected: DispatchError = pallet_contracts::Error::::DecodingFailed.into(); + // Make sure the error is passed through the error converter. + let error = + <() as ErrorConverter>::convert(expected, &mock::MockEnvironment::default()).err(); + assert_eq!(read_result.result.err(), error); + }) } +} - #[derive(Debug, PartialEq, Encode, Decode)] - struct NestedEnumStruct { - inner_enum: InnerEnum, - } +#[test] +fn noop_function_works() { + new_test_ext().execute_with(|| { + // Instantiate a new contract. + let contract = instantiate(); + let noop_result = call(contract, NoopFuncId::get(), (), GAS_LIMIT); + // Successfully return data. + let return_value = noop_result.result.unwrap(); + let decoded = , u32>>::decode(&mut &return_value.data[..]).unwrap(); + assert!(decoded.unwrap().is_empty()); + assert_eq!(noop_result.storage_deposit, StorageDeposit::Charge(0)); + }) +} - // Creating each possible variant for an enum. - let enum_simple = ComprehensiveEnum::SimpleVariant; - let enum_data = ComprehensiveEnum::DataVariant(42); - let enum_named = ComprehensiveEnum::NamedFields { w: 42 }; - let enum_nested = ComprehensiveEnum::NestedEnum(InnerEnum::B { inner_data: 42 }); - let enum_option = ComprehensiveEnum::OptionVariant(Some(42)); - let enum_vec = ComprehensiveEnum::VecVariant(vec![1, 2, 3, 4, 5]); - let enum_tuple = ComprehensiveEnum::TupleVariant(42, 42); - let enum_nested_struct = ComprehensiveEnum::NestedStructVariant(NestedStruct { x: 42, y: 42 }); - let enum_nested_enum_struct = ComprehensiveEnum::NestedEnumStructVariant(NestedEnumStruct { - inner_enum: InnerEnum::C(42), +#[test] +fn invalid_func_id_fails() { + new_test_ext().execute_with(|| { + // Instantiate a new contract. + let contract = instantiate(); + let result = call(contract, INVALID_FUNC_ID, (), GAS_LIMIT); + let expected: DispatchError = pallet_contracts::Error::::DecodingFailed.into(); + // Make sure the error is passed through the error converter. + let error = + <() as ErrorConverter>::convert(expected, &mock::MockEnvironment::default()).err(); + assert_eq!(result.result.err(), error); }); +} - // Encode and print each variant individually to see their encoded values. - println!("{:?} -> {:?}", enum_simple, enum_simple.encode()); - println!("{:?} -> {:?}", enum_data, enum_data.encode()); - println!("{:?} -> {:?}", enum_named, enum_named.encode()); - println!("{:?} -> {:?}", enum_nested, enum_nested.encode()); - println!("{:?} -> {:?}", enum_option, enum_option.encode()); - println!("{:?} -> {:?}", enum_vec, enum_vec.encode()); - println!("{:?} -> {:?}", enum_tuple, enum_tuple.encode()); - println!("{:?} -> {:?}", enum_nested_struct, enum_nested_struct.encode()); - println!("{:?} -> {:?}", enum_nested_enum_struct, enum_nested_enum_struct.encode()); +/// Initializing a new contract file if it does not exist. +fn initialize_contract(contract_path: &str) -> Vec { + if !Path::new(contract_path).exists() { + use contract_build::*; + let manifest_path = ManifestPath::new("contract/Cargo.toml").unwrap(); + let args = ExecuteArgs { + build_artifact: BuildArtifacts::CodeOnly, + build_mode: BuildMode::Debug, + manifest_path, + output_type: OutputType::Json, + verbosity: Verbosity::Quiet, + skip_wasm_validation: true, + ..Default::default() + }; + execute(args).unwrap(); + } + std::fs::read(contract_path).unwrap() } -#[test] -fn encoding_decoding_dispatch_error() { - use sp_runtime::{ArithmeticError, DispatchError, ModuleError, TokenError}; +/// Instantiating the contract. +fn instantiate() -> AccountId { + let result = Contracts::bare_instantiate( + ALICE, + 0, + GAS_LIMIT, + None, + Code::Upload(CONTRACT.clone()), + function_selector("new"), + Default::default(), + DEBUG_OUTPUT, + CollectEvents::UnsafeCollect, + ); + log::debug!("instantiate result: {result:?}"); + let result = result.result.unwrap(); + assert!(!result.result.did_revert()); + result.account_id +} - let error = DispatchError::Module(ModuleError { - index: 255, - error: [2, 0, 0, 0], - message: Some("error message"), - }); - let encoded = error.encode(); - let decoded = DispatchError::decode(&mut &encoded[..]).unwrap(); - assert_eq!(encoded, vec![3, 255, 2, 0, 0, 0]); - assert_eq!( - decoded, - // `message` is skipped for encoding. - DispatchError::Module(ModuleError { index: 255, error: [2, 0, 0, 0], message: None }) +/// Perform a call to a specified contract. +fn call( + contract: AccountId, + func_id: u32, + input: impl Encode + Debug, + gas_limit: Weight, +) -> ContractExecResult { + log::debug!("call: func_id={func_id}, input={input:?}"); + let result = Contracts::bare_call( + ALICE, + contract, + 0, + gas_limit, + None, + [function_selector("call"), (func_id, input.encode()).encode()].concat(), + DEBUG_OUTPUT, + CollectEvents::UnsafeCollect, + Determinism::Enforced, ); + log::debug!("gas consumed: {:?}", result.gas_consumed); + log::debug!("call result: {result:?}"); + result +} - // Example DispatchError::Token - let error = DispatchError::Token(TokenError::UnknownAsset); - let encoded = error.encode(); - let decoded = DispatchError::decode(&mut &encoded[..]).unwrap(); - assert_eq!(encoded, vec![7, 4]); - assert_eq!(decoded, error); - - // Example DispatchError::Arithmetic - let error = DispatchError::Arithmetic(ArithmeticError::Overflow); - let encoded = error.encode(); - let decoded = DispatchError::decode(&mut &encoded[..]).unwrap(); - assert_eq!(encoded, vec![8, 1]); - assert_eq!(decoded, error); +/// Construct the hashed bytes as a selector of function. +fn function_selector(name: &str) -> Vec { + sp_io::hashing::blake2_256(name.as_bytes())[0..4].to_vec() } diff --git a/extension/src/v0.rs b/extension/src/v0.rs deleted file mode 100644 index 4c3536a4..00000000 --- a/extension/src/v0.rs +++ /dev/null @@ -1,298 +0,0 @@ -#[cfg(test)] -use crate::convert_to_status_code; - -pub(crate) fn handle_unknown_error(encoded_error: &mut [u8; 4]) { - let unknown = match encoded_error[0] { - code if UNIT_ERRORS.contains(&code) => nested_errors(&encoded_error[1..], None), - // Single nested errors with a limit in their nesting. - // - // `TokenError`: has ten variants - translated to a limit of nine. - 7 => nested_errors(&encoded_error[1..], Some(9)), - // `ArithmeticError`: has 3 variants - translated to a limit of two. - 8 => nested_errors(&encoded_error[1..], Some(2)), - // `TransactionalError`: has 2 variants - translated to a limit of one. - 9 => nested_errors(&encoded_error[1..], Some(1)), - code if DOUBLE_NESTED_ERRORS.contains(&code) => nested_errors(&encoded_error[3..], None), - _ => true, - }; - if unknown { - encoded_error[..].rotate_right(1); - encoded_error[0] = 0u8; - } -} - -// Unit `Error` variants. -// (variant: index): -// - CannotLookup: 1, -// - BadOrigin: 2, -// - ConsumerRemaining: 4, -// - NoProviders: 5, -// - TooManyConsumers: 6, -// - Exhausted: 10, -// - Corruption: 11, -// - Unavailable: 12, -// - RootNotAllowed: 13, -// - UnknownFunctionId: 254, -// - DecodingFailed: 255, -const UNIT_ERRORS: [u8; 11] = [1, 2, 4, 5, 6, 10, 11, 12, 13, 254, 255]; - -#[cfg(test)] -const SINGLE_NESTED_ERRORS: [u8; 3] = [7, 8, 9]; - -// Double nested `Error` variants -// (variant: index): -// - Module: 3, -const DOUBLE_NESTED_ERRORS: [u8; 1] = [3]; - -// Checks for unknown nested errors within the `DispatchError`. -// - For single nested errors with a limit, it verifies if the nested value exceeds the limit. -// - For other nested errors, it checks if any subsequent bytes are non-zero. -// -// `nested_error` - The slice of bytes representing the nested error. -// `limit` - An optional limit for single nested errors. -fn nested_errors(nested_error: &[u8], limit: Option) -> bool { - match limit { - Some(l) => nested_error[0] > l || nested_error[1..].iter().any(|&x| x != 0u8), - None => nested_error.iter().any(|&x| x != 0u8), - } -} - -#[cfg(test)] -mod tests { - use super::*; - use pop_primitives::error::{ - ArithmeticError::*, - Error::{self, *}, - TokenError::*, - TransactionalError::*, - }; - use sp_runtime::DispatchError; - - // Compare all the different `DispatchError` variants with the expected `Error`. - #[test] - fn dispatch_error_to_error() { - let test_cases = vec![ - ( - DispatchError::Other(""), - (Other { dispatch_error_index: 0, error_index: 0, error: 0 }), - ), - (DispatchError::Other("UnknownCall"), UnknownCall), - (DispatchError::Other("DecodingFailed"), DecodingFailed), - (DispatchError::CannotLookup, CannotLookup), - (DispatchError::BadOrigin, BadOrigin), - ( - DispatchError::Module(sp_runtime::ModuleError { - index: 1, - error: [2, 0, 0, 0], - message: Some("hallo"), - }), - Module { index: 1, error: 2 }, - ), - (DispatchError::ConsumerRemaining, ConsumerRemaining), - (DispatchError::NoProviders, NoProviders), - (DispatchError::TooManyConsumers, TooManyConsumers), - (DispatchError::Token(sp_runtime::TokenError::BelowMinimum), Token(BelowMinimum)), - ( - DispatchError::Arithmetic(sp_runtime::ArithmeticError::Overflow), - Arithmetic(Overflow), - ), - ( - DispatchError::Transactional(sp_runtime::TransactionalError::LimitReached), - Transactional(LimitReached), - ), - (DispatchError::Exhausted, Exhausted), - (DispatchError::Corruption, Corruption), - (DispatchError::Unavailable, Unavailable), - (DispatchError::RootNotAllowed, RootNotAllowed), - ]; - for (dispatch_error, expected) in test_cases { - let status_code = crate::convert_to_status_code(dispatch_error, 0); - let error: Error = status_code.into(); - assert_eq!(error, expected); - } - } - - // Compare all the different `DispatchError::Other` possibilities with the expected `Error`. - #[test] - fn other_error() { - let test_cases = vec![ - ( - DispatchError::Other("Random"), - (Other { dispatch_error_index: 0, error_index: 0, error: 0 }), - ), - (DispatchError::Other("UnknownCall"), UnknownCall), - (DispatchError::Other("DecodingFailed"), DecodingFailed), - ]; - for (dispatch_error, expected) in test_cases { - let status_code = convert_to_status_code(dispatch_error, 0); - let error: Error = status_code.into(); - assert_eq!(error, expected); - } - } - - // Compare all the different `DispatchError::Module` nesting possibilities, which can not be - // handled, with the expected `Error`. See `double_nested_error_variants` fourth byte nesting. - #[test] - fn test_module_error() { - let test_cases = vec![ - DispatchError::Module(sp_runtime::ModuleError { - index: 1, - error: [2, 2, 0, 0], - message: Some("Random"), - }), - DispatchError::Module(sp_runtime::ModuleError { - index: 1, - error: [2, 2, 2, 0], - message: Some("Random"), - }), - DispatchError::Module(sp_runtime::ModuleError { - index: 1, - error: [2, 2, 2, 2], - message: Some("Random"), - }), - ]; - for dispatch_error in test_cases { - let status_code = convert_to_status_code(dispatch_error, 0); - let error: Error = status_code.into(); - assert_eq!(error, Other { dispatch_error_index: 3, error_index: 1, error: 2 }); - } - } - - // Converts 4 bytes into `Error` and handles unknown errors (used in `convert_to_status_code`). - fn into_error(mut error_bytes: [u8; 4]) -> Error { - handle_unknown_error(&mut error_bytes); - u32::from_le_bytes(error_bytes).into() - } - - // Tests the `handle_unknown_error` for `Error`, version 0. - // - // Unit variants: - // If the encoded value indicates a nested `Error` which is known by V0 as a - // unit variant, the encoded value is converted into `Error::Other`. - // - // Example: the error `BadOrigin` (encoded: `[2, 0, 0, 0]`) with a non-zero value for one - // of the bytes [1..4]: `[2, 0, 1, 0]` is converted into `[0, 2, 0, 1]` (shifting the bits - // one forward). This is decoded to `Error::Other { dispatch_error: 2, index: 0, error: 1 }`. - #[test] - fn unit_error_variants() { - let errors = vec![ - CannotLookup, - BadOrigin, - ConsumerRemaining, - NoProviders, - TooManyConsumers, - Exhausted, - Corruption, - Unavailable, - RootNotAllowed, - UnknownCall, - DecodingFailed, - ]; - // Compare an `Error`, which is converted from an encoded value, with the expected `Error`. - for (i, &error_code) in UNIT_ERRORS.iter().enumerate() { - // No nesting and unit variant correctly returned. - assert_eq!(into_error([error_code, 0, 0, 0]), errors[i]); - // Unexpected second byte nested. - assert_eq!( - into_error([error_code, 1, 0, 0]), - (Other { dispatch_error_index: error_code, error_index: 1, error: 0 }), - ); - // Unexpected third byte nested. - assert_eq!( - into_error([error_code, 1, 1, 0]), - (Other { dispatch_error_index: error_code, error_index: 1, error: 1 }), - ); - // Unexpected fourth byte nested. - assert_eq!( - into_error([error_code, 1, 1, 1]), - (Other { dispatch_error_index: error_code, error_index: 1, error: 1 }), - ); - } - } - - // Single nested variants: - // If the encoded value indicates a double nested `Error` which is known by V0 - // as a single nested variant, the encoded value is converted into `Error::Other`. - // - // Example: the error `Arithmetic(Overflow)` (encoded: `[8, 1, 0, 0]`) with a non-zero - // value for one of the bytes [2..4]: `[8, 1, 1, 0]` is converted into `[0, 8, 1, 1]`. This is - // decoded to `Error::Other { dispatch_error: 8, index: 1, error: 1 }`. - #[test] - fn single_nested_error_variants() { - let errors = vec![ - [Token(FundsUnavailable), Token(OnlyProvider)], - [Arithmetic(Underflow), Arithmetic(Overflow)], - [Transactional(LimitReached), Transactional(NoLayer)], - ]; - // Compare an `Error`, which is converted from an encoded value, with the expected `Error`. - for (i, &error_code) in SINGLE_NESTED_ERRORS.iter().enumerate() { - // No nested and single nested variant correctly returned. - assert_eq!(into_error([error_code, 0, 0, 0]), errors[i][0]); - assert_eq!(into_error([error_code, 1, 0, 0]), errors[i][1]); - // Unexpected third byte nested. - assert_eq!( - into_error([error_code, 1, 1, 0]), - (Other { dispatch_error_index: error_code, error_index: 1, error: 1 }), - ); - // Unexpected fourth byte nested. - assert_eq!( - into_error([error_code, 1, 1, 1]), - Other { dispatch_error_index: error_code, error_index: 1, error: 1 }, - ); - } - } - - #[test] - fn single_nested_unknown_variants() { - // Unknown `TokenError` variant. - assert_eq!( - into_error([7, 10, 0, 0]), - Other { dispatch_error_index: 7, error_index: 10, error: 0 } - ); - // Unknown `Arithmetic` variant. - assert_eq!( - into_error([8, 3, 0, 0]), - Other { dispatch_error_index: 8, error_index: 3, error: 0 } - ); - // Unknown `Transactional` variant. - assert_eq!( - into_error([9, 2, 0, 0]), - Other { dispatch_error_index: 9, error_index: 2, error: 0 } - ); - } - - // Double nested variants: - // If the encoded value indicates a triple nested `Error` which is known by V0 - // as a double nested variant, the encoded value is converted into `Error::Other`. - // - // Example: the error `Module { index: 10, error 5 }` (encoded: `[3, 10, 5, 0]`) with a non-zero - // value for the last byte: `[3, 10, 5, 3]` is converted into `[0, 3, 10, 5]`. This is - // decoded to `Error::Other { dispatch_error: 3, index: 10, error: 5 }`. - #[test] - fn double_nested_error_variants() { - // Compare an `Error`, which is converted from an encoded value, with the expected `Error`. - // No nesting and unit variant correctly returned. - assert_eq!(into_error([3, 0, 0, 0]), Module { index: 0, error: 0 }); - // Allowed single nesting and variant correctly returned. - assert_eq!(into_error([3, 1, 0, 0]), Module { index: 1, error: 0 }); - // Allowed double nesting and variant correctly returned. - assert_eq!(into_error([3, 1, 1, 0]), Module { index: 1, error: 1 }); - // Unexpected fourth byte nested. - assert_eq!( - into_error([3, 1, 1, 1]), - Other { dispatch_error_index: 3, error_index: 1, error: 1 }, - ); - } - - #[test] - fn test_random_encoded_values() { - assert_eq!( - into_error([100, 100, 100, 100]), - Other { dispatch_error_index: 100, error_index: 100, error: 100 } - ); - assert_eq!( - into_error([200, 200, 200, 200]), - Other { dispatch_error_index: 200, error_index: 200, error: 200 } - ); - } -} diff --git a/integration-tests/src/lib.rs b/integration-tests/src/lib.rs index c42035f9..eddbc103 100644 --- a/integration-tests/src/lib.rs +++ b/integration-tests/src/lib.rs @@ -299,7 +299,9 @@ fn reserve_transfer_native_asset_from_relay_to_para() { let delivery_fees = PaseoRelay::execute_with(|| { xcm_helpers::transfer_assets_delivery_fees::< ::XcmSender, - >(test.args.assets.clone(), 0, test.args.weight_limit, test.args.beneficiary, test.args.dest) + >( + test.args.assets.clone(), 0, test.args.weight_limit, test.args.beneficiary, test.args.dest + ) }); let sender_balance_after = test.sender.balance; @@ -353,7 +355,9 @@ fn reserve_transfer_native_asset_from_para_to_relay() { let delivery_fees = PopNetworkPara::execute_with(|| { xcm_helpers::transfer_assets_delivery_fees::< ::XcmSender, - >(test.args.assets.clone(), 0, test.args.weight_limit, test.args.beneficiary, test.args.dest) + >( + test.args.assets.clone(), 0, test.args.weight_limit, test.args.beneficiary, test.args.dest + ) }); // Sender's balance is reduced @@ -399,7 +403,9 @@ fn reserve_transfer_native_asset_from_system_para_to_para() { let delivery_fees = AssetHubPaseoPara::execute_with(|| { xcm_helpers::transfer_assets_delivery_fees::< ::XcmSender, - >(test.args.assets.clone(), 0, test.args.weight_limit, test.args.beneficiary, test.args.dest) + >( + test.args.assets.clone(), 0, test.args.weight_limit, test.args.beneficiary, test.args.dest + ) }); // Sender's balance is reduced @@ -417,7 +423,8 @@ fn reserve_transfer_native_asset_from_system_para_to_para() { fn reserve_transfer_native_asset_from_para_to_system_para() { init_tracing(); - // Setup: reserve transfer from AH to Pop, so that sovereign account accurate for return transfer + // Setup: reserve transfer from AH to Pop, so that sovereign account accurate for return + // transfer let amount_to_send: Balance = ASSET_HUB_PASEO_ED * 1000; fund_pop_from_system_para( AssetHubPaseoParaSender::get(), @@ -462,7 +469,9 @@ fn reserve_transfer_native_asset_from_para_to_system_para() { let delivery_fees = PopNetworkPara::execute_with(|| { xcm_helpers::transfer_assets_delivery_fees::< ::XcmSender, - >(test.args.assets.clone(), 0, test.args.weight_limit, test.args.beneficiary, test.args.dest) + >( + test.args.assets.clone(), 0, test.args.weight_limit, test.args.beneficiary, test.args.dest + ) }); // Sender's balance is reduced @@ -482,8 +491,8 @@ fn reserve_transfer_native_asset_from_para_to_system_para() { // // let beneficiary: sp_runtime::AccountId32 = [1u8; 32].into(); // -// // Setup: reserve transfer from relay to Pop, so that sovereign account accurate for return transfer -// let amount_to_send: Balance = pop_runtime::UNIT * 1000; +// // Setup: reserve transfer from relay to Pop, so that sovereign account accurate for return +// transfer let amount_to_send: Balance = pop_runtime::UNIT * 1000; // fund_pop_from_relay(PaseoRelaySender::get(), amount_to_send, beneficiary.clone()); // // let message = { @@ -554,11 +563,11 @@ fn reserve_transfer_native_asset_from_para_to_system_para() { // PaseoRelay, // vec![ // // We currently only check that the message was processed successfully -// RuntimeEvent::MessageQueue(pallet_message_queue::Event::Processed { success: true, .. }) => {}, -// // TODO: check order placed once we can have on-demand para id registered (probably via setting raw storage as a workaround) -// // RuntimeEvent::OnDemandAssignmentProvider(assigner_on_demand::Event::OnDemandOrderPlaced { -// // .. -// // }) => {}, +// RuntimeEvent::MessageQueue(pallet_message_queue::Event::Processed { success: true, .. }) => +// {}, // TODO: check order placed once we can have on-demand para id registered (probably via +// setting raw storage as a workaround) // +// RuntimeEvent::OnDemandAssignmentProvider(assigner_on_demand::Event::OnDemandOrderPlaced { // +// .. // }) => {}, // ] // ); // }); @@ -570,8 +579,8 @@ fn reserve_transfer_native_asset_from_para_to_system_para() { // PopNetworkPara, // vec![ // RuntimeEvent::PolkadotXcm(pallet_xcm::Event::ResponseReady { query_id: 0, .. }) => {}, -// RuntimeEvent::MessageQueue(pallet_message_queue::Event::Processed { success: true, .. }) => {}, -// ] +// RuntimeEvent::MessageQueue(pallet_message_queue::Event::Processed { success: true, .. }) => +// {}, ] // ); // }); // } diff --git a/node/src/command.rs b/node/src/command.rs index b1fcd614..a83253fc 100644 --- a/node/src/command.rs +++ b/node/src/command.rs @@ -64,9 +64,8 @@ impl RuntimeResolver for PathBuf { fn load_spec(id: &str) -> std::result::Result, String> { Ok(match id { - "dev" | "devnet" | "dev-paseo" => { - Box::new(chain_spec::development_config(Relay::PaseoLocal)) - }, + "dev" | "devnet" | "dev-paseo" => + Box::new(chain_spec::development_config(Relay::PaseoLocal)), "test" | "testnet" | "pop-paseo" => Box::new(chain_spec::testnet_config(Relay::Paseo)), "" | "local" => Box::new(chain_spec::development_config(Relay::PaseoLocal)), path => { diff --git a/pallets/api/Cargo.toml b/pallets/api/Cargo.toml index f9a807a3..d2d444bf 100644 --- a/pallets/api/Cargo.toml +++ b/pallets/api/Cargo.toml @@ -11,8 +11,12 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] codec.workspace = true +log.workspace = true scale-info.workspace = true +# Local +pop-chain-extension.workspace = true + # Substrate frame-benchmarking.workspace = true frame-support.workspace = true @@ -42,6 +46,7 @@ std = [ "frame-system/std", "pallet-assets/std", "pallet-balances/std", + "pop-chain-extension/std", "scale-info/std", "sp-core/std", "sp-io/std", diff --git a/pallets/api/src/extension.rs b/pallets/api/src/extension.rs new file mode 100644 index 00000000..8469ae40 --- /dev/null +++ b/pallets/api/src/extension.rs @@ -0,0 +1,180 @@ +use core::{fmt::Debug, marker::PhantomData}; +use frame_support::traits::Get; +pub use pop_chain_extension::{ + Config, ContractWeightsOf, DecodingFailed, DispatchCall, ReadState, Readable, +}; +use pop_chain_extension::{ + Converter, Decodes, Environment, LogTarget, Matches, Processor, Result, RetVal, +}; +use sp_runtime::DispatchError; +use sp_std::vec::Vec; + +/// Encoded version of `pallet_contracts::Error::DecodingFailed`, as found within +/// `DispatchError::ModuleError`. +pub const DECODING_FAILED_ERROR: [u8; 4] = [11, 0, 0, 0]; +/// The logging target for the chain extension. +pub const LOG_TARGET: &str = "pop-api::extension"; + +/// The chain extension used by the API. +pub type Extension = pop_chain_extension::Extension; +/// Decodes output by prepending bytes from ext_id() + func_id() +pub type DecodesAs = + Decodes; + +/// Prepends bytes from ext_id() + func_id() to prefix the encoded input bytes to determine the +/// versioned output +pub struct Prepender; +impl Processor for Prepender { + /// The type of value to be processed. + type Value = Vec; + + /// The log target. + const LOG_TARGET: &'static str = "pop-api::extension::processor"; + + /// Processes the provided value. + /// + /// # Parameters + /// - `value` - The value to be processed. + /// - `env` - The current execution environment. + fn process(mut value: Self::Value, env: &impl Environment) -> Self::Value { + // Resolve version, pallet and call index from environment + let version = version(env); + let (module, index) = module_and_index(env); + // Prepend bytes + value.splice(0..0, [version, module, index]); + log::debug!(target: Self::LOG_TARGET, "prepender: version={version}, module={module}, index={index}"); + value + } +} + +/// Matches on the first byte of a function identifier only. +pub struct IdentifiedByFirstByteOfFunctionId(PhantomData); +impl> Matches for IdentifiedByFirstByteOfFunctionId { + fn matches(env: &impl Environment) -> bool { + func_id(env) == T::get() + } +} + +/// A log target for dispatched calls. +pub struct DispatchCallLogTarget; +impl LogTarget for DispatchCallLogTarget { + const LOG_TARGET: &'static str = "pop-api::extension::dispatch"; +} + +/// A log target for state reads. +pub struct ReadStateLogTarget; +impl LogTarget for ReadStateLogTarget { + const LOG_TARGET: &'static str = "pop-api::extension::read-state"; +} + +/// Conversion of a `DispatchError` to a versioned error. +pub struct VersionedErrorConverter(PhantomData); +impl + Into + Debug> pop_chain_extension::ErrorConverter + for VersionedErrorConverter +{ + /// The log target. + const LOG_TARGET: &'static str = "pop-api::extension::converters::versioned-error"; + + /// Converts the provided error. + /// + /// # Parameters + /// - `error` - The error to be converted. + /// - `env` - The current execution environment. + fn convert(error: DispatchError, env: &impl Environment) -> Result { + // Defer to supplied versioned error conversion type + let version = version(env); + log::debug!(target: Self::LOG_TARGET, "versioned error converter: error={error:?}, version={version}"); + let error: Error = (error, version).into(); + log::debug!(target: Self::LOG_TARGET, "versioned error converter: converted error={error:?}"); + Ok(RetVal::Converging(error.into())) + } +} + +/// Conversion of a read result to a versioned read result. +pub struct VersionedResultConverter(PhantomData<(S, T)>); +impl + Debug> Converter + for VersionedResultConverter +{ + /// The type of value to be converted. + type Source = Source; + /// The target type. + type Target = Target; + /// The log target. + const LOG_TARGET: &'static str = "pop-api::extension::converters::versioned-result"; + + /// Converts the provided value. + /// + /// # Parameters + /// - `value` - The value to be converted. + /// - `env` - The current execution environment. + fn convert(value: Self::Source, env: &impl Environment) -> Self::Target { + // Defer to supplied versioned result conversion type + let version = version(env); + log::debug!(target: Self::LOG_TARGET, "versioned result converter: result={value:?}, version={version}"); + let converted: Target = (value, version).into(); + log::debug!(target: Self::LOG_TARGET, "versioned result converter: converted result={converted:?}"); + converted + } +} + +fn func_id(env: &impl Environment) -> u8 { + // TODO: update once the encoding scheme order has been finalised: expected to be + // env.ext_id().to_le_bytes()[0] + env.func_id().to_le_bytes()[1] +} + +fn module_and_index(env: &impl Environment) -> (u8, u8) { + // TODO: update once the encoding scheme order has been finalised: expected to be + // env.func_id().to_le_bytes()[0..1] + let bytes = env.ext_id().to_le_bytes(); + (bytes[0], bytes[1]) +} + +fn version(env: &impl Environment) -> u8 { + // TODO: update once the encoding scheme order has been finalised: expected to be + // env.ext_id().to_le_bytes()[1] + env.func_id().to_le_bytes()[0] +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::extension::Prepender; + use frame_support::pallet_prelude::Weight; + use pop_chain_extension::Ext; + + #[test] + fn prepender_works() { + let env = MockEnvironment { func_id: 1, ext_id: u16::from_le_bytes([2, 3]) }; + assert_eq!(Prepender::process(vec![0u8], &env), vec![1, 2, 3, 0]); + } + + struct MockEnvironment { + func_id: u16, + ext_id: u16, + } + impl Environment for MockEnvironment { + type AccountId = (); + type ChargedAmount = Weight; + + fn func_id(&self) -> u16 { + self.func_id + } + + fn ext_id(&self) -> u16 { + self.ext_id + } + + fn charge_weight(&mut self, _amount: Weight) -> Result { + unimplemented!() + } + + fn adjust_weight(&mut self, _charged: Self::ChargedAmount, _actual_weight: Weight) { + unimplemented!() + } + + fn ext(&mut self) -> impl Ext { + unimplemented!() + } + } +} diff --git a/pallets/api/src/fungibles/mod.rs b/pallets/api/src/fungibles/mod.rs index 6ff8ac87..dac002e9 100644 --- a/pallets/api/src/fungibles/mod.rs +++ b/pallets/api/src/fungibles/mod.rs @@ -81,6 +81,41 @@ pub mod pallet { AssetExists(AssetIdOf), } + /// Results of state reads for the fungibles API. + #[derive(Debug)] + pub enum ReadResult { + /// Total token supply for a specified asset. + TotalSupply(BalanceOf), + /// Account balance for a specified `asset` and `owner`. + BalanceOf(BalanceOf), + /// Allowance for a `spender` approved by an `owner`, for a specified `asset`. + Allowance(BalanceOf), + /// Name of the specified asset. + TokenName(Vec), + /// Symbol for the specified asset. + TokenSymbol(Vec), + /// Decimals for the specified asset. + TokenDecimals(u8), + /// Whether the specified asset exists. + AssetExists(bool), + } + + impl ReadResult { + /// Encodes the result. + pub fn encode(&self) -> Vec { + use ReadResult::*; + match self { + TotalSupply(result) => result.encode(), + BalanceOf(result) => result.encode(), + Allowance(result) => result.encode(), + TokenName(result) => result.encode(), + TokenSymbol(result) => result.encode(), + TokenDecimals(result) => result.encode(), + AssetExists(result) => result.encode(), + } + } + } + /// Configure the pallet by specifying the parameters and types on which it depends. #[pallet::config] pub trait Config: frame_system::Config + pallet_assets::Config { @@ -385,7 +420,8 @@ pub mod pallet { AssetsOf::::clear_metadata(origin, asset.into()) } - /// Creates `value` amount of tokens and assigns them to `account`, increasing the total supply. + /// Creates `value` amount of tokens and assigns them to `account`, increasing the total + /// supply. /// /// # Parameters /// - `asset` - The asset to mint. @@ -435,38 +471,50 @@ pub mod pallet { } impl Pallet { - /// Reads fungible asset state based on the provided value. + fn weight_approve(approve: u32, cancel: u32) -> Weight { + ::WeightInfo::approve(cancel, approve) + } + } + + impl crate::Read for Pallet { + /// The type of read requested. + type Read = Read; + /// The type or result returned. + type Result = ReadResult; + + /// Determines the weight of the requested read, used to charge the appropriate weight + /// before the read is performed. /// - /// This function matches the value to determine the type of state query and returns the - /// encoded result. + /// # Parameters + /// - `request` - The read request. + fn weight(_request: &Self::Read) -> Weight { + // TODO: match on request and return benchmarked weight + T::DbWeight::get().reads(1_u64) + } + + /// Performs the requested read and returns the result. /// - /// # Parameter - /// - `value` - An instance of `Read`, which specifies the type of state query and - /// the associated parameters. - pub fn read_state(value: Read) -> Vec { + /// # Parameters + /// - `request` - The read request. + fn read(request: Self::Read) -> Self::Result { use Read::*; - - match value { - TotalSupply(asset) => AssetsOf::::total_supply(asset).encode(), - BalanceOf { asset, owner } => AssetsOf::::balance(asset, owner).encode(), - Allowance { asset, owner, spender } => { - AssetsOf::::allowance(asset, &owner, &spender).encode() - }, - TokenName(asset) => { - as MetadataInspect>>::name(asset).encode() - }, - TokenSymbol(asset) => { - as MetadataInspect>>::symbol(asset).encode() - }, - TokenDecimals(asset) => { - as MetadataInspect>>::decimals(asset).encode() - }, - AssetExists(asset) => AssetsOf::::asset_exists(asset).encode(), + match request { + TotalSupply(asset) => ReadResult::TotalSupply(AssetsOf::::total_supply(asset)), + BalanceOf { asset, owner } => + ReadResult::BalanceOf(AssetsOf::::balance(asset, owner)), + Allowance { asset, owner, spender } => + ReadResult::Allowance(AssetsOf::::allowance(asset, &owner, &spender)), + TokenName(asset) => ReadResult::TokenName( as MetadataInspect< + AccountIdOf, + >>::name(asset)), + TokenSymbol(asset) => ReadResult::TokenSymbol( as MetadataInspect< + AccountIdOf, + >>::symbol(asset)), + TokenDecimals(asset) => ReadResult::TokenDecimals( + as MetadataInspect>>::decimals(asset), + ), + AssetExists(asset) => ReadResult::AssetExists(AssetsOf::::asset_exists(asset)), } } - - fn weight_approve(approve: u32, cancel: u32) -> Weight { - ::WeightInfo::approve(cancel, approve) - } } } diff --git a/pallets/api/src/fungibles/tests.rs b/pallets/api/src/fungibles/tests.rs index d881a3c1..d6d4ef2f 100644 --- a/pallets/api/src/fungibles/tests.rs +++ b/pallets/api/src/fungibles/tests.rs @@ -1,4 +1,4 @@ -use crate::{fungibles::Read::*, mock::*}; +use crate::{fungibles::Read::*, mock::*, Read}; use codec::Encode; use frame_support::{ assert_ok, @@ -236,7 +236,10 @@ fn burn_works() { fn total_supply_works() { new_test_ext().execute_with(|| { create_asset_and_mint_to(ALICE, ASSET, ALICE, 100); - assert_eq!(Assets::total_supply(ASSET).encode(), Fungibles::read_state(TotalSupply(ASSET))); + assert_eq!( + Assets::total_supply(ASSET).encode(), + Fungibles::read(TotalSupply(ASSET)).encode() + ); }); } @@ -246,7 +249,7 @@ fn balance_of_works() { create_asset_and_mint_to(ALICE, ASSET, ALICE, 100); assert_eq!( Assets::balance(ASSET, ALICE).encode(), - Fungibles::read_state(BalanceOf { asset: ASSET, owner: ALICE }) + Fungibles::read(BalanceOf { asset: ASSET, owner: ALICE }).encode() ); }); } @@ -257,7 +260,7 @@ fn allowance_works() { create_asset_mint_and_approve(ALICE, ASSET, BOB, 100, ALICE, 50); assert_eq!( Assets::allowance(ASSET, &ALICE, &BOB).encode(), - Fungibles::read_state(Allowance { asset: ASSET, owner: ALICE, spender: BOB }) + Fungibles::read(Allowance { asset: ASSET, owner: ALICE, spender: BOB }).encode() ); }); } @@ -269,9 +272,12 @@ fn token_metadata_works() { let symbol: Vec = vec![21, 22, 23]; let decimals: u8 = 69; create_asset_and_set_metadata(ALICE, ASSET, name.clone(), symbol.clone(), decimals); - assert_eq!(Assets::name(ASSET).encode(), Fungibles::read_state(TokenName(ASSET))); - assert_eq!(Assets::symbol(ASSET).encode(), Fungibles::read_state(TokenSymbol(ASSET))); - assert_eq!(Assets::decimals(ASSET).encode(), Fungibles::read_state(TokenDecimals(ASSET))); + assert_eq!(Assets::name(ASSET).encode(), Fungibles::read(TokenName(ASSET)).encode()); + assert_eq!(Assets::symbol(ASSET).encode(), Fungibles::read(TokenSymbol(ASSET)).encode()); + assert_eq!( + Assets::decimals(ASSET).encode(), + Fungibles::read(TokenDecimals(ASSET)).encode() + ); }); } @@ -279,7 +285,10 @@ fn token_metadata_works() { fn asset_exists_works() { new_test_ext().execute_with(|| { create_asset(ALICE, ASSET); - assert_eq!(Assets::asset_exists(ASSET).encode(), Fungibles::read_state(AssetExists(ASSET))); + assert_eq!( + Assets::asset_exists(ASSET).encode(), + Fungibles::read(AssetExists(ASSET)).encode() + ); }); } diff --git a/pallets/api/src/lib.rs b/pallets/api/src/lib.rs index 5cba0551..d94d1978 100644 --- a/pallets/api/src/lib.rs +++ b/pallets/api/src/lib.rs @@ -1,5 +1,30 @@ #![cfg_attr(not(feature = "std"), no_std)] +pub use extension::Extension; +use frame_support::pallet_prelude::Weight; + +pub mod extension; pub mod fungibles; #[cfg(test)] mod mock; + +/// Trait for performing reads of runtime state. +pub trait Read { + /// The type of read requested. + type Read; + /// The type or result returned. + type Result; + + /// Determines the weight of the requested read, used to charge the appropriate weight before + /// the read is performed. + /// + /// # Parameters + /// - `request` - The read request. + fn weight(read: &Self::Read) -> Weight; + + /// Performs the requested read and returns the result. + /// + /// # Parameters + /// - `request` - The read request. + fn read(request: Self::Read) -> Self::Result; +} diff --git a/pop-api/integration-tests/Cargo.toml b/pop-api/integration-tests/Cargo.toml index 7ab2d0fb..499ad991 100644 --- a/pop-api/integration-tests/Cargo.toml +++ b/pop-api/integration-tests/Cargo.toml @@ -14,6 +14,7 @@ scale = { package = "parity-scale-codec", version = "3.0.0", default-features = ] } frame-support = { version = "29.0.0", default-features = false } frame-system = { version = "29.0.0", default-features = false } +log = "0.4.22" pallet-balances = { version = "29.0.2", default-features = false } pallet-assets = { version = "30.0.0", default-features = false } pallet-contracts = { version = "28.0.0", default-features = false } diff --git a/pop-api/integration-tests/src/fungibles/mod.rs b/pop-api/integration-tests/src/fungibles/mod.rs index 0ca7d4f9..d1c0e2ae 100644 --- a/pop-api/integration-tests/src/fungibles/mod.rs +++ b/pop-api/integration-tests/src/fungibles/mod.rs @@ -1,9 +1,5 @@ use super::*; -use pop_primitives::error::{ - ArithmeticError::*, - Error::{self, *}, - TokenError::*, -}; +use pop_primitives::{ArithmeticError::*, AssetId, Error::*, TokenError::*, *}; use utils::*; mod utils; @@ -86,23 +82,29 @@ fn transfer_works() { let amount: Balance = 100 * UNIT; // Asset does not exist. - assert_eq!(transfer(addr.clone(), 1, BOB, amount), Err(Module { index: 52, error: 3 })); + assert_eq!( + transfer(addr.clone(), 1, BOB, amount), + Err(Module { index: 52, error: [3, 0] }) + ); // Create asset with Alice as owner and mint `amount` to contract address. let asset = create_asset_and_mint_to(ALICE, 1, addr.clone(), amount); // Asset is not live, i.e. frozen or being destroyed. freeze_asset(ALICE, asset); assert_eq!( transfer(addr.clone(), asset, BOB, amount), - Err(Module { index: 52, error: 16 }) + Err(Module { index: 52, error: [16, 0] }) ); thaw_asset(ALICE, asset); // Not enough balance. assert_eq!( transfer(addr.clone(), asset, BOB, amount + 1 * UNIT), - Err(Module { index: 52, error: 0 }) + Err(Module { index: 52, error: [0, 0] }) ); // Not enough balance due to ED. - assert_eq!(transfer(addr.clone(), asset, BOB, amount), Err(Module { index: 52, error: 0 })); + assert_eq!( + transfer(addr.clone(), asset, BOB, amount), + Err(Module { index: 52, error: [0, 0] }) + ); // Successful transfer. let balance_before_transfer = Assets::balance(asset, &BOB); assert_ok!(transfer(addr.clone(), asset, BOB, amount / 2)); @@ -114,7 +116,7 @@ fn transfer_works() { start_destroy_asset(ALICE, asset); assert_eq!( transfer(addr.clone(), asset, BOB, amount / 4), - Err(Module { index: 52, error: 16 }) + Err(Module { index: 52, error: [16, 0] }) ); }); } @@ -129,14 +131,14 @@ fn transfer_from_works() { // Asset does not exist. assert_eq!( transfer_from(addr.clone(), 1, ALICE, BOB, amount / 2), - Err(Module { index: 52, error: 3 }), + Err(Module { index: 52, error: [3, 0] }), ); // Create asset with Alice as owner and mint `amount` to contract address. let asset = create_asset_and_mint_to(ALICE, 1, ALICE, amount); // Unapproved transfer. assert_eq!( transfer_from(addr.clone(), asset, ALICE, BOB, amount / 2), - Err(Module { index: 52, error: 10 }) + Err(Module { index: 52, error: [10, 0] }) ); assert_ok!(Assets::approve_transfer( RuntimeOrigin::signed(ALICE.into()), @@ -148,13 +150,13 @@ fn transfer_from_works() { freeze_asset(ALICE, asset); assert_eq!( transfer_from(addr.clone(), asset, ALICE, BOB, amount), - Err(Module { index: 52, error: 16 }), + Err(Module { index: 52, error: [16, 0] }), ); thaw_asset(ALICE, asset); // Not enough balance. assert_eq!( transfer_from(addr.clone(), asset, ALICE, BOB, amount + 1 * UNIT), - Err(Module { index: 52, error: 0 }), + Err(Module { index: 52, error: [0, 0] }), ); // Successful transfer. let balance_before_transfer = Assets::balance(asset, &BOB); @@ -172,7 +174,7 @@ fn approve_works() { let amount: Balance = 100 * UNIT; // Asset does not exist. - assert_eq!(approve(addr.clone(), 0, BOB, amount), Err(Module { index: 52, error: 3 })); + assert_eq!(approve(addr.clone(), 0, BOB, amount), Err(Module { index: 52, error: [3, 0] })); let asset = create_asset_and_mint_to(ALICE, 0, addr.clone(), amount); assert_eq!(approve(addr.clone(), asset, BOB, amount), Err(ConsumerRemaining)); let addr = instantiate(CONTRACT, INIT_VALUE, vec![1]); @@ -180,7 +182,10 @@ fn approve_works() { let asset = create_asset_and_mint_to(ALICE, 1, addr.clone(), amount); // Asset is not live, i.e. frozen or being destroyed. freeze_asset(ALICE, asset); - assert_eq!(approve(addr.clone(), asset, BOB, amount), Err(Module { index: 52, error: 16 })); + assert_eq!( + approve(addr.clone(), asset, BOB, amount), + Err(Module { index: 52, error: [16, 0] }) + ); thaw_asset(ALICE, asset); // Successful approvals: assert_eq!(0, Assets::allowance(asset, &addr, &BOB)); @@ -191,7 +196,10 @@ fn approve_works() { assert_eq!(Assets::allowance(asset, &addr, &BOB), amount / 2); // Asset is not live, i.e. frozen or being destroyed. start_destroy_asset(ALICE, asset); - assert_eq!(approve(addr.clone(), asset, BOB, amount), Err(Module { index: 52, error: 16 })); + assert_eq!( + approve(addr.clone(), asset, BOB, amount), + Err(Module { index: 52, error: [16, 0] }) + ); }); } @@ -205,7 +213,7 @@ fn increase_allowance_works() { // Asset does not exist. assert_eq!( increase_allowance(addr.clone(), 0, BOB, amount), - Err(Module { index: 52, error: 3 }) + Err(Module { index: 52, error: [3, 0] }) ); let asset = create_asset_and_mint_to(ALICE, 0, addr.clone(), amount); assert_eq!(increase_allowance(addr.clone(), asset, BOB, amount), Err(ConsumerRemaining)); @@ -218,7 +226,7 @@ fn increase_allowance_works() { freeze_asset(ALICE, asset); assert_eq!( increase_allowance(addr.clone(), asset, BOB, amount), - Err(Module { index: 52, error: 16 }) + Err(Module { index: 52, error: [16, 0] }) ); thaw_asset(ALICE, asset); // Successful approvals: @@ -232,7 +240,7 @@ fn increase_allowance_works() { start_destroy_asset(ALICE, asset); assert_eq!( increase_allowance(addr.clone(), asset, BOB, amount), - Err(Module { index: 52, error: 16 }) + Err(Module { index: 52, error: [16, 0] }) ); }); } @@ -247,7 +255,7 @@ fn decrease_allowance_works() { // Asset does not exist. assert_eq!( decrease_allowance(addr.clone(), 0, BOB, amount), - Err(Module { index: 52, error: 3 }), + Err(Module { index: 52, error: [3, 0] }), ); // Create asset and mint `amount` to contract address, then approve Bob to spend `amount`. let asset = @@ -256,7 +264,7 @@ fn decrease_allowance_works() { freeze_asset(addr.clone(), asset); assert_eq!( decrease_allowance(addr.clone(), asset, BOB, amount), - Err(Module { index: 52, error: 16 }), + Err(Module { index: 52, error: [16, 0] }), ); thaw_asset(addr.clone(), asset); // Successfully decrease allowance. @@ -268,7 +276,7 @@ fn decrease_allowance_works() { start_destroy_asset(addr.clone(), asset); assert_eq!( decrease_allowance(addr.clone(), asset, BOB, amount), - Err(Module { index: 52, error: 16 }), + Err(Module { index: 52, error: [16, 0] }), ); }); } @@ -327,7 +335,7 @@ fn create_works() { // No balance to pay for fees. assert_eq!( create(addr.clone(), ASSET_ID, addr.clone(), 1), - Err(Module { index: 10, error: 2 }), + Err(Module { index: 10, error: [2, 0] }), ); // Instantiate a contract without balance for deposit. @@ -335,18 +343,27 @@ fn create_works() { // No balance to pay the deposit. assert_eq!( create(addr.clone(), ASSET_ID, addr.clone(), 1), - Err(Module { index: 10, error: 2 }), + Err(Module { index: 10, error: [2, 0] }), ); // Instantiate a contract with enough balance. let addr = instantiate(CONTRACT, INIT_VALUE, vec![2]); - assert_eq!(create(addr.clone(), ASSET_ID, BOB, 0), Err(Module { index: 52, error: 7 }),); + assert_eq!( + create(addr.clone(), ASSET_ID, BOB, 0), + Err(Module { index: 52, error: [7, 0] }), + ); // The minimal balance for an asset must be non zero. - assert_eq!(create(addr.clone(), ASSET_ID, BOB, 0), Err(Module { index: 52, error: 7 }),); + assert_eq!( + create(addr.clone(), ASSET_ID, BOB, 0), + Err(Module { index: 52, error: [7, 0] }), + ); // Create asset successfully. assert_ok!(create(addr.clone(), ASSET_ID, BOB, 1)); // Asset ID is already taken. - assert_eq!(create(addr.clone(), ASSET_ID, BOB, 1), Err(Module { index: 52, error: 5 }),); + assert_eq!( + create(addr.clone(), ASSET_ID, BOB, 1), + Err(Module { index: 52, error: [5, 0] }), + ); }); } @@ -361,7 +378,7 @@ fn instantiate_and_create_fungible_works() { create_asset(ALICE, 0, 1); assert_eq!( instantiate_and_create_fungible(contract, 0, 1), - Err(Module { index: 52, error: 5 }) + Err(Module { index: 52, error: [5, 0] }) ); // Successfully create an asset when instantiating the contract. assert_ok!(instantiate_and_create_fungible(contract, ASSET_ID, 1)); @@ -376,11 +393,11 @@ fn start_destroy_works() { let addr = instantiate(CONTRACT, INIT_VALUE, vec![2]); // Asset does not exist. - assert_eq!(start_destroy(addr.clone(), ASSET_ID), Err(Module { index: 52, error: 3 }),); + assert_eq!(start_destroy(addr.clone(), ASSET_ID), Err(Module { index: 52, error: [3, 0] }),); // Create assets where contract is not the owner. let asset = create_asset(ALICE, 0, 1); // No Permission. - assert_eq!(start_destroy(addr.clone(), asset), Err(Module { index: 52, error: 2 }),); + assert_eq!(start_destroy(addr.clone(), asset), Err(Module { index: 52, error: [2, 0] }),); let asset = create_asset(addr.clone(), ASSET_ID, 1); assert_ok!(start_destroy(addr.clone(), asset)); }); @@ -398,21 +415,21 @@ fn set_metadata_works() { // Asset does not exist. assert_eq!( set_metadata(addr.clone(), ASSET_ID, vec![0], vec![0], 0u8), - Err(Module { index: 52, error: 3 }), + Err(Module { index: 52, error: [3, 0] }), ); // Create assets where contract is not the owner. let asset = create_asset(ALICE, 0, 1); // No Permission. assert_eq!( set_metadata(addr.clone(), asset, vec![0], vec![0], 0u8), - Err(Module { index: 52, error: 2 }), + Err(Module { index: 52, error: [2, 0] }), ); let asset = create_asset(addr.clone(), ASSET_ID, 1); // Asset is not live, i.e. frozen or being destroyed. freeze_asset(addr.clone(), asset); assert_eq!( set_metadata(addr.clone(), ASSET_ID, vec![0], vec![0], 0u8), - Err(Module { index: 52, error: 16 }), + Err(Module { index: 52, error: [16, 0] }), ); thaw_asset(addr.clone(), asset); // TODO: calling the below with a vector of length `100_000` errors in pallet contracts @@ -420,7 +437,7 @@ fn set_metadata_works() { // Set bad metadata - too large values. assert_eq!( set_metadata(addr.clone(), ASSET_ID, vec![0; 1000], vec![0; 1000], 0u8), - Err(Module { index: 52, error: 9 }), + Err(Module { index: 52, error: [9, 0] }), ); // Set metadata successfully. assert_ok!(set_metadata(addr.clone(), ASSET_ID, name, symbol, decimals)); @@ -428,7 +445,7 @@ fn set_metadata_works() { start_destroy_asset(addr.clone(), asset); assert_eq!( set_metadata(addr.clone(), ASSET_ID, vec![0], vec![0], 0), - Err(Module { index: 52, error: 16 }), + Err(Module { index: 52, error: [16, 0] }), ); }); } @@ -443,18 +460,18 @@ fn clear_metadata_works() { let addr = instantiate(CONTRACT, INIT_VALUE, vec![]); // Asset does not exist. - assert_eq!(clear_metadata(addr.clone(), 0), Err(Module { index: 52, error: 3 }),); + assert_eq!(clear_metadata(addr.clone(), 0), Err(Module { index: 52, error: [3, 0] }),); // Create assets where contract is not the owner. let asset = create_asset_and_set_metadata(ALICE, 0, vec![0], vec![0], 0); // No Permission. - assert_eq!(clear_metadata(addr.clone(), asset), Err(Module { index: 52, error: 2 }),); + assert_eq!(clear_metadata(addr.clone(), asset), Err(Module { index: 52, error: [2, 0] }),); let asset = create_asset(addr.clone(), ASSET_ID, 1); // Asset is not live, i.e. frozen or being destroyed. freeze_asset(addr.clone(), asset); - assert_eq!(clear_metadata(addr.clone(), asset), Err(Module { index: 52, error: 16 }),); + assert_eq!(clear_metadata(addr.clone(), asset), Err(Module { index: 52, error: [16, 0] }),); thaw_asset(addr.clone(), asset); // No metadata set. - assert_eq!(clear_metadata(addr.clone(), asset), Err(Module { index: 52, error: 3 }),); + assert_eq!(clear_metadata(addr.clone(), asset), Err(Module { index: 52, error: [3, 0] }),); set_metadata_asset(addr.clone(), asset, name, symbol, decimals); // Clear metadata successfully. assert_ok!(clear_metadata(addr.clone(), ASSET_ID)); @@ -462,7 +479,7 @@ fn clear_metadata_works() { start_destroy_asset(addr.clone(), asset); assert_eq!( set_metadata(addr.clone(), ASSET_ID, vec![0], vec![0], decimals), - Err(Module { index: 52, error: 16 }), + Err(Module { index: 52, error: [16, 0] }), ); }); } @@ -493,13 +510,16 @@ fn mint_works() { assert_eq!(mint(addr.clone(), 1, BOB, amount), Err(Token(UnknownAsset))); let asset = create_asset(ALICE, 1, 1); // Minting can only be done by the owner. - assert_eq!(mint(addr.clone(), asset, BOB, 1), Err(Module { index: 52, error: 2 })); + assert_eq!(mint(addr.clone(), asset, BOB, 1), Err(Module { index: 52, error: [2, 0] })); let asset = create_asset(addr.clone(), 2, 2); // Minimum balance of an asset can not be zero. assert_eq!(mint(addr.clone(), asset, BOB, 1), Err(Token(BelowMinimum))); // Asset is not live, i.e. frozen or being destroyed. freeze_asset(addr.clone(), asset); - assert_eq!(mint(addr.clone(), asset, BOB, amount), Err(Module { index: 52, error: 16 })); + assert_eq!( + mint(addr.clone(), asset, BOB, amount), + Err(Module { index: 52, error: [16, 0] }) + ); thaw_asset(addr.clone(), asset); // Successful mint. let balance_before_mint = Assets::balance(asset, &BOB); @@ -510,7 +530,10 @@ fn mint_works() { assert_eq!(mint(addr.clone(), asset, BOB, Balance::MAX,), Err(Arithmetic(Overflow))); // Asset is not live, i.e. frozen or being destroyed. start_destroy_asset(addr.clone(), asset); - assert_eq!(mint(addr.clone(), asset, BOB, amount), Err(Module { index: 52, error: 16 })); + assert_eq!( + mint(addr.clone(), asset, BOB, amount), + Err(Module { index: 52, error: [16, 0] }) + ); }); } @@ -522,17 +545,20 @@ fn burn_works() { let amount: Balance = 100 * UNIT; // Asset does not exist. - assert_eq!(burn(addr.clone(), 1, BOB, amount), Err(Module { index: 52, error: 3 })); + assert_eq!(burn(addr.clone(), 1, BOB, amount), Err(Module { index: 52, error: [3, 0] })); let asset = create_asset(ALICE, 1, 1); // Bob has no tokens and thus pallet assets doesn't know the account. - assert_eq!(burn(addr.clone(), asset, BOB, 1), Err(Module { index: 52, error: 1 })); + assert_eq!(burn(addr.clone(), asset, BOB, 1), Err(Module { index: 52, error: [1, 0] })); // Burning can only be done by the manager. mint_asset(ALICE, asset, BOB, amount); - assert_eq!(burn(addr.clone(), asset, BOB, 1), Err(Module { index: 52, error: 2 })); + assert_eq!(burn(addr.clone(), asset, BOB, 1), Err(Module { index: 52, error: [2, 0] })); let asset = create_asset_and_mint_to(addr.clone(), 2, BOB, amount); // Asset is not live, i.e. frozen or being destroyed. freeze_asset(addr.clone(), asset); - assert_eq!(burn(addr.clone(), asset, BOB, amount), Err(Module { index: 52, error: 16 })); + assert_eq!( + burn(addr.clone(), asset, BOB, amount), + Err(Module { index: 52, error: [16, 0] }) + ); thaw_asset(addr.clone(), asset); // Successful mint. let balance_before_burn = Assets::balance(asset, &BOB); @@ -541,6 +567,9 @@ fn burn_works() { assert_eq!(balance_after_burn, balance_before_burn - amount); // Asset is not live, i.e. frozen or being destroyed. start_destroy_asset(addr.clone(), asset); - assert_eq!(burn(addr.clone(), asset, BOB, amount), Err(Module { index: 52, error: 16 })); + assert_eq!( + burn(addr.clone(), asset, BOB, amount), + Err(Module { index: 52, error: [16, 0] }) + ); }); } diff --git a/pop-api/integration-tests/src/lib.rs b/pop-api/integration-tests/src/lib.rs index b728fca6..1dab5b85 100644 --- a/pop-api/integration-tests/src/lib.rs +++ b/pop-api/integration-tests/src/lib.rs @@ -76,6 +76,7 @@ fn bare_call( CollectEvents::Skip, Determinism::Enforced, ); + log::info!("contract exec result={result:?}"); result.result } diff --git a/pop-api/src/v0/assets/fungibles.rs b/pop-api/src/v0/assets/fungibles.rs index 4f270e6b..56d2f9af 100644 --- a/pop-api/src/v0/assets/fungibles.rs +++ b/pop-api/src/v0/assets/fungibles.rs @@ -485,7 +485,7 @@ mod tests { use super::FungiblesError; use crate::{ constants::{ASSETS, BALANCES}, - primitives::error::{ + primitives::{ ArithmeticError::*, Error::{self, *}, TokenError::*, @@ -524,11 +524,11 @@ mod tests { #[test] fn conversion_status_code_into_fungibles_error_works() { let other_errors = vec![ - Other { dispatch_error_index: 5, error_index: 5, error: 1 }, + Other, CannotLookup, BadOrigin, // `ModuleError` other than assets module. - Module { index: 2, error: 5 }, + Module { index: 2, error: [5, 0] }, ConsumerRemaining, NoProviders, TooManyConsumers, @@ -539,7 +539,7 @@ mod tests { Corruption, Unavailable, RootNotAllowed, - UnknownCall, + Unknown { dispatch_error_index: 5, error_index: 5, error: 1 }, DecodingFailed, ]; for error in other_errors { @@ -549,32 +549,35 @@ mod tests { } assert_eq!( - into_fungibles_error(Module { index: BALANCES, error: 2 }), + into_fungibles_error(Module { index: BALANCES, error: [2, 0] }), FungiblesError::NoBalance ); assert_eq!( - into_fungibles_error(Module { index: ASSETS, error: 0 }), + into_fungibles_error(Module { index: ASSETS, error: [0, 0] }), FungiblesError::NoAccount ); assert_eq!( - into_fungibles_error(Module { index: ASSETS, error: 1 }), + into_fungibles_error(Module { index: ASSETS, error: [1, 0] }), FungiblesError::NoPermission ); assert_eq!( - into_fungibles_error(Module { index: ASSETS, error: 2 }), + into_fungibles_error(Module { index: ASSETS, error: [2, 0] }), FungiblesError::Unknown ); - assert_eq!(into_fungibles_error(Module { index: ASSETS, error: 3 }), FungiblesError::InUse); assert_eq!( - into_fungibles_error(Module { index: ASSETS, error: 5 }), + into_fungibles_error(Module { index: ASSETS, error: [3, 0] }), + FungiblesError::InUse + ); + assert_eq!( + into_fungibles_error(Module { index: ASSETS, error: [5, 0] }), FungiblesError::MinBalanceZero ); assert_eq!( - into_fungibles_error(Module { index: ASSETS, error: 7 }), + into_fungibles_error(Module { index: ASSETS, error: [7, 0] }), FungiblesError::InsufficientAllowance ); assert_eq!( - into_fungibles_error(Module { index: ASSETS, error: 10 }), + into_fungibles_error(Module { index: ASSETS, error: [10, 0] }), FungiblesError::AssetNotLive ); } diff --git a/pop-api/src/v0/mod.rs b/pop-api/src/v0/mod.rs index a4824327..55732e2d 100644 --- a/pop-api/src/v0/mod.rs +++ b/pop-api/src/v0/mod.rs @@ -1,7 +1,7 @@ use crate::{ build_extension_method, constants::{DISPATCH, READ_STATE}, - primitives::error::Error, + primitives::Error, StatusCode, }; use ink::env::chain_extension::ChainExtensionMethod; diff --git a/primitives/src/lib.rs b/primitives/src/lib.rs index a51661ea..e15b142c 100644 --- a/primitives/src/lib.rs +++ b/primitives/src/lib.rs @@ -3,14 +3,16 @@ use codec::{Decode, Encode}; #[cfg(feature = "std")] use scale_info::TypeInfo; -pub use v0::error; +pub use v0::*; /// Identifier for the class of asset. pub type AssetId = u32; pub mod v0 { use super::*; - pub mod error { + pub use error::*; + + mod error { use super::*; /// Reason why a Pop API call failed. @@ -19,25 +21,21 @@ pub mod v0 { #[repr(u8)] #[allow(clippy::unnecessary_cast)] pub enum Error { - /// An unknown error occurred. This variant captures any unexpected errors that the - /// contract cannot specifically handle. It is useful for cases where there are breaking - /// changes in the runtime or when an error falls outside the predefined categories. The - /// variant includes: - /// - /// - `dispatch_error_index`: The index within the `DispatchError`. - /// - `error_index`: The index within the `DispatchError` variant (e.g. a `TokenError`). - /// - `error`: The specific error code or sub-index, providing additional context (e.g. - /// `error` in `ModuleError`). - Other { dispatch_error_index: u8, error_index: u8, error: u8 } = 0, - /// Failed to lookup some data. + /// Some error occurred. + Other = 0, + /// Failed to look up some data. CannotLookup = 1, /// A bad origin. BadOrigin = 2, /// A custom error in a module. - /// - /// - `index`: The pallet index. - /// - `error`: The error within the pallet. - Module { index: u8, error: u8 } = 3, + Module { + /// The pallet index. + index: u8, + /// The error within the pallet. + // Supports a single level of nested error only, due to status code type size + // constraints. + error: [u8; 2], + } = 3, /// At least one consumer is remaining so the account cannot be destroyed. ConsumerRemaining = 4, /// There are no providers so the account cannot be created. @@ -48,21 +46,34 @@ pub mod v0 { Token(TokenError) = 7, /// An arithmetic error. Arithmetic(ArithmeticError) = 8, - /// The number of transactional layers has been reached, or we are not in a transactional - /// layer. + /// The number of transactional layers has been reached, or we are not in a + /// transactional layer. Transactional(TransactionalError) = 9, - /// Resources exhausted, e.g. attempt to read/write data which is too large to manipulate. + /// Resources exhausted, e.g. attempt to read/write data which is too large to + /// manipulate. Exhausted = 10, /// The state is corrupt; this is generally not going to fix itself. Corruption = 11, - /// Some resource (e.g. a preimage) is unavailable right now. This might fix itself later. + /// Some resource (e.g. a preimage) is unavailable right now. This might fix itself + /// later. Unavailable = 12, /// Root origin is not allowed. RootNotAllowed = 13, - /// Unknown call. - UnknownCall = 254, /// Decoding failed. - DecodingFailed = 255, + DecodingFailed = 254, + /// An unknown error occurred. This variant captures any unexpected errors that the + /// contract cannot specifically handle. It is useful for cases where there are + /// breaking changes in the runtime or when an error falls outside the predefined + /// categories. + Unknown { + /// The index within the `DispatchError`. + dispatch_error_index: u8, + /// The index within the `DispatchError` variant (e.g. a `TokenError`). + error_index: u8, + /// The specific error code or sub-index, providing additional context (e.g. + /// `error` in `ModuleError`). + error: u8, + } = 255, } impl From for Error { @@ -77,14 +88,26 @@ pub mod v0 { } } + impl From for u32 { + fn from(value: Error) -> Self { + let mut encoded_error = value.encode(); + // Resize the encoded value to 4 bytes in order to decode the value into a u32 (4 + // bytes). + encoded_error.resize(4, 0); + u32::from_le_bytes( + encoded_error.try_into().expect("qed, resized to 4 bytes line above"), + ) + } + } + /// Description of what went wrong when trying to complete an operation on a token. #[derive(Encode, Decode, Debug, Eq, PartialEq)] #[cfg_attr(feature = "std", derive(TypeInfo))] pub enum TokenError { /// Funds are unavailable. FundsUnavailable, - /// Some part of the balance gives the only provider reference to the account and thus cannot - /// be (re)moved. + /// Some part of the balance gives the only provider reference to the account and thus + /// cannot be (re)moved. OnlyProvider, /// Account cannot exist with the funds that would be given. BelowMinimum, diff --git a/runtime/devnet/src/config/api.rs b/runtime/devnet/src/config/api.rs deleted file mode 100644 index 4a404c99..00000000 --- a/runtime/devnet/src/config/api.rs +++ /dev/null @@ -1,68 +0,0 @@ -use crate::{ - config::assets::TrustBackedAssetsInstance, fungibles, Runtime, RuntimeCall, RuntimeEvent, -}; -use codec::{Decode, Encode, MaxEncodedLen}; -use pop_chain_extension::{CallFilter, ReadState}; -use sp_std::vec::Vec; - -/// A query of runtime state. -#[derive(Encode, Decode, Debug, MaxEncodedLen)] -#[repr(u8)] -pub enum RuntimeRead { - /// Fungible token queries. - #[codec(index = 150)] - Fungibles(fungibles::Read), -} - -/// A struct that implement requirements for the Pop API chain extension. -#[derive(Default)] -pub struct Extension; -impl ReadState for Extension { - type StateQuery = RuntimeRead; - - fn contains(c: &Self::StateQuery) -> bool { - use fungibles::Read::*; - matches!( - c, - RuntimeRead::Fungibles( - TotalSupply(..) - | BalanceOf { .. } | Allowance { .. } - | TokenName(..) | TokenSymbol(..) - | TokenDecimals(..) | AssetExists(..) - ) - ) - } - - fn read(read: RuntimeRead) -> Vec { - match read { - RuntimeRead::Fungibles(key) => fungibles::Pallet::read_state(key), - } - } -} - -impl CallFilter for Extension { - type Call = RuntimeCall; - - fn contains(c: &Self::Call) -> bool { - use fungibles::Call::*; - matches!( - c, - RuntimeCall::Fungibles( - transfer { .. } - | transfer_from { .. } - | approve { .. } | increase_allowance { .. } - | decrease_allowance { .. } - | create { .. } | set_metadata { .. } - | start_destroy { .. } - | clear_metadata { .. } - | mint { .. } | burn { .. } - ) - ) - } -} - -impl fungibles::Config for Runtime { - type RuntimeEvent = RuntimeEvent; - type AssetsInstance = TrustBackedAssetsInstance; - type WeightInfo = fungibles::weights::SubstrateWeight; -} diff --git a/runtime/devnet/src/config/api/mod.rs b/runtime/devnet/src/config/api/mod.rs new file mode 100644 index 00000000..ac956eb2 --- /dev/null +++ b/runtime/devnet/src/config/api/mod.rs @@ -0,0 +1,213 @@ +use crate::{ + config::assets::TrustBackedAssetsInstance, fungibles, Runtime, RuntimeCall, RuntimeEvent, +}; +use codec::Decode; +use core::marker::PhantomData; +use cumulus_primitives_core::Weight; +use frame_support::traits::Contains; +pub(crate) use pallet_api::Extension; +use pallet_api::{extension::*, Read}; +use sp_core::ConstU8; +use sp_runtime::DispatchError; +use sp_std::vec::Vec; +use versioning::*; + +mod versioning; + +type DecodingFailedError = DecodingFailed; +type DecodesAs = pallet_api::extension::DecodesAs< + Output, + ContractWeightsOf, + DecodingFailedError, + Logger, +>; + +/// A query of runtime state. +#[derive(Decode, Debug)] +#[repr(u8)] +pub enum RuntimeRead { + /// Fungible token queries. + #[codec(index = 150)] + Fungibles(fungibles::Read), +} + +impl Readable for RuntimeRead { + /// The corresponding type carrying the result of the query for runtime state. + type Result = RuntimeResult; + + /// Determines the weight of the read, used to charge the appropriate weight before the read is + /// performed. + fn weight(&self) -> Weight { + match self { + RuntimeRead::Fungibles(key) => fungibles::Pallet::weight(key), + } + } + + /// Performs the read and returns the result. + fn read(self) -> Self::Result { + match self { + RuntimeRead::Fungibles(key) => RuntimeResult::Fungibles(fungibles::Pallet::read(key)), + } + } +} + +/// The result of a runtime state read. +#[derive(Debug)] +pub enum RuntimeResult { + /// Fungible token read results. + Fungibles(fungibles::ReadResult), +} + +impl RuntimeResult { + /// Encodes the result. + fn encode(&self) -> Vec { + match self { + RuntimeResult::Fungibles(result) => result.encode(), + } + } +} + +impl fungibles::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type AssetsInstance = TrustBackedAssetsInstance; + type WeightInfo = fungibles::weights::SubstrateWeight; +} + +#[derive(Default)] +pub struct Config; +impl pallet_api::extension::Config for Config { + /// Functions used by the Pop API. + /// + /// Each function corresponds to specific functionality provided by the API, facilitating the + /// interaction between smart contracts and the runtime. + type Functions = ( + // Dispatching calls + DispatchCall< + // Function ID: 0. + IdentifiedByFirstByteOfFunctionId>, + // The runtime configuration. + Runtime, + // Decode as a versioned runtime call. + DecodesAs, + // Apply any filtering. + Filter, + // Ensure errors are versioned. + VersionedErrorConverter, + // Logging with a specific target. + DispatchCallLogTarget, + >, + // Reading state + ReadState< + // Function ID: 1. + IdentifiedByFirstByteOfFunctionId>, + // The runtime configuration. + Runtime, + // The runtime state reads available. + RuntimeRead, + // Decode as a versioned runtime read. + DecodesAs, + // Apply any filtering. + Filter, + // Convert the result of a read into the expected versioned result + VersionedResultConverter, + // Ensure errors are versioned. + VersionedErrorConverter, + // Logging with a specific target. + ReadStateLogTarget, + >, + ); + + /// The log target. + const LOG_TARGET: &'static str = LOG_TARGET; +} + +/// Filters used by the chain extension. +pub struct Filter(PhantomData); + +impl> Contains for Filter { + fn contains(c: &RuntimeCall) -> bool { + use fungibles::Call::*; + T::BaseCallFilter::contains(c) && + matches!( + c, + RuntimeCall::Fungibles( + transfer { .. } | + transfer_from { .. } | + approve { .. } | increase_allowance { .. } | + decrease_allowance { .. } | + create { .. } | set_metadata { .. } | + start_destroy { .. } | + clear_metadata { .. } | + mint { .. } | burn { .. } + ) + ) + } +} + +impl Contains for Filter { + fn contains(r: &RuntimeRead) -> bool { + use fungibles::Read::*; + matches!( + r, + RuntimeRead::Fungibles( + TotalSupply(..) | + BalanceOf { .. } | + Allowance { .. } | + TokenName(..) | TokenSymbol(..) | + TokenDecimals(..) | + AssetExists(..) + ) + ) + } +} + +#[test] +fn filter_prevents_runtime_filtered_calls() { + use pallet_balances::{AdjustmentDirection, Call::*}; + use sp_runtime::MultiAddress; + use RuntimeCall::Balances; + + const CALLS: [RuntimeCall; 4] = [ + Balances(force_adjust_total_issuance { + direction: AdjustmentDirection::Increase, + delta: 0, + }), + Balances(force_set_balance { who: MultiAddress::Address32([0u8; 32]), new_free: 0 }), + Balances(force_transfer { + source: MultiAddress::Address32([0u8; 32]), + dest: MultiAddress::Address32([0u8; 32]), + value: 0, + }), + Balances(force_unreserve { who: MultiAddress::Address32([0u8; 32]), amount: 0 }), + ]; + + for call in CALLS { + assert!(!Filter::::contains(&call)) + } +} + +#[test] +fn filter_allows_fungibles_calls() { + use pallet_api::fungibles::Call::*; + use sp_core::crypto::AccountId32; + use RuntimeCall::Fungibles; + + const ACCOUNT: AccountId32 = AccountId32::new([0u8; 32]); + const CALLS: [RuntimeCall; 11] = [ + Fungibles(transfer { asset: 0, to: ACCOUNT, value: 0 }), + Fungibles(transfer_from { asset: 0, from: ACCOUNT, to: ACCOUNT, value: 0 }), + Fungibles(approve { asset: 0, spender: ACCOUNT, value: 0 }), + Fungibles(increase_allowance { asset: 0, spender: ACCOUNT, value: 0 }), + Fungibles(decrease_allowance { asset: 0, spender: ACCOUNT, value: 0 }), + Fungibles(create { id: 0, admin: ACCOUNT, min_balance: 0 }), + Fungibles(set_metadata { asset: 0, name: vec![], symbol: vec![], decimals: 0 }), + Fungibles(start_destroy { asset: 0 }), + Fungibles(clear_metadata { asset: 0 }), + Fungibles(mint { asset: 0, account: ACCOUNT, value: 0 }), + Fungibles(burn { asset: 0, account: ACCOUNT, value: 0 }), + ]; + + for call in CALLS { + assert!(Filter::::contains(&call)) + } +} diff --git a/runtime/devnet/src/config/api/versioning.rs b/runtime/devnet/src/config/api/versioning.rs new file mode 100644 index 00000000..50041340 --- /dev/null +++ b/runtime/devnet/src/config/api/versioning.rs @@ -0,0 +1,218 @@ +use super::*; +use sp_runtime::ModuleError; + +type Version = u8; + +/// Versioned runtime calls. +#[derive(Decode, Debug)] +pub enum VersionedRuntimeCall { + /// Version zero of runtime calls. + #[codec(index = 0)] + V0(RuntimeCall), +} + +impl From for RuntimeCall { + fn from(value: VersionedRuntimeCall) -> Self { + // Allows mapping from some previous runtime call shape to a current valid runtime call + match value { + VersionedRuntimeCall::V0(call) => call, + } + } +} + +/// Versioned runtime state reads. +#[derive(Decode, Debug)] +pub enum VersionedRuntimeRead { + /// Version zero of runtime state reads. + #[codec(index = 0)] + V0(RuntimeRead), +} + +impl From for RuntimeRead { + fn from(value: VersionedRuntimeRead) -> Self { + // Allows mapping from some previous runtime read shape to a current valid runtime read + match value { + VersionedRuntimeRead::V0(read) => read, + } + } +} + +/// Versioned runtime state read results. +#[derive(Debug)] +pub enum VersionedRuntimeResult { + /// Version zero of runtime read results. + V0(RuntimeResult), +} + +impl From<(RuntimeResult, Version)> for VersionedRuntimeResult { + fn from(value: (RuntimeResult, Version)) -> Self { + let (result, version) = value; + match version { + // Allows mapping from current `RuntimeResult` to a specific/prior version + 0 => VersionedRuntimeResult::V0(result), + // TODO: should never occur due to version processing/validation when request received + _ => unimplemented!(), + } + } +} + +impl From for Vec { + fn from(result: VersionedRuntimeResult) -> Self { + match result { + // Simply unwrap and return the encoded result + VersionedRuntimeResult::V0(result) => result.encode(), + } + } +} + +/// Versioned errors. +#[derive(Debug)] +pub enum VersionedError { + /// Version zero of errors. + V0(pop_primitives::v0::Error), +} + +impl From<(DispatchError, Version)> for VersionedError { + fn from(value: (DispatchError, Version)) -> Self { + let (error, version) = value; + match version { + // Allows mapping from current `DispatchError` to a specific/prior version of `Error` + 0 => VersionedError::V0(V0Error::from(error).0), + // TODO: should never occur due to version processing/validation when request received + _ => unimplemented!(), + } + } +} + +impl From for u32 { + fn from(value: VersionedError) -> Self { + match value { + VersionedError::V0(error) => error.into(), + } + } +} + +struct V0Error(pop_primitives::v0::Error); +impl From for V0Error { + fn from(error: DispatchError) -> Self { + use pop_primitives::v0::*; + use sp_runtime::{ArithmeticError::*, TokenError::*, TransactionalError::*}; + use DispatchError::*; + // Mappings exist here to avoid taking a dependency of sp_runtime on pop-primitives + Self(match error { + Other(_message) => { + // Note: lossy conversion: message not used due to returned contract status code + // size limitation + Error::Other + }, + CannotLookup => Error::CannotLookup, + BadOrigin => Error::BadOrigin, + Module(error) => { + // Note: message not used + let ModuleError { index, error, message: _message } = error; + // Map `pallet-contracts::Error::DecodingFailed` to `Error::DecodingFailed` + if index as usize == + ::index() && + error == DECODING_FAILED_ERROR + { + Error::DecodingFailed + } else { + // Note: lossy conversion of error value due to returned contract status code + // size limitation + Error::Module { index, error: [error[0], error[1]] } + } + }, + ConsumerRemaining => Error::ConsumerRemaining, + NoProviders => Error::NoProviders, + TooManyConsumers => Error::TooManyConsumers, + Token(error) => Error::Token(match error { + FundsUnavailable => TokenError::FundsUnavailable, + OnlyProvider => TokenError::OnlyProvider, + BelowMinimum => TokenError::BelowMinimum, + CannotCreate => TokenError::CannotCreate, + UnknownAsset => TokenError::UnknownAsset, + Frozen => TokenError::Frozen, + Unsupported => TokenError::Unsupported, + CannotCreateHold => TokenError::CannotCreateHold, + NotExpendable => TokenError::NotExpendable, + Blocked => TokenError::Blocked, + }), + Arithmetic(error) => Error::Arithmetic(match error { + Underflow => ArithmeticError::Underflow, + Overflow => ArithmeticError::Overflow, + DivisionByZero => ArithmeticError::DivisionByZero, + }), + Transactional(error) => Error::Transactional(match error { + LimitReached => TransactionalError::LimitReached, + NoLayer => TransactionalError::NoLayer, + }), + Exhausted => Error::Exhausted, + Corruption => Error::Corruption, + Unavailable => Error::Unavailable, + RootNotAllowed => Error::RootNotAllowed, + }) + } +} + +#[cfg(test)] +mod tests { + use super::*; + use pop_primitives::{ArithmeticError::*, Error, TokenError::*, TransactionalError::*}; + use sp_runtime::ModuleError; + use DispatchError::*; + + // Compare all the different `DispatchError` variants with the expected `Error`. + #[test] + fn dispatch_error_to_error() { + let test_cases = vec![ + (Other(""), (Error::Other)), + (Other("UnknownCall"), Error::Other), + (Other("DecodingFailed"), Error::Other), + (Other("Random"), (Error::Other)), + (CannotLookup, Error::CannotLookup), + (BadOrigin, Error::BadOrigin), + ( + Module(ModuleError { index: 1, error: [2, 0, 0, 0], message: Some("hallo") }), + Error::Module { index: 1, error: [2, 0] }, + ), + ( + Module(ModuleError { index: 1, error: [2, 2, 0, 0], message: Some("hallo") }), + Error::Module { index: 1, error: [2, 2] }, + ), + ( + Module(ModuleError { index: 1, error: [2, 2, 2, 0], message: Some("hallo") }), + Error::Module { index: 1, error: [2, 2] }, + ), + ( + Module(ModuleError { index: 1, error: [2, 2, 2, 4], message: Some("hallo") }), + Error::Module { index: 1, error: [2, 2] }, + ), + (pallet_contracts::Error::::DecodingFailed.into(), Error::DecodingFailed), + (ConsumerRemaining, Error::ConsumerRemaining), + (NoProviders, Error::NoProviders), + (TooManyConsumers, Error::TooManyConsumers), + (Token(sp_runtime::TokenError::BelowMinimum), Error::Token(BelowMinimum)), + (Arithmetic(sp_runtime::ArithmeticError::Overflow), Error::Arithmetic(Overflow)), + ( + Transactional(sp_runtime::TransactionalError::LimitReached), + Error::Transactional(LimitReached), + ), + (Exhausted, Error::Exhausted), + (Corruption, Error::Corruption), + (Unavailable, Error::Unavailable), + (RootNotAllowed, Error::RootNotAllowed), + ]; + for (dispatch_error, expected) in test_cases { + let error = V0Error::from(dispatch_error).0; + assert_eq!(error, expected); + } + } + + #[test] + fn decoding_failed_error_encoding_works() { + let Module(error) = pallet_contracts::Error::::DecodingFailed.into() else { + unreachable!() + }; + assert_eq!(error.error, DECODING_FAILED_ERROR) + } +} diff --git a/runtime/devnet/src/config/contracts.rs b/runtime/devnet/src/config/contracts.rs index 5dc613b5..67a2f33c 100644 --- a/runtime/devnet/src/config/contracts.rs +++ b/runtime/devnet/src/config/contracts.rs @@ -1,4 +1,4 @@ -use super::api::Extension; +use super::api::{self, Config}; use crate::{ deposit, Balance, Balances, BalancesCall, Perbill, Runtime, RuntimeCall, RuntimeEvent, RuntimeHoldReason, Timestamp, @@ -64,7 +64,7 @@ impl pallet_contracts::Config for Runtime { type CallStack = [pallet_contracts::Frame; 23]; type WeightPrice = pallet_transaction_payment::Pallet; type WeightInfo = pallet_contracts::weights::SubstrateWeight; - type ChainExtension = pop_chain_extension::ApiExtension; + type ChainExtension = api::Extension; type Schedule = Schedule; type AddressGenerator = pallet_contracts::DefaultAddressGenerator; // This node is geared towards development and testing of contracts. diff --git a/runtime/devnet/src/config/proxy.rs b/runtime/devnet/src/config/proxy.rs index 07d5f0f8..c1142126 100644 --- a/runtime/devnet/src/config/proxy.rs +++ b/runtime/devnet/src/config/proxy.rs @@ -13,77 +13,77 @@ impl InstanceFilter for ProxyType { ProxyType::Any => true, ProxyType::NonTransfer => !matches!( c, - RuntimeCall::Balances { .. } - | RuntimeCall::Assets { .. } - | RuntimeCall::Nfts { .. } + RuntimeCall::Balances { .. } | + RuntimeCall::Assets { .. } | + RuntimeCall::Nfts { .. } ), ProxyType::CancelProxy => matches!( c, - RuntimeCall::Proxy(pallet_proxy::Call::reject_announcement { .. }) - | RuntimeCall::Utility { .. } - | RuntimeCall::Multisig { .. } + RuntimeCall::Proxy(pallet_proxy::Call::reject_announcement { .. }) | + RuntimeCall::Utility { .. } | + RuntimeCall::Multisig { .. } ), ProxyType::Assets => { matches!( c, - RuntimeCall::Assets { .. } - | RuntimeCall::Utility { .. } - | RuntimeCall::Multisig { .. } - | RuntimeCall::Nfts { .. } + RuntimeCall::Assets { .. } | + RuntimeCall::Utility { .. } | + RuntimeCall::Multisig { .. } | + RuntimeCall::Nfts { .. } ) }, ProxyType::AssetOwner => matches!( c, - RuntimeCall::Assets(AssetsCall::create { .. }) - | RuntimeCall::Assets(AssetsCall::start_destroy { .. }) - | RuntimeCall::Assets(AssetsCall::destroy_accounts { .. }) - | RuntimeCall::Assets(AssetsCall::destroy_approvals { .. }) - | RuntimeCall::Assets(AssetsCall::finish_destroy { .. }) - | RuntimeCall::Assets(AssetsCall::transfer_ownership { .. }) - | RuntimeCall::Assets(AssetsCall::set_team { .. }) - | RuntimeCall::Assets(AssetsCall::set_metadata { .. }) - | RuntimeCall::Assets(AssetsCall::clear_metadata { .. }) - | RuntimeCall::Assets(AssetsCall::set_min_balance { .. }) - | RuntimeCall::Nfts(pallet_nfts::Call::create { .. }) - | RuntimeCall::Nfts(pallet_nfts::Call::destroy { .. }) - | RuntimeCall::Nfts(pallet_nfts::Call::redeposit { .. }) - | RuntimeCall::Nfts(pallet_nfts::Call::transfer_ownership { .. }) - | RuntimeCall::Nfts(pallet_nfts::Call::set_team { .. }) - | RuntimeCall::Nfts(pallet_nfts::Call::set_collection_max_supply { .. }) - | RuntimeCall::Nfts(pallet_nfts::Call::lock_collection { .. }) - | RuntimeCall::Utility { .. } - | RuntimeCall::Multisig { .. } + RuntimeCall::Assets(AssetsCall::create { .. }) | + RuntimeCall::Assets(AssetsCall::start_destroy { .. }) | + RuntimeCall::Assets(AssetsCall::destroy_accounts { .. }) | + RuntimeCall::Assets(AssetsCall::destroy_approvals { .. }) | + RuntimeCall::Assets(AssetsCall::finish_destroy { .. }) | + RuntimeCall::Assets(AssetsCall::transfer_ownership { .. }) | + RuntimeCall::Assets(AssetsCall::set_team { .. }) | + RuntimeCall::Assets(AssetsCall::set_metadata { .. }) | + RuntimeCall::Assets(AssetsCall::clear_metadata { .. }) | + RuntimeCall::Assets(AssetsCall::set_min_balance { .. }) | + RuntimeCall::Nfts(pallet_nfts::Call::create { .. }) | + RuntimeCall::Nfts(pallet_nfts::Call::destroy { .. }) | + RuntimeCall::Nfts(pallet_nfts::Call::redeposit { .. }) | + RuntimeCall::Nfts(pallet_nfts::Call::transfer_ownership { .. }) | + RuntimeCall::Nfts(pallet_nfts::Call::set_team { .. }) | + RuntimeCall::Nfts(pallet_nfts::Call::set_collection_max_supply { .. }) | + RuntimeCall::Nfts(pallet_nfts::Call::lock_collection { .. }) | + RuntimeCall::Utility { .. } | + RuntimeCall::Multisig { .. } ), ProxyType::AssetManager => matches!( c, - RuntimeCall::Assets(AssetsCall::mint { .. }) - | RuntimeCall::Assets(AssetsCall::burn { .. }) - | RuntimeCall::Assets(AssetsCall::freeze { .. }) - | RuntimeCall::Assets(AssetsCall::block { .. }) - | RuntimeCall::Assets(AssetsCall::thaw { .. }) - | RuntimeCall::Assets(AssetsCall::freeze_asset { .. }) - | RuntimeCall::Assets(AssetsCall::thaw_asset { .. }) - | RuntimeCall::Assets(AssetsCall::touch_other { .. }) - | RuntimeCall::Assets(AssetsCall::refund_other { .. }) - | RuntimeCall::Nfts(pallet_nfts::Call::force_mint { .. }) - | RuntimeCall::Nfts(pallet_nfts::Call::update_mint_settings { .. }) - | RuntimeCall::Nfts(pallet_nfts::Call::mint_pre_signed { .. }) - | RuntimeCall::Nfts(pallet_nfts::Call::set_attributes_pre_signed { .. }) - | RuntimeCall::Nfts(pallet_nfts::Call::lock_item_transfer { .. }) - | RuntimeCall::Nfts(pallet_nfts::Call::unlock_item_transfer { .. }) - | RuntimeCall::Nfts(pallet_nfts::Call::lock_item_properties { .. }) - | RuntimeCall::Nfts(pallet_nfts::Call::set_metadata { .. }) - | RuntimeCall::Nfts(pallet_nfts::Call::clear_metadata { .. }) - | RuntimeCall::Nfts(pallet_nfts::Call::set_collection_metadata { .. }) - | RuntimeCall::Nfts(pallet_nfts::Call::clear_collection_metadata { .. }) - | RuntimeCall::Utility { .. } - | RuntimeCall::Multisig { .. } + RuntimeCall::Assets(AssetsCall::mint { .. }) | + RuntimeCall::Assets(AssetsCall::burn { .. }) | + RuntimeCall::Assets(AssetsCall::freeze { .. }) | + RuntimeCall::Assets(AssetsCall::block { .. }) | + RuntimeCall::Assets(AssetsCall::thaw { .. }) | + RuntimeCall::Assets(AssetsCall::freeze_asset { .. }) | + RuntimeCall::Assets(AssetsCall::thaw_asset { .. }) | + RuntimeCall::Assets(AssetsCall::touch_other { .. }) | + RuntimeCall::Assets(AssetsCall::refund_other { .. }) | + RuntimeCall::Nfts(pallet_nfts::Call::force_mint { .. }) | + RuntimeCall::Nfts(pallet_nfts::Call::update_mint_settings { .. }) | + RuntimeCall::Nfts(pallet_nfts::Call::mint_pre_signed { .. }) | + RuntimeCall::Nfts(pallet_nfts::Call::set_attributes_pre_signed { .. }) | + RuntimeCall::Nfts(pallet_nfts::Call::lock_item_transfer { .. }) | + RuntimeCall::Nfts(pallet_nfts::Call::unlock_item_transfer { .. }) | + RuntimeCall::Nfts(pallet_nfts::Call::lock_item_properties { .. }) | + RuntimeCall::Nfts(pallet_nfts::Call::set_metadata { .. }) | + RuntimeCall::Nfts(pallet_nfts::Call::clear_metadata { .. }) | + RuntimeCall::Nfts(pallet_nfts::Call::set_collection_metadata { .. }) | + RuntimeCall::Nfts(pallet_nfts::Call::clear_collection_metadata { .. }) | + RuntimeCall::Utility { .. } | + RuntimeCall::Multisig { .. } ), ProxyType::Collator => matches!( c, - RuntimeCall::CollatorSelection { .. } - | RuntimeCall::Utility { .. } - | RuntimeCall::Multisig { .. } + RuntimeCall::CollatorSelection { .. } | + RuntimeCall::Utility { .. } | + RuntimeCall::Multisig { .. } ), } } diff --git a/runtime/devnet/src/config/xcm.rs b/runtime/devnet/src/config/xcm.rs index b58baf2f..a5b7a04d 100644 --- a/runtime/devnet/src/config/xcm.rs +++ b/runtime/devnet/src/config/xcm.rs @@ -116,8 +116,8 @@ pub struct NativeAssetFrom(PhantomData); impl> ContainsPair for NativeAssetFrom { fn contains(asset: &Asset, origin: &Location) -> bool { let loc = T::get(); - &loc == origin - && matches!(asset, Asset { id: AssetId(asset_loc), fun: Fungible(_a) } + &loc == origin && + matches!(asset, Asset { id: AssetId(asset_loc), fun: Fungible(_a) } if *asset_loc == Location::from(Parent)) } } diff --git a/runtime/devnet/src/lib.rs b/runtime/devnet/src/lib.rs index e1ef6c6d..4f4b2e22 100644 --- a/runtime/devnet/src/lib.rs +++ b/runtime/devnet/src/lib.rs @@ -242,10 +242,10 @@ impl Contains for FilteredCalls { matches!( c, RuntimeCall::Balances( - force_adjust_total_issuance { .. } - | force_set_balance { .. } - | force_transfer { .. } - | force_unreserve { .. } + force_adjust_total_issuance { .. } | + force_set_balance { .. } | + force_transfer { .. } | + force_unreserve { .. } ) ) } diff --git a/runtime/testnet/src/config/proxy.rs b/runtime/testnet/src/config/proxy.rs index 07d5f0f8..c1142126 100644 --- a/runtime/testnet/src/config/proxy.rs +++ b/runtime/testnet/src/config/proxy.rs @@ -13,77 +13,77 @@ impl InstanceFilter for ProxyType { ProxyType::Any => true, ProxyType::NonTransfer => !matches!( c, - RuntimeCall::Balances { .. } - | RuntimeCall::Assets { .. } - | RuntimeCall::Nfts { .. } + RuntimeCall::Balances { .. } | + RuntimeCall::Assets { .. } | + RuntimeCall::Nfts { .. } ), ProxyType::CancelProxy => matches!( c, - RuntimeCall::Proxy(pallet_proxy::Call::reject_announcement { .. }) - | RuntimeCall::Utility { .. } - | RuntimeCall::Multisig { .. } + RuntimeCall::Proxy(pallet_proxy::Call::reject_announcement { .. }) | + RuntimeCall::Utility { .. } | + RuntimeCall::Multisig { .. } ), ProxyType::Assets => { matches!( c, - RuntimeCall::Assets { .. } - | RuntimeCall::Utility { .. } - | RuntimeCall::Multisig { .. } - | RuntimeCall::Nfts { .. } + RuntimeCall::Assets { .. } | + RuntimeCall::Utility { .. } | + RuntimeCall::Multisig { .. } | + RuntimeCall::Nfts { .. } ) }, ProxyType::AssetOwner => matches!( c, - RuntimeCall::Assets(AssetsCall::create { .. }) - | RuntimeCall::Assets(AssetsCall::start_destroy { .. }) - | RuntimeCall::Assets(AssetsCall::destroy_accounts { .. }) - | RuntimeCall::Assets(AssetsCall::destroy_approvals { .. }) - | RuntimeCall::Assets(AssetsCall::finish_destroy { .. }) - | RuntimeCall::Assets(AssetsCall::transfer_ownership { .. }) - | RuntimeCall::Assets(AssetsCall::set_team { .. }) - | RuntimeCall::Assets(AssetsCall::set_metadata { .. }) - | RuntimeCall::Assets(AssetsCall::clear_metadata { .. }) - | RuntimeCall::Assets(AssetsCall::set_min_balance { .. }) - | RuntimeCall::Nfts(pallet_nfts::Call::create { .. }) - | RuntimeCall::Nfts(pallet_nfts::Call::destroy { .. }) - | RuntimeCall::Nfts(pallet_nfts::Call::redeposit { .. }) - | RuntimeCall::Nfts(pallet_nfts::Call::transfer_ownership { .. }) - | RuntimeCall::Nfts(pallet_nfts::Call::set_team { .. }) - | RuntimeCall::Nfts(pallet_nfts::Call::set_collection_max_supply { .. }) - | RuntimeCall::Nfts(pallet_nfts::Call::lock_collection { .. }) - | RuntimeCall::Utility { .. } - | RuntimeCall::Multisig { .. } + RuntimeCall::Assets(AssetsCall::create { .. }) | + RuntimeCall::Assets(AssetsCall::start_destroy { .. }) | + RuntimeCall::Assets(AssetsCall::destroy_accounts { .. }) | + RuntimeCall::Assets(AssetsCall::destroy_approvals { .. }) | + RuntimeCall::Assets(AssetsCall::finish_destroy { .. }) | + RuntimeCall::Assets(AssetsCall::transfer_ownership { .. }) | + RuntimeCall::Assets(AssetsCall::set_team { .. }) | + RuntimeCall::Assets(AssetsCall::set_metadata { .. }) | + RuntimeCall::Assets(AssetsCall::clear_metadata { .. }) | + RuntimeCall::Assets(AssetsCall::set_min_balance { .. }) | + RuntimeCall::Nfts(pallet_nfts::Call::create { .. }) | + RuntimeCall::Nfts(pallet_nfts::Call::destroy { .. }) | + RuntimeCall::Nfts(pallet_nfts::Call::redeposit { .. }) | + RuntimeCall::Nfts(pallet_nfts::Call::transfer_ownership { .. }) | + RuntimeCall::Nfts(pallet_nfts::Call::set_team { .. }) | + RuntimeCall::Nfts(pallet_nfts::Call::set_collection_max_supply { .. }) | + RuntimeCall::Nfts(pallet_nfts::Call::lock_collection { .. }) | + RuntimeCall::Utility { .. } | + RuntimeCall::Multisig { .. } ), ProxyType::AssetManager => matches!( c, - RuntimeCall::Assets(AssetsCall::mint { .. }) - | RuntimeCall::Assets(AssetsCall::burn { .. }) - | RuntimeCall::Assets(AssetsCall::freeze { .. }) - | RuntimeCall::Assets(AssetsCall::block { .. }) - | RuntimeCall::Assets(AssetsCall::thaw { .. }) - | RuntimeCall::Assets(AssetsCall::freeze_asset { .. }) - | RuntimeCall::Assets(AssetsCall::thaw_asset { .. }) - | RuntimeCall::Assets(AssetsCall::touch_other { .. }) - | RuntimeCall::Assets(AssetsCall::refund_other { .. }) - | RuntimeCall::Nfts(pallet_nfts::Call::force_mint { .. }) - | RuntimeCall::Nfts(pallet_nfts::Call::update_mint_settings { .. }) - | RuntimeCall::Nfts(pallet_nfts::Call::mint_pre_signed { .. }) - | RuntimeCall::Nfts(pallet_nfts::Call::set_attributes_pre_signed { .. }) - | RuntimeCall::Nfts(pallet_nfts::Call::lock_item_transfer { .. }) - | RuntimeCall::Nfts(pallet_nfts::Call::unlock_item_transfer { .. }) - | RuntimeCall::Nfts(pallet_nfts::Call::lock_item_properties { .. }) - | RuntimeCall::Nfts(pallet_nfts::Call::set_metadata { .. }) - | RuntimeCall::Nfts(pallet_nfts::Call::clear_metadata { .. }) - | RuntimeCall::Nfts(pallet_nfts::Call::set_collection_metadata { .. }) - | RuntimeCall::Nfts(pallet_nfts::Call::clear_collection_metadata { .. }) - | RuntimeCall::Utility { .. } - | RuntimeCall::Multisig { .. } + RuntimeCall::Assets(AssetsCall::mint { .. }) | + RuntimeCall::Assets(AssetsCall::burn { .. }) | + RuntimeCall::Assets(AssetsCall::freeze { .. }) | + RuntimeCall::Assets(AssetsCall::block { .. }) | + RuntimeCall::Assets(AssetsCall::thaw { .. }) | + RuntimeCall::Assets(AssetsCall::freeze_asset { .. }) | + RuntimeCall::Assets(AssetsCall::thaw_asset { .. }) | + RuntimeCall::Assets(AssetsCall::touch_other { .. }) | + RuntimeCall::Assets(AssetsCall::refund_other { .. }) | + RuntimeCall::Nfts(pallet_nfts::Call::force_mint { .. }) | + RuntimeCall::Nfts(pallet_nfts::Call::update_mint_settings { .. }) | + RuntimeCall::Nfts(pallet_nfts::Call::mint_pre_signed { .. }) | + RuntimeCall::Nfts(pallet_nfts::Call::set_attributes_pre_signed { .. }) | + RuntimeCall::Nfts(pallet_nfts::Call::lock_item_transfer { .. }) | + RuntimeCall::Nfts(pallet_nfts::Call::unlock_item_transfer { .. }) | + RuntimeCall::Nfts(pallet_nfts::Call::lock_item_properties { .. }) | + RuntimeCall::Nfts(pallet_nfts::Call::set_metadata { .. }) | + RuntimeCall::Nfts(pallet_nfts::Call::clear_metadata { .. }) | + RuntimeCall::Nfts(pallet_nfts::Call::set_collection_metadata { .. }) | + RuntimeCall::Nfts(pallet_nfts::Call::clear_collection_metadata { .. }) | + RuntimeCall::Utility { .. } | + RuntimeCall::Multisig { .. } ), ProxyType::Collator => matches!( c, - RuntimeCall::CollatorSelection { .. } - | RuntimeCall::Utility { .. } - | RuntimeCall::Multisig { .. } + RuntimeCall::CollatorSelection { .. } | + RuntimeCall::Utility { .. } | + RuntimeCall::Multisig { .. } ), } } diff --git a/runtime/testnet/src/config/xcm.rs b/runtime/testnet/src/config/xcm.rs index b58baf2f..a5b7a04d 100644 --- a/runtime/testnet/src/config/xcm.rs +++ b/runtime/testnet/src/config/xcm.rs @@ -116,8 +116,8 @@ pub struct NativeAssetFrom(PhantomData); impl> ContainsPair for NativeAssetFrom { fn contains(asset: &Asset, origin: &Location) -> bool { let loc = T::get(); - &loc == origin - && matches!(asset, Asset { id: AssetId(asset_loc), fun: Fungible(_a) } + &loc == origin && + matches!(asset, Asset { id: AssetId(asset_loc), fun: Fungible(_a) } if *asset_loc == Location::from(Parent)) } } diff --git a/runtime/testnet/src/extensions.rs b/runtime/testnet/src/extensions.rs index a6e309f9..fc228b03 100644 --- a/runtime/testnet/src/extensions.rs +++ b/runtime/testnet/src/extensions.rs @@ -1,7 +1,7 @@ -use frame_support::traits::{Contains, OriginTrait}; use frame_support::{ dispatch::{GetDispatchInfo, RawOrigin}, pallet_prelude::*, + traits::{Contains, OriginTrait}, }; use pallet_contracts::chain_extension::{ BufInBufOutState, ChainExtension, ChargedAmount, Environment, Ext, InitState, RetVal, diff --git a/runtime/testnet/src/lib.rs b/runtime/testnet/src/lib.rs index 52104c43..700257fa 100644 --- a/runtime/testnet/src/lib.rs +++ b/runtime/testnet/src/lib.rs @@ -244,10 +244,10 @@ impl Contains for FilteredCalls { matches!( c, RuntimeCall::Balances( - force_adjust_total_issuance { .. } - | force_set_balance { .. } - | force_transfer { .. } - | force_unreserve { .. } + force_adjust_total_issuance { .. } | + force_set_balance { .. } | + force_transfer { .. } | + force_unreserve { .. } ) ) } From ec49dc3aea6f6b1a9c15e89eeed724ac59f92509 Mon Sep 17 00:00:00 2001 From: Tin Chung <56880684+chungquantin@users.noreply.github.com> Date: Sat, 7 Sep 2024 20:42:55 +0700 Subject: [PATCH 050/112] chore: resolve conflicts for `daan/api` (#267) Signed-off-by: dependabot[bot] Co-authored-by: Frank Bell Co-authored-by: Frank Bell <60948618+evilrobot-01@users.noreply.github.com> Co-authored-by: Peter White Co-authored-by: Daanvdplas Co-authored-by: Alejandro Martinez Andres <11448715+al3mart@users.noreply.github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Alex Bean Co-authored-by: Daan van der Plas <93204684+Daanvdplas@users.noreply.github.com> --- .githooks/README.md | 41 + .githooks/pre-push | 49 + .github/ISSUE_TEMPLATE/release_tracking.md | 97 + .github/workflows/ci.yml | 16 + .github/workflows/release.yml | 6 +- .rustfmt.toml | 32 +- .taplo.toml | 17 + Cargo.lock | 4269 +++++++++++------ Cargo.toml | 267 +- README.md | 2 +- extension/Cargo.toml | 52 +- extension/contract/Cargo.toml | 10 +- extension/src/decoding.rs | 12 +- extension/src/environment.rs | 5 +- extension/src/functions.rs | 29 +- extension/src/lib.rs | 6 +- extension/src/matching.rs | 3 +- extension/src/mock.rs | 65 +- extension/src/tests.rs | 9 +- integration-tests/Cargo.toml | 106 +- .../src/chains/asset_hub_paseo/mod.rs | 5 +- integration-tests/src/chains/paseo/genesis.rs | 14 +- integration-tests/src/chains/paseo/mod.rs | 5 +- .../src/chains/pop_network/mod.rs | 24 +- integration-tests/src/lib.rs | 29 +- networks/mainnet.toml | 40 + networks/testnet.toml | 10 +- node/Cargo.toml | 66 +- node/src/chain_spec.rs | 154 +- node/src/cli.rs | 5 - node/src/command.rs | 113 +- node/src/rpc.rs | 1 - node/src/service.rs | 185 +- pallets/api/Cargo.toml | 47 +- pallets/api/src/extension.rs | 7 +- pallets/api/src/fungibles/benchmarking.rs | 3 +- pallets/api/src/fungibles/mod.rs | 4 +- pallets/api/src/fungibles/tests.rs | 3 +- pallets/api/src/mock.rs | 66 +- pop-api/Cargo.toml | 23 +- pop-api/examples/balance-transfer/Cargo.toml | 22 +- pop-api/examples/fungibles/Cargo.toml | 16 +- pop-api/examples/fungibles/lib.rs | 2 +- pop-api/examples/nfts/Cargo.toml | 22 +- pop-api/examples/place-spot-order/Cargo.toml | 22 +- .../examples/read-runtime-state/Cargo.toml | 22 +- pop-api/integration-tests/Cargo.toml | 49 +- .../integration-tests/contracts/.gitignore | 9 - .../create_token_in_constructor/Cargo.toml | 16 +- .../contracts/fungibles/Cargo.toml | 16 +- .../integration-tests/src/fungibles/mod.rs | 2 +- pop-api/integration-tests/src/lib.rs | 2 +- primitives/Cargo.toml | 11 +- primitives/src/lib.rs | 3 +- runtime/common/Cargo.toml | 18 +- runtime/common/src/lib.rs | 11 +- runtime/devnet/Cargo.toml | 293 +- runtime/devnet/build.rs | 13 +- runtime/devnet/src/config/api/mod.rs | 12 +- runtime/devnet/src/config/api/versioning.rs | 6 +- runtime/devnet/src/config/assets.rs | 86 +- runtime/devnet/src/config/contracts.rs | 52 +- runtime/devnet/src/config/proxy.rs | 59 +- runtime/devnet/src/config/xcm.rs | 109 +- runtime/devnet/src/lib.rs | 394 +- .../devnet/src/weights/paritydb_weights.rs | 3 +- runtime/devnet/src/weights/rocksdb_weights.rs | 3 +- runtime/mainnet/Cargo.toml | 220 + runtime/mainnet/build.rs | 16 + runtime/mainnet/src/config/mod.rs | 2 + runtime/mainnet/src/config/proxy.rs | 57 + runtime/mainnet/src/config/xcm.rs | 213 + runtime/mainnet/src/lib.rs | 1015 ++++ runtime/mainnet/src/weights/block_weights.rs | 53 + .../mainnet/src/weights/extrinsic_weights.rs | 53 + runtime/mainnet/src/weights/mod.rs | 27 + .../mainnet/src/weights/paritydb_weights.rs | 64 + .../mainnet/src/weights/rocksdb_weights.rs | 64 + runtime/testnet/Cargo.toml | 284 +- runtime/testnet/build.rs | 13 +- runtime/testnet/src/config/assets.rs | 95 +- runtime/testnet/src/config/contracts.rs | 52 +- runtime/testnet/src/config/proxy.rs | 59 +- runtime/testnet/src/config/xcm.rs | 109 +- runtime/testnet/src/extensions.rs | 28 +- runtime/testnet/src/lib.rs | 392 +- .../testnet/src/weights/paritydb_weights.rs | 3 +- .../testnet/src/weights/rocksdb_weights.rs | 3 +- rust-toolchain.toml | 4 +- tests/contracts/filtered-call/Cargo.toml | 18 +- 90 files changed, 6766 insertions(+), 3248 deletions(-) create mode 100644 .githooks/README.md create mode 100755 .githooks/pre-push create mode 100644 .github/ISSUE_TEMPLATE/release_tracking.md create mode 100644 .taplo.toml create mode 100644 networks/mainnet.toml delete mode 100755 pop-api/integration-tests/contracts/.gitignore create mode 100644 runtime/mainnet/Cargo.toml create mode 100644 runtime/mainnet/build.rs create mode 100644 runtime/mainnet/src/config/mod.rs create mode 100644 runtime/mainnet/src/config/proxy.rs create mode 100644 runtime/mainnet/src/config/xcm.rs create mode 100644 runtime/mainnet/src/lib.rs create mode 100644 runtime/mainnet/src/weights/block_weights.rs create mode 100644 runtime/mainnet/src/weights/extrinsic_weights.rs create mode 100644 runtime/mainnet/src/weights/mod.rs create mode 100644 runtime/mainnet/src/weights/paritydb_weights.rs create mode 100644 runtime/mainnet/src/weights/rocksdb_weights.rs diff --git a/.githooks/README.md b/.githooks/README.md new file mode 100644 index 00000000..3ea52c72 --- /dev/null +++ b/.githooks/README.md @@ -0,0 +1,41 @@ +# Git Hooks + +A pre-push hook which checks formatting of Rust files. Additional checks may be added in the future. + +# Prerequisites + +The following prerequisites are required: + +## Rust Nightly + +The nightly version of Rust provides additional formatting benefits over the stable version. + +```shell +rustup toolchain install nightly --profile minimal --component rustfmt +``` + +## Taplo + +Formatting of TOML documents is done via `taplo`. +Find more about taplo [here](https://taplo.tamasfe.dev/). + +``` +cargo install taplo-cli --locked +``` + +## Zepter + +Analyze, fix and format features in your Rust workspace. +Find more about zepter [here](https://github.com/ggwpez/zepter). + +``` +cargo install zepter -f --locked +``` + +# Installation + +Use the following command in the root directory of the local repository to configure Git to use the hooks: + +```shell +git config core.hooksPath .githooks +``` diff --git a/.githooks/pre-push b/.githooks/pre-push new file mode 100755 index 00000000..f50f255a --- /dev/null +++ b/.githooks/pre-push @@ -0,0 +1,49 @@ +#!/bin/sh + +set -eu + +# Are deps installed +if ! command -v cargo > /dev/null 2>&1 +then + echo "cargo couldn't be found, please confirm your set up is properly configured." + exit 1 +else + # Check Rust formatting + if ! cargo +nightly fmt --all -- --check + then + echo "There are some code style issues." + # shellcheck disable=SC2006 + echo "Run 'cargo +nightly fmt --all' first." + exit 1 + fi +fi + +if ! command -v taplo > /dev/null 2>&1 +then + echo "taplo couldn't be found. Please, refer to .githooks/README.md." + exit 1 +else + # Check TOML formatting + if ! taplo format --check + then + echo "There are some code style issues." + echo "Run 'taplo fmt' first." + exit 1 + fi +fi + +if ! command -v zepter > /dev/null 2>&1 +then + echo "zepter couldn't be found. Please, refer to .githooks/README.md." + exit 1 +else + # Check for feature formatting + if ! zepter format features + then + echo "There are some code style issues." + echo "Run 'zepter format features --fix' first." + exit 1 + fi +fi + +exit 0 diff --git a/.github/ISSUE_TEMPLATE/release_tracking.md b/.github/ISSUE_TEMPLATE/release_tracking.md new file mode 100644 index 00000000..7ea4f8d2 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/release_tracking.md @@ -0,0 +1,97 @@ +--- +name: New Release +about: Create a tracking issue for a new release. +title: '-v' +assignees: '' +--- + +## Release Readiness Tracking + +> _Node Release_ + +- [ ] All changes have passed peer-review. < link PR > +- [ ] `pop-node` crate version has been updated. +- [ ] The new binary is able to sync the live network and peers with other active nodes, logs are healthy. +- [ ] One collator runs with the new binary, syncs the network and peers with other nodes, produces blocks and logs are healthy. + +> _Runtime Release_ + +- [ ] All changes have passed peer-review. < link PR > +- [ ] Update runtime crate version. Note that `pop-runtime-devnet` is usually not updated. +- [ ] Runtime spec version is updated. +- [ ] If needed, new benchmarks have been run. A diff between the new weights and the current ones has been reviewed. + - [`substrate-weight-compare`](https://github.com/ggwpez/substrate-weight-compare) can be used for this purpose. +- [ ] Execution of [`try-runtime`](https://github.com/paritytech/try-runtime-cli) doesn't point out any missing migrations or other items requiring action. + + + +## Testing Tracking + +- [ ] Local upgrade test runs as expected. + +1. Build the latest release. +2. Launch a network using `pop up parachiain -f networks/testnet.toml -v`. + - `pop-node` version can be verified via: `rpc calls -> system -> version()` + - Runtime version can be verified via: `rpc calls -> state -> getRuntimeVersion()` + + +> _Node release_ + +3. Switch to the new release branch and rebuild. +4. Kill the running `pop-node` process +> For instance, on Mac one can look in Activity Monitor, find the `pop-node` process and force quit. The network will still be running, but without the collator so Pop Network might not be producing blocks. +6. Run the new `pop-node` binary using the command prompted in step `2`, with the same specs that are prompted at step `2`. +7. Verify that the new node is producing blocks. +8. Verify running versions as needed. + +> _Runtime release_ + +_The new runtime might need a certian `pop-node` version to be deployed first, if that is the case make sure you follow the above steps for a Node Release_ + +3. Do a runtime upgrade using the new runtime release -- can be found in `./target/release/wbuild/pop-runtime-testnet/pop_runtime_testnet.compact.compressed.wasm`. +4. Verify the runtime upgrade was successful: + - The runtime version should have changed. + - The corresponding migrations should have run. + - Pop Network is still producing blocks. + + +- [ ] Successful execution of `try-runtime` . +``` +cargo build --release --features=try-runtime -p +try-runtime --runtime ./target/release/wbuild/pop-runtime-testnet/pop_runtime_testnet.compact.compressed.wasm on-runtime-upgrade live --uri wss://rpc3.paseo.popnetwork.xyz:443 +``` + +- [ ] (Advised) Runtime upgrade on a local **fork** of Pop Network. + +_More instructions around using chopsticks for this can be found in [.chopsticks directory](../../.chopsticks)_ + +1. Launch the local fork: +```shell + npx @acala-network/chopsticks@latest xcm -r ./.chopsticks/paseo.yml -p ./.chopsticks/testnet.yml +``` +2. Do a runtime upgrade using the new runtime release -- can be found in `./target/release/wbuild/pop-runtime-testnet/pop_runtime_testnet.compact.compressed.wasm`. +3. Might be needed to trigger block production on Pop Network: +```shell + websocat ws://localhost:8000 + {"jsonrpc":"2.0","id":2,"method":"dev_newBlock","params":[{"count":20}]} +``` + + +## Release + +> _Node release_ + +- [ ] New node release has been created: e.g. https://github.com/r0gue-io/pop-node/releases/tag/node-v0.2.0-alpha + - Create a tag like `node-v`. + - Point to the previous node release to create a proper diff. + - Provide a description and then release notes. + +> _Runtime release_ + +- [ ] New runtime release has been created: e.g. https://github.com/r0gue-io/pop-node/releases/tag/runtime-v0.4.0-alpha + - Create a tag like `runtime-v`. + - Point to the previous runtime release to create a proper diff. + - Provide a description and then release notes. + +- [ ] Create the authorization call data + - < Edit with authorized runtime call data > diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c8e2b2cc..953aa723 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -12,11 +12,26 @@ jobs: steps: - uses: actions/checkout@v4 + - uses: "./.github/actions/init" + - name: Check formatting run: | rustup toolchain install nightly --profile minimal --component rustfmt cargo +nightly fmt --all -- --check + - name: Check manifests + run: | + cargo install taplo-cli --locked + taplo format --check + + - name: Check features + run: | + cargo install zepter --locked + zepter lint propagate-feature --feature try-runtime --left-side-feature-missing=ignore --workspace --feature-enables-dep="try-runtime:frame-try-runtime" --locked + zepter lint propagate-feature --feature runtime-benchmarks --left-side-feature-missing=ignore --workspace --feature-enables-dep="runtime-benchmarks:frame-benchmarking" --locked + zepter lint propagate-feature --feature std --left-side-feature-missing=ignore --workspace --locked + zepter format features + check: needs: lint runs-on: ubuntu-latest @@ -35,6 +50,7 @@ jobs: permissions: checks: write env: + RUSTFLAGS: "-Wmissing_docs" SKIP_WASM_BUILD: 1 steps: - uses: actions/checkout@v4 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index c82d1b9f..bbbac837 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -28,7 +28,7 @@ jobs: contents: write strategy: matrix: - runtime: [ "devnet", "testnet" ] + runtime: [ "devnet", "testnet", "mainnet" ] steps: - name: Checkout sources uses: actions/checkout@v4 @@ -45,6 +45,8 @@ jobs: - name: Build ${{ matrix.runtime }} runtime id: srtool_build uses: chevdor/srtool-actions@v0.9.2 + env: + BUILD_OPTS: "--features on-chain-release-build" with: chain: ${{ matrix.runtime }} package: "pop-runtime-${{ matrix.runtime }}" @@ -166,7 +168,7 @@ jobs: run: rustup target add ${{ matrix.platform.target }} - name: Build node - run: cargo build --profile=production -p pop-node --target ${{ matrix.platform.target }} + run: cargo build --profile=production -p pop-node --features on-chain-release-build --target ${{ matrix.platform.target }} - name: Package binary (Linux) if: contains(matrix.platform.target, 'linux') diff --git a/.rustfmt.toml b/.rustfmt.toml index c3421539..8743bd4c 100644 --- a/.rustfmt.toml +++ b/.rustfmt.toml @@ -1,24 +1,24 @@ -# Basic +# Non-default formatting configuration options: use with `cargo +nightly fmt --all` +binop_separator = "Back" +chain_width = 80 +combine_control_expr = false +comment_width = 100 +condense_wildcard_suffixes = true edition = "2021" +format_code_in_doc_comments = true +format_strings = true +group_imports = "StdExternalCrate" hard_tabs = true -max_width = 100 -use_small_heuristics = "Max" -# Imports imports_granularity = "Crate" -reorder_imports = true -# Consistency -newline_style = "Unix" -# Misc -chain_width = 80 -spaces_around_ranges = false -binop_separator = "Back" -reorder_impl_items = false -match_arm_leading_pipes = "Preserve" match_arm_blocks = false match_block_trailing_comma = true -trailing_comma = "Vertical" +newline_style = "Unix" +normalize_comments = true +reorder_impl_items = true trailing_semicolon = false +unstable_features = true use_field_init_shorthand = true -# Format comments -comment_width = 100 +# Uses max_width or its default value (100) if not specified. +use_small_heuristics = "Max" +use_try_shorthand = true wrap_comments = true diff --git a/.taplo.toml b/.taplo.toml new file mode 100644 index 00000000..ea64cf51 --- /dev/null +++ b/.taplo.toml @@ -0,0 +1,17 @@ +# all options https://taplo.tamasfe.dev/configuration/formatter-options.html + +exclude = [ "networks/**", "target/**" ] + +# global rules +[formatting] +array_auto_collapse = false +array_auto_expand = true +compact_arrays = false # zepter compatibility +indent_string = " " # tab +inline_table_expand = false +reorder_arrays = true +reorder_keys = true + +[[rule]] +include = [ "Cargo.toml" ] +keys = [ "workspace.dependencies" ] diff --git a/Cargo.lock b/Cargo.lock index 26fb5d46..960e68f5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -36,12 +36,6 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" -[[package]] -name = "adler2" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" - [[package]] name = "aead" version = "0.5.2" @@ -74,7 +68,7 @@ dependencies = [ "cipher 0.4.4", "ctr", "ghash", - "subtle 2.4.1", + "subtle 2.5.0", ] [[package]] @@ -83,7 +77,7 @@ version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "891477e0c6a8957309ee5c45a6368af3ae14bb510732d2684ffa19af310920f9" dependencies = [ - "getrandom 0.2.15", + "getrandom", "once_cell", "version_check", ] @@ -95,7 +89,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" dependencies = [ "cfg-if", - "getrandom 0.2.15", + "getrandom", "once_cell", "version_check", "zerocopy", @@ -353,12 +347,6 @@ dependencies = [ "rand", ] -[[package]] -name = "array-bytes" -version = "4.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f52f63c5c1316a16a4b35eaac8b76a98248961a533f061684cb2a7cb0eafb6c6" - [[package]] name = "array-bytes" version = "6.2.3" @@ -392,8 +380,24 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f6fd5ddaf0351dff5b8da21b2fb4ff8e08ddd02857f0bf69c47639106c0fff0" dependencies = [ - "asn1-rs-derive", - "asn1-rs-impl", + "asn1-rs-derive 0.4.0", + "asn1-rs-impl 0.1.0", + "displaydoc", + "nom", + "num-traits", + "rusticata-macros", + "thiserror", + "time", +] + +[[package]] +name = "asn1-rs" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5493c3bedbacf7fd7382c6346bbd66687d12bbaad3a89a2d2c303ee6cf20b048" +dependencies = [ + "asn1-rs-derive 0.5.1", + "asn1-rs-impl 0.2.0", "displaydoc", "nom", "num-traits", @@ -414,6 +418,18 @@ dependencies = [ "synstructure 0.12.6", ] +[[package]] +name = "asn1-rs-derive" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "965c2d33e53cb6b267e148a4cb0760bc01f4904c1cd4bb4002a085bb016d1490" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.66", + "synstructure 0.13.1", +] + [[package]] name = "asn1-rs-impl" version = "0.1.0" @@ -425,6 +441,17 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "asn1-rs-impl" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b18050c2cd6fe86c3a76584ef5e0baf286d038cda203eb6223df2cc413565f7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.66", +] + [[package]] name = "assert_matches" version = "1.5.0" @@ -432,13 +459,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b34d609dfbaf33d6889b2b7106d3ca345eacad44200913df5ba02bfd31d2ba9" [[package]] -name = "asset-hub-paseo-runtime" +name = "asset-hub-polkadot-runtime" version = "1.0.0" -source = "git+https://github.com/paseo-network/runtimes/?tag=v1.2.5-system-chains#2fa66a19eef96bd2c079385057fab2564d09b751" +source = "git+https://github.com/polkadot-fellows/runtimes#f42acab60edf4d6ded4d9e99b1a8fbacded85669" dependencies = [ "assets-common", - "bp-asset-hub-paseo", - "bp-bridge-hub-paseo", + "bp-asset-hub-kusama", + "bp-asset-hub-polkadot", + "bp-bridge-hub-kusama", + "bp-bridge-hub-polkadot", + "collectives-polkadot-runtime-constants", "cumulus-pallet-aura-ext", "cumulus-pallet-parachain-system", "cumulus-pallet-session-benchmarking", @@ -456,6 +486,7 @@ dependencies = [ "frame-system-rpc-runtime-api", "frame-try-runtime", "hex-literal", + "kusama-runtime-constants", "log", "pallet-asset-conversion", "pallet-asset-conversion-tx-payment", @@ -481,12 +512,13 @@ dependencies = [ "pallet-xcm-bridge-hub-router", "parachains-common", "parity-scale-codec", - "paseo-runtime-constants", "polkadot-core-primitives", "polkadot-parachain-primitives", "polkadot-runtime-common", + "polkadot-runtime-constants", "primitive-types", "scale-info", + "serde_json", "snowbridge-router-primitives", "sp-api", "sp-block-builder", @@ -509,13 +541,14 @@ dependencies = [ "staging-xcm-executor", "substrate-wasm-builder", "system-parachains-constants", + "xcm-runtime-apis", ] [[package]] name = "asset-test-utils" -version = "8.0.1" +version = "15.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d78501ca6b4c848efe233672124ebab9293d8efefc44a728d70f3245a8ef595" +checksum = "8ccc232efa79f7f180856e9bc8535dbb2d813b62418cda7bf154a713adb9ea36" dependencies = [ "cumulus-pallet-parachain-system", "cumulus-pallet-xcmp-queue", @@ -526,6 +559,7 @@ dependencies = [ "pallet-balances", "pallet-collator-selection", "pallet-session", + "pallet-timestamp", "pallet-xcm", "pallet-xcm-bridge-hub-router", "parachains-common", @@ -543,9 +577,9 @@ dependencies = [ [[package]] name = "assets-common" -version = "0.8.0" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65e90021d772c2dd82d45fd085e05a2cb5866464d4c7421ac6a8007733b350bb" +checksum = "d4e2360c96927aa33b3fef7190eabf2aa4129fe3505c11dfa860ada0f27fd1b1" dependencies = [ "cumulus-primitives-core", "frame-support", @@ -585,7 +619,7 @@ dependencies = [ "concurrent-queue", "event-listener-strategy", "futures-core", - "pin-project-lite 0.2.14", + "pin-project-lite", ] [[package]] @@ -669,7 +703,7 @@ checksum = "ff6e472cdea888a4bd64f342f09b3f50e1886d32afe8df3d663c01140b811b18" dependencies = [ "event-listener 5.3.1", "event-listener-strategy", - "pin-project-lite 0.2.14", + "pin-project-lite", ] [[package]] @@ -745,7 +779,7 @@ dependencies = [ "futures-sink", "futures-util", "memchr", - "pin-project-lite 0.2.14", + "pin-project-lite", ] [[package]] @@ -760,6 +794,17 @@ version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" +[[package]] +name = "attohttpc" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d9a9bf8b79a749ee0b911b91b671cc2b6c670bdbc7e3dfd537576ddc94bb2a2" +dependencies = [ + "http 0.2.12", + "log", + "url", +] + [[package]] name = "autocfg" version = "1.3.0" @@ -776,7 +821,7 @@ dependencies = [ "cc", "cfg-if", "libc", - "miniz_oxide 0.7.3", + "miniz_oxide", "object 0.36.0", "rustc-demangle", ] @@ -828,9 +873,9 @@ dependencies = [ [[package]] name = "binary-merkle-tree" -version = "14.0.0" +version = "15.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bf857f8f411164ce1af14a778626af96251de7a77837711efbc440807e7053f" +checksum = "4b5c0fd4282c30c05647e1052d71bf1a0c8067ab1e9a8fc6d0c292dce0ecb237" dependencies = [ "hash-db", "log", @@ -872,19 +917,31 @@ version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "93f2635620bf0b9d4576eb7bb9a38a55df78bd1205d26fa994b25911a69f212f" dependencies = [ - "bitcoin_hashes", - "rand", - "rand_core 0.6.4", - "serde", - "unicode-normalization", + "bitcoin_hashes 0.11.0", ] +[[package]] +name = "bitcoin-internals" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9425c3bf7089c983facbae04de54513cce73b41c7f9ff8c845b54e7bc64ebbfb" + [[package]] name = "bitcoin_hashes" version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "90064b8dee6815a6470d60bad07bbbaee885c0e12d04177138fa3291a01b7bc4" +[[package]] +name = "bitcoin_hashes" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1930a4dabfebb8d7d9992db18ebe3ae2876f0a305fab206fd168df931ede293b" +dependencies = [ + "bitcoin-internals", + "hex-conservative", +] + [[package]] name = "bitflags" version = "1.3.2" @@ -1026,7 +1083,7 @@ dependencies = [ "hyper-util", "hyperlocal-next", "log", - "pin-project-lite 0.2.14", + "pin-project-lite", "serde", "serde_derive", "serde_json", @@ -1073,11 +1130,28 @@ dependencies = [ ] [[package]] -name = "bp-asset-hub-paseo" +name = "bp-asset-hub-kusama" +version = "1.0.0" +source = "git+https://github.com/polkadot-fellows/runtimes#f42acab60edf4d6ded4d9e99b1a8fbacded85669" +dependencies = [ + "bp-xcm-bridge-hub-router", + "frame-support", + "parity-scale-codec", + "scale-info", + "sp-std", + "staging-xcm", + "system-parachains-constants", +] + +[[package]] +name = "bp-asset-hub-polkadot" version = "1.0.0" -source = "git+https://github.com/paseo-network/runtimes/?tag=v1.2.5-system-chains#2fa66a19eef96bd2c079385057fab2564d09b751" +source = "git+https://github.com/polkadot-fellows/runtimes#f42acab60edf4d6ded4d9e99b1a8fbacded85669" dependencies = [ + "bp-xcm-bridge-hub-router", "frame-support", + "parity-scale-codec", + "scale-info", "sp-std", "staging-xcm", "system-parachains-constants", @@ -1085,9 +1159,9 @@ dependencies = [ [[package]] name = "bp-bridge-hub-cumulus" -version = "0.8.0" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e91ab68506081576066d3641d7794f63d96f3ca1eee0c059c2cc2174e55f638" +checksum = "d48cca10dce1c6d2914e48594f13add2da4a5b7c3ed54fd0fa324054dfb8569a" dependencies = [ "bp-messages", "bp-polkadot-core", @@ -1100,28 +1174,47 @@ dependencies = [ ] [[package]] -name = "bp-bridge-hub-paseo" +name = "bp-bridge-hub-kusama" version = "1.0.0" -source = "git+https://github.com/paseo-network/runtimes/?tag=v1.2.5-system-chains#2fa66a19eef96bd2c079385057fab2564d09b751" +source = "git+https://github.com/polkadot-fellows/runtimes#f42acab60edf4d6ded4d9e99b1a8fbacded85669" dependencies = [ "bp-bridge-hub-cumulus", "bp-messages", "bp-runtime", "frame-support", - "parity-scale-codec", - "scale-info", + "kusama-runtime-constants", + "polkadot-runtime-constants", + "sp-api", + "sp-runtime", + "sp-std", + "system-parachains-constants", +] + +[[package]] +name = "bp-bridge-hub-polkadot" +version = "1.0.0" +source = "git+https://github.com/polkadot-fellows/runtimes#f42acab60edf4d6ded4d9e99b1a8fbacded85669" +dependencies = [ + "bp-bridge-hub-cumulus", + "bp-messages", + "bp-polkadot-bulletin", + "bp-runtime", + "frame-support", + "kusama-runtime-constants", + "polkadot-runtime-constants", "snowbridge-core", "sp-api", "sp-runtime", "sp-std", "staging-xcm", + "system-parachains-constants", ] [[package]] name = "bp-header-chain" -version = "0.8.2" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c4d2c457d5e18a5dbfe47a2ecd01f95036930a4a7ac0f3e47c2843bb067331b" +checksum = "57cac4b71008e46d43e346476ed1be85cf7b505efacee17dad84d687344bf1b1" dependencies = [ "bp-runtime", "finality-grandpa", @@ -1137,9 +1230,9 @@ dependencies = [ [[package]] name = "bp-messages" -version = "0.8.0" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf43a49ea13d4c2f141481b6cbff85a197c47fe6aec1f5af21e40b68e8fd02fd" +checksum = "f97eec00a98efeb052ac9fc9676d9fccf5acd19e3b18530f3d72af1a1faf21ec" dependencies = [ "bp-header-chain", "bp-runtime", @@ -1153,9 +1246,9 @@ dependencies = [ [[package]] name = "bp-parachains" -version = "0.8.0" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "762e309a008b2ad4088d4c4e9d39fa9f78f59124b6a52c25ceb0ef5f22d901f5" +checksum = "60c0bde723a5daf39f4f02816483c9ac049818990b06858dff751736636a4ea2" dependencies = [ "bp-header-chain", "bp-polkadot-core", @@ -1169,11 +1262,30 @@ dependencies = [ "sp-std", ] +[[package]] +name = "bp-polkadot-bulletin" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfb5b3cd885b40b52bf96e52ffbec92d0c435f7303fc11374ccfcfa5bebfbc4f" +dependencies = [ + "bp-header-chain", + "bp-messages", + "bp-polkadot-core", + "bp-runtime", + "frame-support", + "frame-system", + "parity-scale-codec", + "scale-info", + "sp-api", + "sp-runtime", + "sp-std", +] + [[package]] name = "bp-polkadot-core" -version = "0.8.0" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b862e8dcccc9a3fafb58a1735bc205b7663d3335d7b3dd942503b98f28d6b067" +checksum = "6ef2272823ecfee580c00f6542dfcab3ec7abdb00857af853429736847c3a2d9" dependencies = [ "bp-messages", "bp-runtime", @@ -1190,9 +1302,9 @@ dependencies = [ [[package]] name = "bp-relayers" -version = "0.8.0" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74a4b0e2771227611fe9e6a2c37ba2bf7408cf2385a9eb2f44e6096bb0e616ec" +checksum = "5a589f5bb70baa4377a798823be752042aa6c220d51afc559716667e29b0203d" dependencies = [ "bp-messages", "bp-runtime", @@ -1205,9 +1317,9 @@ dependencies = [ [[package]] name = "bp-runtime" -version = "0.8.0" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b29668fffbc3e4a7ad789b498424ed6d8a313f93544a090bbaaef8a1f7fd243" +checksum = "904644c23b437dde65741f3148067624ed0b4d8360f68adf9e92273aeb970814" dependencies = [ "frame-support", "frame-system", @@ -1229,9 +1341,9 @@ dependencies = [ [[package]] name = "bp-test-utils" -version = "0.8.0" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6640a95733148b4f2004d362471eba49583da4b961681f5ea722039478924d31" +checksum = "85062410c8f85ba074f04d843c59f39c7fcb64b83f2ece5bd4379f8c34a4bf15" dependencies = [ "bp-header-chain", "bp-parachains", @@ -1250,18 +1362,18 @@ dependencies = [ [[package]] name = "bp-xcm-bridge-hub" -version = "0.2.0" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6663e0179d475e30cfcf28cf597cdc8f4bb1c2c39a557b4cbe0057db0657fb67" +checksum = "192804908f1d3b7bfad12abce448fb3b7ec8dda765cac4a8d811fa75557e528f" dependencies = [ "sp-std", ] [[package]] name = "bp-xcm-bridge-hub-router" -version = "0.7.0" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86ff4abe93be7bc1663adc41817b1aa3476fbec953ce361537419924310d5dd4" +checksum = "b7dae4d1ec894ee920195dd39070b279ef3c1d4d078c3fcf7336c93a1d502a9d" dependencies = [ "parity-scale-codec", "scale-info", @@ -1271,9 +1383,9 @@ dependencies = [ [[package]] name = "bridge-runtime-common" -version = "0.8.0" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be96f5eb3ef2ce92e0337e06b76a2e0e9f120a5f6fd96bf8db817e5643c118b9" +checksum = "639591635551f94b6e310852430b669495bd99cfd2af20b00a00f6cc7169e70d" dependencies = [ "bp-header-chain", "bp-messages", @@ -1303,6 +1415,7 @@ dependencies = [ "sp-trie", "staging-xcm", "staging-xcm-builder", + "tuplex", ] [[package]] @@ -1443,6 +1556,12 @@ dependencies = [ "once_cell", ] +[[package]] +name = "cesu8" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c" + [[package]] name = "cexpr" version = "0.6.0" @@ -1532,7 +1651,20 @@ dependencies = [ "multibase", "multihash 0.17.0", "serde", - "unsigned-varint", + "unsigned-varint 0.7.2", +] + +[[package]] +name = "cid" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd94671561e36e4e7de75f753f577edafb0e7c05d6e4547229fdf7938fbcd2c3" +dependencies = [ + "core2", + "multibase", + "multihash 0.18.1", + "serde", + "unsigned-varint 0.7.2", ] [[package]] @@ -1555,15 +1687,6 @@ dependencies = [ "zeroize", ] -[[package]] -name = "ckb-merkle-mountain-range" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56ccb671c5921be8a84686e6212ca184cb1d7c51cadcdbfcbd1cc3f042f5dfb8" -dependencies = [ - "cfg-if", -] - [[package]] name = "clang-sys" version = "1.8.1" @@ -1637,6 +1760,11 @@ dependencies = [ "unicode-width", ] +[[package]] +name = "collectives-polkadot-runtime-constants" +version = "1.0.0" +source = "git+https://github.com/polkadot-fellows/runtimes#f42acab60edf4d6ded4d9e99b1a8fbacded85669" + [[package]] name = "color-print" version = "0.3.6" @@ -1674,6 +1802,16 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "combine" +version = "4.6.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba5a308b75df32fe02788e748662718f03fde005016435c444eea572398219fd" +dependencies = [ + "bytes", + "memchr", +] + [[package]] name = "comfy-table" version = "7.1.1" @@ -1734,7 +1872,7 @@ version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f9d839f2a20b0aee515dc581a6172f2321f96cab76c1a38a4c584a194955390e" dependencies = [ - "getrandom 0.2.15", + "getrandom", "once_cell", "tiny-keccak", ] @@ -1894,7 +2032,7 @@ dependencies = [ "gimli 0.27.3", "hashbrown 0.13.2", "log", - "regalloc2", + "regalloc2 0.6.1", "smallvec", "target-lexicon", ] @@ -1968,6 +2106,21 @@ dependencies = [ "wasmtime-types", ] +[[package]] +name = "crc" +version = "3.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69e6e4d7b33a94f0991c26729976b10ebde1d34c3ee82408fb536164fa10d636" +dependencies = [ + "crc-catalog", +] + +[[package]] +name = "crc-catalog" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5" + [[package]] name = "crc32fast" version = "1.4.2" @@ -2049,8 +2202,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" dependencies = [ "generic-array 0.14.7", - "rand_core 0.6.4", - "subtle 2.4.1", + "rand_core", + "subtle 2.5.0", "zeroize", ] @@ -2061,7 +2214,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" dependencies = [ "generic-array 0.14.7", - "rand_core 0.6.4", + "rand_core", "typenum", ] @@ -2082,17 +2235,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b584a330336237c1eecd3e94266efb216c56ed91225d634cb2991c5f3fd1aeab" dependencies = [ "generic-array 0.14.7", - "subtle 2.4.1", -] - -[[package]] -name = "crypto-mac" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1d1a86f49236c215f271d40892d5fc950490551400b02ef360692c29815c714" -dependencies = [ - "generic-array 0.14.7", - "subtle 2.4.1", + "subtle 2.5.0", ] [[package]] @@ -2106,9 +2249,9 @@ dependencies = [ [[package]] name = "cumulus-client-cli" -version = "0.8.0" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70d2597fe3235d263457aaff65d0fb5bed506698b81530e2e6afecd6d6c9af32" +checksum = "b64901f2fde878bec8f4c3949b5e5ee6fb5de45dd19b45d9fcd6a23a859fd0cc" dependencies = [ "clap", "parity-scale-codec", @@ -2124,9 +2267,9 @@ dependencies = [ [[package]] name = "cumulus-client-collator" -version = "0.8.0" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c06ae72a125d056da3b722f00f87881a2afbb2af8fe9fa9a91587f139b9667e" +checksum = "2311f438161902135ff57db8a81ed3c701e33fd4bccbcc72e785f1efc73e1df3" dependencies = [ "cumulus-client-consensus-common", "cumulus-client-network", @@ -2148,9 +2291,9 @@ dependencies = [ [[package]] name = "cumulus-client-consensus-aura" -version = "0.8.0" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18f4977f6a88af39c46832d571ac0d95e8322bf22eab42550fec34f72da9f034" +checksum = "76c45052da56eb1631e177812f47c9426cb2617a5bfcc4c76a746e6a4c660df2" dependencies = [ "async-trait", "cumulus-client-collator", @@ -2162,6 +2305,7 @@ dependencies = [ "cumulus-relay-chain-interface", "futures", "parity-scale-codec", + "parking_lot 0.12.3", "polkadot-node-primitives", "polkadot-node-subsystem", "polkadot-overseer", @@ -2191,9 +2335,9 @@ dependencies = [ [[package]] name = "cumulus-client-consensus-common" -version = "0.8.0" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "350db1fc8841a44f344474b791d2ebe61b79bf6061043a7d826b3d02d1935a56" +checksum = "83b4de5c24c4304b509dffccb95218f22c2ef619a91aee85a3d9523b63347be2" dependencies = [ "async-trait", "cumulus-client-pov-recovery", @@ -2215,15 +2359,16 @@ dependencies = [ "sp-runtime", "sp-timestamp", "sp-trie", + "sp-version", "substrate-prometheus-endpoint", "tracing", ] [[package]] name = "cumulus-client-consensus-proposer" -version = "0.8.0" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38028f75597a34d447f059d6a7fd9c1c91bce0b8c48b08b1cbd19eb3def9c376" +checksum = "56e980b3e5c05415eaa4ac07f398bc8e74666811f3112f19a654ccb3a948018e" dependencies = [ "anyhow", "async-trait", @@ -2237,9 +2382,9 @@ dependencies = [ [[package]] name = "cumulus-client-network" -version = "0.8.0" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ac095ef439c595ccb998be5a9d40778d8963c5a8ebbaed838fed6293232915b" +checksum = "ed8d6844af4dbb35a925d493331b631f4ccd3b15568643e92afbf0ee7f4b22e3" dependencies = [ "async-trait", "cumulus-relay-chain-interface", @@ -2248,22 +2393,25 @@ dependencies = [ "parity-scale-codec", "parking_lot 0.12.3", "polkadot-node-primitives", + "polkadot-node-subsystem", "polkadot-parachain-primitives", "polkadot-primitives", "sc-client-api", + "sp-api", "sp-blockchain", "sp-consensus", "sp-core", "sp-runtime", "sp-state-machine", + "sp-version", "tracing", ] [[package]] name = "cumulus-client-parachain-inherent" -version = "0.2.0" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b516290cd4a6efc117824135761f3642dc57685e13da00727c460053ce978fe" +checksum = "e99367f72d7bce6d8996eb397d265290e4a982fbbc4b0fd7659e57a2ad5b6b7b" dependencies = [ "async-trait", "cumulus-primitives-core", @@ -2286,9 +2434,9 @@ dependencies = [ [[package]] name = "cumulus-client-pov-recovery" -version = "0.8.0" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4d55e96004ca9aa9d9b96a28ab2d97b1ca8d303c9d2405ea34cdf1462d4c4f0" +checksum = "21e3bd944ef351edb61fdaca5bf6d9a964d7c7571bd0b0236ea51f167bec9b6f" dependencies = [ "async-trait", "cumulus-primitives-core", @@ -2303,17 +2451,19 @@ dependencies = [ "rand", "sc-client-api", "sc-consensus", + "sp-api", "sp-consensus", "sp-maybe-compressed-blob", "sp-runtime", + "sp-version", "tracing", ] [[package]] name = "cumulus-client-service" -version = "0.8.0" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "657f57c56159bb6cb74d9221de8f11c9e09962666381357896562662d3019799" +checksum = "fb134f1526eba4455290859ad34174ab787c8f36f509063f41eeac17202a8f78" dependencies = [ "cumulus-client-cli", "cumulus-client-collator", @@ -2342,15 +2492,16 @@ dependencies = [ "sp-blockchain", "sp-consensus", "sp-core", + "sp-io", "sp-runtime", "sp-transaction-pool", ] [[package]] name = "cumulus-pallet-aura-ext" -version = "0.8.0" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e8e78b18548ae3454bc8a46e2bc2e3f521ea547844cbaecc9344d4741f4b1ef" +checksum = "c5e8af48090936c45483d489ee681acb54277763586b53fa3dbd17173aa474fc" dependencies = [ "cumulus-pallet-parachain-system", "frame-support", @@ -2367,9 +2518,9 @@ dependencies = [ [[package]] name = "cumulus-pallet-parachain-system" -version = "0.8.1" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a215fe4d66d23e8f3956bd21b9d80d2b33239f3b150b36d56fa238cfc9421a5" +checksum = "300d5509bd8ac95bafe158fa475278315175a4eb0422c2cd82e08e8b9dde035c" dependencies = [ "bytes", "cumulus-pallet-parachain-system-proc-macro", @@ -2398,6 +2549,7 @@ dependencies = [ "sp-trie", "sp-version", "staging-xcm", + "staging-xcm-builder", "trie-db", ] @@ -2415,9 +2567,9 @@ dependencies = [ [[package]] name = "cumulus-pallet-session-benchmarking" -version = "10.0.0" +version = "17.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f3259f743f70f39baa3abf2d9d8de864e18120465f8731b99bef039a3bf9329" +checksum = "506daacefa861aa2909b64f26e76495ce029227fd8355b97e074cc1d5dc54ab2" dependencies = [ "frame-benchmarking", "frame-support", @@ -2430,9 +2582,9 @@ dependencies = [ [[package]] name = "cumulus-pallet-xcm" -version = "0.8.0" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e802291060763f8d1176bf808da97aafe5afe7351f62bb093c317c1d35c5cee" +checksum = "8d5224285f60e5159bab549f458079d606a7f95ef779def8b89f1a244dc7cf81" dependencies = [ "cumulus-primitives-core", "frame-support", @@ -2447,9 +2599,9 @@ dependencies = [ [[package]] name = "cumulus-pallet-xcmp-queue" -version = "0.8.0" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fa22d6e479a4d3a2790bab291269ba0917a1ac384255a54a2ebc3f7c37e505e" +checksum = "0adf5409618b21e754fef0ac70f257878d22d61c48fdeefcab666835dcb8e0f0" dependencies = [ "bounded-collections", "bp-xcm-bridge-hub-router", @@ -2468,14 +2620,15 @@ dependencies = [ "sp-runtime", "sp-std", "staging-xcm", + "staging-xcm-builder", "staging-xcm-executor", ] [[package]] name = "cumulus-primitives-aura" -version = "0.8.0" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f07d6177692154043d7ddcc0b87ca5365ae8e4d94b90d9931f6b2f76e162f09" +checksum = "3e7977947ad43a4cbc532ca33abcde136ae3deffdc7168b2ae253d73ccd371e4" dependencies = [ "parity-scale-codec", "polkadot-core-primitives", @@ -2488,9 +2641,9 @@ dependencies = [ [[package]] name = "cumulus-primitives-core" -version = "0.8.0" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9df07f6825fd50ea30aae335e43dc1a615a05de7465f5f329b9e414f2c886a12" +checksum = "751e64b89a839d5cfabebc1c797936e5eee791d0fa2322d91e86f8440a743ddb" dependencies = [ "parity-scale-codec", "polkadot-core-primitives", @@ -2506,9 +2659,9 @@ dependencies = [ [[package]] name = "cumulus-primitives-parachain-inherent" -version = "0.8.0" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38ad140a065a6b8001fb26ec42b91391e90fde120f5b4e57986698249a9b98c8" +checksum = "df521e13b48278b86d02c61d6e44036d6d263deb5aaec4838b1751da8988d3d2" dependencies = [ "async-trait", "cumulus-primitives-core", @@ -2516,26 +2669,46 @@ dependencies = [ "scale-info", "sp-core", "sp-inherents", + "sp-runtime", + "sp-state-machine", "sp-std", "sp-trie", ] [[package]] name = "cumulus-primitives-proof-size-hostfunction" -version = "0.3.0" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1b74f9141190b9f4bf96a947ade46da64097b77f1ebfa8d611c81724250e119" +checksum = "9f973d2a7262c90e48dcd42062bcb1e0fbf48bbcdac4ea6df3d85212d8d8be5d" dependencies = [ "sp-externalities", "sp-runtime-interface", "sp-trie", ] +[[package]] +name = "cumulus-primitives-storage-weight-reclaim" +version = "6.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29a7e13063f593f21534a7b64c96f311c40cd4d3c72649e0bd063a34506fdd70" +dependencies = [ + "cumulus-primitives-core", + "cumulus-primitives-proof-size-hostfunction", + "docify", + "frame-support", + "frame-system", + "log", + "parity-scale-codec", + "scale-info", + "sp-runtime", + "sp-std", +] + [[package]] name = "cumulus-primitives-utility" -version = "0.8.1" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e65466e56d642f979b556d098a03755ae51972fff5fa0f9b1cdcfdb3df062ea3" +checksum = "05742c520065e3870d419683113ed7f6d35de66f0c80af6828e7878d1bb0ea94" dependencies = [ "cumulus-primitives-core", "frame-support", @@ -2554,9 +2727,9 @@ dependencies = [ [[package]] name = "cumulus-relay-chain-inprocess-interface" -version = "0.8.0" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cff27dec2eab6cd1d854756d62bd7053721ccd115f36f9e8b0976b1e46b70ef7" +checksum = "511675c9780fe8396e2b0c3ca8a04ff0ddc57d837fd9fe4086cb9aac1b107523" dependencies = [ "async-trait", "cumulus-primitives-core", @@ -2579,9 +2752,9 @@ dependencies = [ [[package]] name = "cumulus-relay-chain-interface" -version = "0.8.0" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40c736f39b50eecf194707e15d0359677bb8fe8138b01f6493ab9b7e10d2d1ae" +checksum = "36abc0a30972529fad05c4fae9f6866ec6c3edfaf2e20977219c94a807d96ffa" dependencies = [ "async-trait", "cumulus-primitives-core", @@ -2593,16 +2766,17 @@ dependencies = [ "sp-api", "sp-blockchain", "sp-state-machine", + "sp-version", "thiserror", ] [[package]] name = "cumulus-relay-chain-minimal-node" -version = "0.8.0" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c7718fe298d567adc44fae3dd7024418d6eff08264041e4b0544d1892861cd6" +checksum = "b39ec9de6ed195263af022094d63689fc6a914f48f70d74eb3fed8ee48973ea3" dependencies = [ - "array-bytes 6.2.3", + "array-bytes", "async-trait", "cumulus-primitives-core", "cumulus-relay-chain-interface", @@ -2621,6 +2795,7 @@ dependencies = [ "polkadot-node-subsystem-util", "polkadot-overseer", "polkadot-primitives", + "polkadot-service", "sc-authority-discovery", "sc-client-api", "sc-network", @@ -2640,9 +2815,9 @@ dependencies = [ [[package]] name = "cumulus-relay-chain-rpc-interface" -version = "0.8.0" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8e2269d4c1f37593257b3d7b90f8b56adab0793d9b9f5c1b5334c9ca7e3b10b" +checksum = "b22c43792fa5d56a2360bcdbdc58c47aafa23688072d2b6e61844864e69a15c8" dependencies = [ "async-trait", "cumulus-primitives-core", @@ -2680,9 +2855,9 @@ dependencies = [ [[package]] name = "cumulus-test-relay-sproof-builder" -version = "0.8.0" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfff604ad01c5c0c397f9a971c8cec6443aea3658813778875b4f64de07847d5" +checksum = "e1f4ab9d64a581d4a5431f2554f4602a4208c5e28b30be01af386e24d8447599" dependencies = [ "cumulus-primitives-core", "parity-scale-codec", @@ -2693,19 +2868,6 @@ dependencies = [ "sp-trie", ] -[[package]] -name = "curve25519-dalek" -version = "3.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b9fdf9972b2bd6af2d913799d9ebc165ea4d2e65878e329d9c6b372c4491b61" -dependencies = [ - "byteorder", - "digest 0.9.0", - "rand_core 0.5.1", - "subtle 2.4.1", - "zeroize", -] - [[package]] name = "curve25519-dalek" version = "4.1.3" @@ -2718,7 +2880,7 @@ dependencies = [ "digest 0.10.7", "fiat-crypto", "rustc_version", - "subtle 2.4.1", + "subtle 2.5.0", "zeroize", ] @@ -2741,7 +2903,7 @@ checksum = "1c359b7249347e46fb28804470d071c921156ad62b3eef5d34e2ba867533dec8" dependencies = [ "byteorder", "digest 0.9.0", - "rand_core 0.6.4", + "rand_core", "subtle-ng", "zeroize", ] @@ -2790,6 +2952,19 @@ dependencies = [ "syn 2.0.66", ] +[[package]] +name = "dashmap" +version = "5.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856" +dependencies = [ + "cfg-if", + "hashbrown 0.14.5", + "lock_api", + "once_cell", + "parking_lot_core 0.9.10", +] + [[package]] name = "data-encoding" version = "2.6.0" @@ -2832,7 +3007,21 @@ version = "8.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dbd676fbbab537128ef0278adb5576cf363cff6aa22a7b24effe97347cfab61e" dependencies = [ - "asn1-rs", + "asn1-rs 0.5.2", + "displaydoc", + "nom", + "num-bigint", + "num-traits", + "rusticata-macros", +] + +[[package]] +name = "der-parser" +version = "9.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5cd0a5c643689626bec213c4d8bd4d96acc8ffdb4ad4bb6bc16abf27d5f4b553" +dependencies = [ + "asn1-rs 0.6.2", "displaydoc", "nom", "num-bigint", @@ -2929,7 +3118,7 @@ dependencies = [ "block-buffer 0.10.4", "const-oid", "crypto-common", - "subtle 2.4.1", + "subtle 2.5.0", ] [[package]] @@ -3079,6 +3268,7 @@ dependencies = [ "digest 0.10.7", "elliptic-curve", "rfc6979", + "serdect", "signature", "spki", ] @@ -3099,26 +3289,12 @@ version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4a3daa8e81a3963a60642bcc1f90a670680bd4a77535faa384e9d1c79d620871" dependencies = [ - "curve25519-dalek 4.1.3", + "curve25519-dalek", "ed25519", - "rand_core 0.6.4", + "rand_core", "serde", "sha2 0.10.8", - "subtle 2.4.1", - "zeroize", -] - -[[package]] -name = "ed25519-zebra" -version = "3.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c24f403d068ad0b359e577a77f92392118be3f3c927538f2bb544a5ecd828c6" -dependencies = [ - "curve25519-dalek 3.2.0", - "hashbrown 0.12.3", - "hex", - "rand_core 0.6.4", - "sha2 0.9.9", + "subtle 2.5.0", "zeroize", ] @@ -3128,11 +3304,11 @@ version = "4.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7d9ce6874da5d4415896cd45ffbc4d1cfc0c4f9c079427bd870742c30f2f65a9" dependencies = [ - "curve25519-dalek 4.1.3", + "curve25519-dalek", "ed25519", "hashbrown 0.14.5", "hex", - "rand_core 0.6.4", + "rand_core", "sha2 0.10.8", "zeroize", ] @@ -3156,17 +3332,18 @@ dependencies = [ "generic-array 0.14.7", "group", "pkcs8", - "rand_core 0.6.4", + "rand_core", "sec1", - "subtle 2.4.1", + "serdect", + "subtle 2.5.0", "zeroize", ] [[package]] name = "emulated-integration-tests-common" -version = "4.0.0" +version = "11.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24a73ae1af5bb264240ccd199335ae78db85d055da4f749d44333d21719e5896" +checksum = "aef7c980b99bb2e4edfc9535d4096c1d0b5c8e3b52aab38a497a79563e6005f7" dependencies = [ "asset-test-utils", "bp-messages", @@ -3183,12 +3360,13 @@ dependencies = [ "parachains-common", "parity-scale-codec", "paste", + "polkadot-parachain-primitives", "polkadot-primitives", "polkadot-runtime-parachains", - "polkadot-service", "sc-consensus-grandpa", "sp-authority-discovery", "sp-consensus-babe", + "sp-consensus-beefy", "sp-core", "sp-runtime", "staging-xcm", @@ -3213,6 +3391,18 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "enum-as-inner" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ffccbb6966c05b32ef8fbac435df276c4ae4d3dc55a8cd0eb9745e6c12f546a" +dependencies = [ + "heck 0.4.1", + "proc-macro2", + "quote", + "syn 2.0.66", +] + [[package]] name = "enumflags2" version = "0.7.10" @@ -3357,7 +3547,7 @@ checksum = "d93877bcde0eb80ca09131a08d23f0a5c18a620b01db137dba666d18cd9b30c2" dependencies = [ "concurrent-queue", "parking", - "pin-project-lite 0.2.14", + "pin-project-lite", ] [[package]] @@ -3368,7 +3558,7 @@ checksum = "6032be9bd27023a771701cc49f9f053c751055f71efb2e0ae5c15809093675ba" dependencies = [ "concurrent-queue", "parking", - "pin-project-lite 0.2.14", + "pin-project-lite", ] [[package]] @@ -3378,7 +3568,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0f214dc438f977e6d4e3500aaa277f5ad94ca83fbbd9b1a15713ce2344ccc5a1" dependencies = [ "event-listener 5.3.1", - "pin-project-lite 0.2.14", + "pin-project-lite", ] [[package]] @@ -3390,18 +3580,6 @@ dependencies = [ "futures", ] -[[package]] -name = "expander" -version = "0.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a718c0675c555c5f976fff4ea9e2c150fa06cefa201cadef87cfbf9324075881" -dependencies = [ - "blake3", - "fs-err", - "proc-macro2", - "quote", -] - [[package]] name = "expander" version = "2.2.1" @@ -3423,6 +3601,12 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7" +[[package]] +name = "fallible-iterator" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2acce4a10f12dc2fb14a218589d4f1f62ef011b2d0cc4b3cb1bba8e94da14649" + [[package]] name = "fastrand" version = "1.9.0" @@ -3440,9 +3624,9 @@ checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a" [[package]] name = "fatality" -version = "0.0.6" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ad875162843b0d046276327afe0136e9ed3a23d5a754210fb6f1f33610d39ab" +checksum = "ec6f82451ff7f0568c6181287189126d492b5654e30a788add08027b6363d019" dependencies = [ "fatality-proc-macro", "thiserror", @@ -3450,17 +3634,16 @@ dependencies = [ [[package]] name = "fatality-proc-macro" -version = "0.0.6" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5aa1e3ae159e592ad222dc90c5acbad632b527779ba88486abe92782ab268bd" +checksum = "eb42427514b063d97ce21d5199f36c0c307d981434a6be32582bc79fe5bd2303" dependencies = [ - "expander 0.0.4", - "indexmap 1.9.3", - "proc-macro-crate 1.1.3", + "expander", + "indexmap 2.2.6", + "proc-macro-crate 3.1.0", "proc-macro2", "quote", - "syn 1.0.109", - "thiserror", + "syn 2.0.66", ] [[package]] @@ -3479,8 +3662,8 @@ version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" dependencies = [ - "rand_core 0.6.4", - "subtle 2.4.1", + "rand_core", + "subtle 2.5.0", ] [[package]] @@ -3555,17 +3738,6 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" -[[package]] -name = "flate2" -version = "1.0.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c0596c1eac1f9e04ed902702e9878208b336edc9d6fddc8a48387349bab3666" -dependencies = [ - "crc32fast", - "libz-sys", - "miniz_oxide 0.8.0", -] - [[package]] name = "float-cmp" version = "0.9.0" @@ -3581,11 +3753,26 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +dependencies = [ + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + [[package]] name = "fork-tree" -version = "12.0.0" +version = "13.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e93d3f0315c2eccf23453609e0ab92fe7c6ad1ca8129bcaf80b9a08c8d7fc52b" +checksum = "ad4cc2314d3be8b49c555f6a7e550f5559e73ffd6ef9690ffbd9a706774452e0" dependencies = [ "parity-scale-codec", ] @@ -3599,6 +3786,16 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "forwarded-header-value" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8835f84f38484cc86f110a805655697908257fb9a7af005234060891557198e9" +dependencies = [ + "nonempty", + "thiserror", +] + [[package]] name = "fragile" version = "2.0.0" @@ -3607,9 +3804,9 @@ checksum = "6c2141d6d6c8512188a7891b4b01590a45f6dac67afb4f255c4124dbb86d4eaa" [[package]] name = "frame-benchmarking" -version = "29.0.0" +version = "36.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4090659c6aaa3c4d5b6c6ec909b4b0a25dec10ad92aad5f729efa8d5bd4d806a" +checksum = "709b26657ebbba53dc7bb616577375ca462b20fef1b00e8d9b20d2435e87f7bc" dependencies = [ "frame-support", "frame-support-procedural", @@ -3633,12 +3830,12 @@ dependencies = [ [[package]] name = "frame-benchmarking-cli" -version = "33.0.0" +version = "40.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "efe02c96362e3c7308cdea7545859f767194a1f3f00928f0e1357f4b8a0b3b2c" +checksum = "49302558cac41cba0a28aa784615daea85c49253ecc6d6a6c4a8ee2f2303655a" dependencies = [ "Inflector", - "array-bytes 6.2.3", + "array-bytes", "chrono", "clap", "comfy-table", @@ -3647,7 +3844,7 @@ dependencies = [ "frame-system", "gethostname", "handlebars", - "itertools 0.10.5", + "itertools 0.11.0", "lazy_static", "linked-hash-map", "log", @@ -3655,6 +3852,7 @@ dependencies = [ "rand", "rand_pcg", "sc-block-builder", + "sc-chain-spec", "sc-cli", "sc-client-api", "sc-client-db", @@ -3668,6 +3866,7 @@ dependencies = [ "sp-core", "sp-database", "sp-externalities", + "sp-genesis-builder", "sp-inherents", "sp-io", "sp-keystore", @@ -3682,9 +3881,9 @@ dependencies = [ [[package]] name = "frame-election-provider-solution-type" -version = "13.0.0" +version = "14.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5c3bff645e46577c69c272733c53fa3a77d1ee6e40dfb66157bc94b0740b8fc" +checksum = "1388eb632484a1208a5b51d7d822a7df995f37bb10878b2a88f4ec89cbe5e6b2" dependencies = [ "proc-macro-crate 3.1.0", "proc-macro2", @@ -3694,9 +3893,9 @@ dependencies = [ [[package]] name = "frame-election-provider-support" -version = "29.0.0" +version = "36.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87da19ee99e6473cd057ead84337d20011fe5e299c6750e88e43b8b7963b8852" +checksum = "b1ec289ebad5e601bb165cf7eb6ec2179ae34280ee310d0710a3111d4f8f8f94" dependencies = [ "frame-election-provider-solution-type", "frame-support", @@ -3712,10 +3911,11 @@ dependencies = [ [[package]] name = "frame-executive" -version = "29.0.0" +version = "36.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09bff9574ee2dcc349f646e1d2faadf76afd688c2ea1bbac5e4a0e19a0c19c59" +checksum = "4d878830330eaa9e8b886279c338556b05702d0059989cb51cfb226b70bf3fa4" dependencies = [ + "aquamarine", "frame-support", "frame-system", "frame-try-runtime", @@ -3743,11 +3943,11 @@ dependencies = [ [[package]] name = "frame-metadata-hash-extension" -version = "0.1.0" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5bb1eec9eb46d3e016c95b2fa875118c04609f2150013c56a894cae00581e265" +checksum = "cf37fc730bf4b51e82a34c6357eebe32c04dbacf6525e0a7b9726f6a17ec9427" dependencies = [ - "array-bytes 6.2.3", + "array-bytes", "docify", "frame-support", "frame-system", @@ -3757,37 +3957,14 @@ dependencies = [ "sp-runtime", ] -[[package]] -name = "frame-remote-externalities" -version = "0.36.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "360bfdb6821372164a65933d9a6d5998f38c722360b59b69d2bf78a87ef58b2a" -dependencies = [ - "futures", - "indicatif", - "jsonrpsee", - "log", - "parity-scale-codec", - "serde", - "sp-core", - "sp-crypto-hashing", - "sp-io", - "sp-runtime", - "sp-state-machine", - "spinners", - "substrate-rpc-client", - "tokio", - "tokio-retry", -] - [[package]] name = "frame-support" -version = "29.0.2" +version = "36.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8e52c84b611d2049d9253f83a62ab0f093e4be5c42a7ef42ea5bb16d6611e32" +checksum = "512b517645f29d76c79e4c97bf8b0f4dcb6708a2af3be24b1956085dcdcf6ce5" dependencies = [ "aquamarine", - "array-bytes 6.2.3", + "array-bytes", "bitflags 1.3.2", "docify", "environmental", @@ -3824,18 +4001,18 @@ dependencies = [ [[package]] name = "frame-support-procedural" -version = "24.0.0" +version = "30.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3bf1d648c4007d421b9677b3c893256913498fff159dc2d85022cdd9cc432f3c" +checksum = "fd94af68373e179c32c360b3c280497a9cf0f45a4f47f0ee6539a6c6c9cf2343" dependencies = [ "Inflector", "cfg-expr", - "derive-syn-parse 0.1.5", - "expander 2.2.1", + "derive-syn-parse 0.2.0", + "expander", "frame-support-procedural-tools", - "itertools 0.10.5", + "itertools 0.11.0", "macro_magic", - "proc-macro-warning", + "proc-macro-warning 1.0.2", "proc-macro2", "quote", "sp-crypto-hashing", @@ -3844,9 +4021,9 @@ dependencies = [ [[package]] name = "frame-support-procedural-tools" -version = "10.0.0" +version = "13.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3363df38464c47a73eb521a4f648bfcc7537a82d70347ef8af3f73b6d019e910" +checksum = "bead15a320be1764cdd50458c4cfacb23e0cee65f64f500f8e34136a94c7eeca" dependencies = [ "frame-support-procedural-tools-derive", "proc-macro-crate 3.1.0", @@ -3857,9 +4034,9 @@ dependencies = [ [[package]] name = "frame-support-procedural-tools-derive" -version = "11.0.0" +version = "12.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68672b9ec6fe72d259d3879dc212c5e42e977588cdac830c76f54d9f492aeb58" +checksum = "ed971c6435503a099bdac99fe4c5bea08981709e5b5a0a8535a1856f48561191" dependencies = [ "proc-macro2", "quote", @@ -3868,9 +4045,9 @@ dependencies = [ [[package]] name = "frame-system" -version = "29.0.0" +version = "36.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5bc20a793c3cec0b11165c1075fe11a255b2491f3eef8230bb3073cb296e7383" +checksum = "64d6a0e7bb6503facdcc6f8e19c83cd0bfc8bbbd268522b1a50e107dfc6b972d" dependencies = [ "cfg-if", "docify", @@ -3889,9 +4066,9 @@ dependencies = [ [[package]] name = "frame-system-benchmarking" -version = "29.0.0" +version = "36.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac47ee48fee3a0b49c9ab9ee68997dee3733776a355f780cf2858449cf495d69" +checksum = "15afc91c7780e18274dcea58ed1edb700c48d10e086a9785e3f6708099cd3250" dependencies = [ "frame-benchmarking", "frame-support", @@ -3905,9 +4082,9 @@ dependencies = [ [[package]] name = "frame-system-rpc-runtime-api" -version = "27.0.0" +version = "33.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c1b20433c3c76b56ce905ed971631ec8c34fa64cf6c20e590afe46455fc0cc8" +checksum = "c9e9e2b7b85e451e367f4fb85ff3295bd039e17f64de1906154d3976e2638ee8" dependencies = [ "parity-scale-codec", "sp-api", @@ -3915,9 +4092,9 @@ dependencies = [ [[package]] name = "frame-try-runtime" -version = "0.35.0" +version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0eab87d07bc2f9a2160b818d1b7506c303b3b28b6a8a5f01dc5e2641390450b5" +checksum = "ae6ba8b36a52775ad39ccfb45ff4ad814c3cb45ec74d0a4271889e00bd791c6c" dependencies = [ "frame-support", "parity-scale-codec", @@ -3976,6 +4153,16 @@ dependencies = [ "futures-util", ] +[[package]] +name = "futures-bounded" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b07bbbe7d7e78809544c6f718d875627addc73a7c3582447abc052cd3dc67e0" +dependencies = [ + "futures-timer", + "futures-util", +] + [[package]] name = "futures-channel" version = "0.3.30" @@ -4021,7 +4208,7 @@ dependencies = [ "futures-io", "memchr", "parking", - "pin-project-lite 0.2.14", + "pin-project-lite", "waker-fn", ] @@ -4035,7 +4222,7 @@ dependencies = [ "futures-core", "futures-io", "parking", - "pin-project-lite 0.2.14", + "pin-project-lite", ] [[package]] @@ -4051,13 +4238,12 @@ dependencies = [ [[package]] name = "futures-rustls" -version = "0.22.2" +version = "0.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2411eed028cdf8c8034eaf21f9915f956b6c3abec4d4c7949ee67f0721127bd" +checksum = "35bd3cf68c183738046838e300353e4716c674dc5e56890de4826801a6622a28" dependencies = [ "futures-io", - "rustls 0.20.9", - "webpki", + "rustls 0.21.12", ] [[package]] @@ -4091,7 +4277,7 @@ dependencies = [ "futures-sink", "futures-task", "memchr", - "pin-project-lite 0.2.14", + "pin-project-lite", "pin-utils", "slab", ] @@ -4135,17 +4321,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "getrandom" -version = "0.1.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" -dependencies = [ - "cfg-if", - "libc", - "wasi 0.9.0+wasi-snapshot-preview1", -] - [[package]] name = "getrandom" version = "0.2.15" @@ -4154,7 +4329,7 @@ checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" dependencies = [ "cfg-if", "libc", - "wasi 0.11.0+wasi-snapshot-preview1", + "wasi", ] [[package]] @@ -4164,7 +4339,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6ea1015b5a70616b688dc230cfe50c8af89d972cb132d5a622814d29773b10b9" dependencies = [ "rand", - "rand_core 0.6.4", + "rand_core", ] [[package]] @@ -4183,11 +4358,21 @@ version = "0.27.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6c80984affa11d98d1b88b66ac8853f143217b399d3c74116778ff8fdb4ed2e" dependencies = [ - "fallible-iterator", + "fallible-iterator 0.2.0", "indexmap 1.9.3", "stable_deref_trait", ] +[[package]] +name = "gimli" +version = "0.28.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" +dependencies = [ + "fallible-iterator 0.3.0", + "stable_deref_trait", +] + [[package]] name = "gimli" version = "0.29.0" @@ -4200,6 +4385,26 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" +[[package]] +name = "governor" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68a7f542ee6b35af73b06abc0dad1c1bae89964e4e253bc4b587b91c9637867b" +dependencies = [ + "cfg-if", + "dashmap", + "futures", + "futures-timer", + "no-std-compat", + "nonzero_ext", + "parking_lot 0.12.3", + "portable-atomic", + "quanta", + "rand", + "smallvec", + "spinning_top", +] + [[package]] name = "group" version = "0.13.0" @@ -4207,8 +4412,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" dependencies = [ "ff", - "rand_core 0.6.4", - "subtle 2.4.1", + "rand_core", + "subtle 2.5.0", ] [[package]] @@ -4230,11 +4435,30 @@ dependencies = [ "tracing", ] +[[package]] +name = "h2" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa82e28a107a8cc405f0839610bdc9b15f1e25ec7d696aa5cf173edbcb1486ab" +dependencies = [ + "atomic-waker", + "bytes", + "fnv", + "futures-core", + "futures-sink", + "http 1.1.0", + "indexmap 2.2.6", + "slab", + "tokio", + "tokio-util", + "tracing", +] + [[package]] name = "handlebars" -version = "4.5.0" +version = "5.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "faa67bab9ff362228eb3d00bd024a4965d8231bbb7921167f0cfa66c6626b225" +checksum = "d08485b96a0e6393e9e4d1b8d48cf74ad6c063cd905eb33f42c1ce3f0377539b" dependencies = [ "log", "pest", @@ -4327,6 +4551,12 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" +[[package]] +name = "hex-conservative" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "212ab92002354b4819390025006c897e8140934349e8635c9b077f47b4dcbd20" + [[package]] name = "hex-literal" version = "0.4.1" @@ -4352,16 +4582,6 @@ dependencies = [ "digest 0.9.0", ] -[[package]] -name = "hmac" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a2a2320eb7ec0ebe8da8f744d7812d9fc4cb4d09344ac01898dbcb6a20ae69b" -dependencies = [ - "crypto-mac 0.11.1", - "digest 0.9.0", -] - [[package]] name = "hmac" version = "0.12.1" @@ -4432,7 +4652,7 @@ checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" dependencies = [ "bytes", "http 0.2.12", - "pin-project-lite 0.2.14", + "pin-project-lite", ] [[package]] @@ -4455,15 +4675,9 @@ dependencies = [ "futures-util", "http 1.1.0", "http-body 1.0.1", - "pin-project-lite 0.2.14", + "pin-project-lite", ] -[[package]] -name = "http-range-header" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "add0ab9360ddbd88cfeb3bd9574a1d85cfdfa14db10b3e21d3700dbc4328758f" - [[package]] name = "httparse" version = "1.9.4" @@ -4492,13 +4706,13 @@ dependencies = [ "futures-channel", "futures-core", "futures-util", - "h2", + "h2 0.3.26", "http 0.2.12", "http-body 0.4.6", "httparse", "httpdate", "itoa", - "pin-project-lite 0.2.14", + "pin-project-lite", "socket2 0.5.7", "tokio", "tower-service", @@ -4515,11 +4729,13 @@ dependencies = [ "bytes", "futures-channel", "futures-util", + "h2 0.4.5", "http 1.1.0", "http-body 1.0.1", "httparse", + "httpdate", "itoa", - "pin-project-lite 0.2.14", + "pin-project-lite", "smallvec", "tokio", "want", @@ -4534,7 +4750,7 @@ dependencies = [ "hex", "hyper 1.4.1", "hyper-util", - "pin-project-lite 0.2.14", + "pin-project-lite", "tokio", "tower-service", "winapi", @@ -4551,9 +4767,9 @@ dependencies = [ "hyper 0.14.29", "log", "rustls 0.21.12", - "rustls-native-certs", + "rustls-native-certs 0.6.3", "tokio", - "tokio-rustls", + "tokio-rustls 0.24.1", ] [[package]] @@ -4568,7 +4784,7 @@ dependencies = [ "http 1.1.0", "http-body 1.0.1", "hyper 1.4.1", - "pin-project-lite 0.2.14", + "pin-project-lite", "socket2 0.5.7", "tokio", "tower", @@ -4586,7 +4802,7 @@ dependencies = [ "http-body-util", "hyper 1.4.1", "hyper-util", - "pin-project-lite 0.2.14", + "pin-project-lite", "tokio", "tower-service", ] @@ -4743,6 +4959,16 @@ dependencies = [ "unicode-normalization", ] +[[package]] +name = "idna" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + [[package]] name = "idna" version = "1.0.0" @@ -4785,19 +5011,38 @@ dependencies = [ ] [[package]] -name = "impl-codec" -version = "0.6.0" +name = "igd-next" +version = "0.14.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba6a270039626615617f3f36d15fc827041df3b78c439da2cadfa47455a77f2f" +checksum = "064d90fec10d541084e7b39ead8875a5a80d9114a2b18791565253bae25f49e4" dependencies = [ - "parity-scale-codec", -] - -[[package]] -name = "impl-num-traits" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "951641f13f873bff03d4bf19ae8bec531935ac0ac2cc775f84d7edfdcfed3f17" + "async-trait", + "attohttpc", + "bytes", + "futures", + "http 0.2.12", + "hyper 0.14.29", + "log", + "rand", + "tokio", + "url", + "xmltree", +] + +[[package]] +name = "impl-codec" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba6a270039626615617f3f36d15fc827041df3b78c439da2cadfa47455a77f2f" +dependencies = [ + "parity-scale-codec", +] + +[[package]] +name = "impl-num-traits" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "951641f13f873bff03d4bf19ae8bec531935ac0ac2cc775f84d7edfdcfed3f17" dependencies = [ "integer-sqrt", "num-traits", @@ -4880,19 +5125,6 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e04e2fd2b8188ea827b32ef11de88377086d690286ab35747ef7f9bf3ccb590" -[[package]] -name = "indicatif" -version = "0.17.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "763a5a8f45087d6bcea4222e7b72c291a054edf80e4ef6efd2a4979878c7bea3" -dependencies = [ - "console", - "instant", - "number_prefix", - "portable-atomic", - "unicode-width", -] - [[package]] name = "inout" version = "0.1.3" @@ -4930,7 +5162,7 @@ dependencies = [ name = "integration-tests" version = "0.0.0" dependencies = [ - "asset-hub-paseo-runtime", + "asset-hub-polkadot-runtime", "asset-test-utils", "cumulus-primitives-core", "emulated-integration-tests-common", @@ -4940,12 +5172,13 @@ dependencies = [ "pallet-message-queue", "pallet-xcm", "parity-scale-codec", - "paseo-runtime", - "paseo-runtime-constants", "polkadot-primitives", + "polkadot-runtime", + "polkadot-runtime-constants", "polkadot-runtime-parachains", "pop-runtime-common", "pop-runtime-devnet", + "pop-runtime-mainnet", "sp-authority-discovery", "sp-consensus-aura", "sp-consensus-babe", @@ -5043,6 +5276,26 @@ version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" +[[package]] +name = "jni" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6df18c2e3db7e453d3c6ac5b3e9d5182664d28788126d39b91f2d1e22b017ec" +dependencies = [ + "cesu8", + "combine", + "jni-sys", + "log", + "thiserror", + "walkdir", +] + +[[package]] +name = "jni-sys" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" + [[package]] name = "jobserver" version = "0.1.31" @@ -5063,12 +5316,11 @@ dependencies = [ [[package]] name = "jsonrpsee" -version = "0.20.4" +version = "0.23.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "138572befc78a9793240645926f30161f8b4143d2be18d09e44ed9814bd7ee2c" +checksum = "62b089779ad7f80768693755a031cc14a7766aba707cbe886674e3f79e9b7e47" dependencies = [ "jsonrpsee-core", - "jsonrpsee-http-client", "jsonrpsee-proc-macros", "jsonrpsee-server", "jsonrpsee-types", @@ -5079,19 +5331,22 @@ dependencies = [ [[package]] name = "jsonrpsee-client-transport" -version = "0.20.4" +version = "0.23.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c671353e4adf926799107bd7f5724a06b6bc0a333db442a0843c58640bdd0c1" +checksum = "08163edd8bcc466c33d79e10f695cdc98c00d1e6ddfb95cec41b6b0279dd5432" dependencies = [ + "base64 0.22.1", "futures-util", - "http 0.2.12", + "http 1.1.0", "jsonrpsee-core", "pin-project", - "rustls-native-certs", - "soketto", + "rustls 0.23.10", + "rustls-pki-types", + "rustls-platform-verifier", + "soketto 0.8.0", "thiserror", "tokio", - "tokio-rustls", + "tokio-rustls 0.26.0", "tokio-util", "tracing", "url", @@ -5099,77 +5354,65 @@ dependencies = [ [[package]] name = "jsonrpsee-core" -version = "0.20.4" +version = "0.23.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f24ea59b037b6b9b0e2ebe2c30a3e782b56bd7c76dcc5d6d70ba55d442af56e3" +checksum = "79712302e737d23ca0daa178e752c9334846b08321d439fd89af9a384f8c830b" dependencies = [ "anyhow", - "async-lock 2.8.0", "async-trait", "beef", + "bytes", "futures-timer", "futures-util", - "hyper 0.14.29", + "http 1.1.0", + "http-body 1.0.1", + "http-body-util", "jsonrpsee-types", "parking_lot 0.12.3", + "pin-project", "rand", "rustc-hash", "serde", "serde_json", - "soketto", - "thiserror", - "tokio", - "tracing", -] - -[[package]] -name = "jsonrpsee-http-client" -version = "0.20.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57c7b9f95208927653e7965a98525e7fc641781cab89f0e27c43fa2974405683" -dependencies = [ - "async-trait", - "hyper 0.14.29", - "hyper-rustls", - "jsonrpsee-core", - "jsonrpsee-types", - "serde", - "serde_json", "thiserror", "tokio", - "tower", + "tokio-stream", "tracing", - "url", ] [[package]] name = "jsonrpsee-proc-macros" -version = "0.20.4" +version = "0.23.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcc0eba68ba205452bcb4c7b80a79ddcb3bf36c261a841b239433142db632d24" +checksum = "7895f186d5921065d96e16bd795e5ca89ac8356ec423fafc6e3d7cf8ec11aee4" dependencies = [ - "heck 0.4.1", - "proc-macro-crate 1.1.3", + "heck 0.5.0", + "proc-macro-crate 3.1.0", "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.66", ] [[package]] name = "jsonrpsee-server" -version = "0.20.4" +version = "0.23.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a482bc4e25eebd0adb61a3468c722763c381225bd3ec46e926f709df8a8eb548" +checksum = "654afab2e92e5d88ebd8a39d6074483f3f2bfdf91c5ac57fe285e7127cdd4f51" dependencies = [ + "anyhow", "futures-util", - "http 0.2.12", - "hyper 0.14.29", + "http 1.1.0", + "http-body 1.0.1", + "http-body-util", + "hyper 1.4.1", + "hyper-util", "jsonrpsee-core", "jsonrpsee-types", + "pin-project", "route-recognizer", "serde", "serde_json", - "soketto", + "soketto 0.8.0", "thiserror", "tokio", "tokio-stream", @@ -5180,25 +5423,24 @@ dependencies = [ [[package]] name = "jsonrpsee-types" -version = "0.20.4" +version = "0.23.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3264e339143fe37ed081953842ee67bfafa99e3b91559bdded6e4abd8fc8535e" +checksum = "d9c465fbe385238e861fdc4d1c85e04ada6c1fd246161d26385c1b311724d2af" dependencies = [ - "anyhow", "beef", + "http 1.1.0", "serde", "serde_json", "thiserror", - "tracing", ] [[package]] name = "jsonrpsee-ws-client" -version = "0.20.4" +version = "0.23.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d06eeabbb55f0af8405288390a358ebcceb6e79e1390741e6f152309c4d6076" +checksum = "1c28759775f5cb2f1ea9667672d3fe2b0e701d1f4b7b67954e60afe7fd058b5e" dependencies = [ - "http 0.2.12", + "http 1.1.0", "jsonrpsee-client-transport", "jsonrpsee-core", "jsonrpsee-types", @@ -5215,6 +5457,7 @@ dependencies = [ "ecdsa", "elliptic-curve", "once_cell", + "serdect", "sha2 0.10.8", ] @@ -5233,6 +5476,21 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c33070833c9ee02266356de0c43f723152bd38bd96ddf52c82b3af10c9138b28" +[[package]] +name = "kusama-runtime-constants" +version = "1.0.0" +source = "git+https://github.com/polkadot-fellows/runtimes#f42acab60edf4d6ded4d9e99b1a8fbacded85669" +dependencies = [ + "frame-support", + "polkadot-primitives", + "polkadot-runtime-common", + "smallvec", + "sp-core", + "sp-runtime", + "sp-weights", + "staging-xcm-builder", +] + [[package]] name = "kvdb" version = "0.13.0" @@ -5302,7 +5560,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c2a198fb6b0eada2a8df47933734e6d35d350665a33a3593d7164fa52c75c19" dependencies = [ "cfg-if", - "windows-targets 0.48.5", + "windows-targets 0.52.6", ] [[package]] @@ -5313,14 +5571,15 @@ checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" [[package]] name = "libp2p" -version = "0.51.4" +version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f35eae38201a993ece6bdc823292d6abd1bffed1c4d0f4a3517d2bd8e1d917fe" +checksum = "e94495eb319a85b70a68b85e2389a95bb3555c71c49025b78c691a854a7e6464" dependencies = [ "bytes", + "either", "futures", "futures-timer", - "getrandom 0.2.15", + "getrandom", "instant", "libp2p-allow-block-list", "libp2p-connection-limits", @@ -5337,18 +5596,21 @@ dependencies = [ "libp2p-request-response", "libp2p-swarm", "libp2p-tcp", + "libp2p-upnp", "libp2p-wasm-ext", "libp2p-websocket", "libp2p-yamux", - "multiaddr", + "multiaddr 0.18.1", "pin-project", + "rw-stream-sink", + "thiserror", ] [[package]] name = "libp2p-allow-block-list" -version = "0.1.1" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "510daa05efbc25184458db837f6f9a5143888f1caa742426d92e1833ddd38a50" +checksum = "55b46558c5c0bf99d3e2a1a38fd54ff5476ca66dd1737b12466a1824dd219311" dependencies = [ "libp2p-core", "libp2p-identity", @@ -5358,9 +5620,9 @@ dependencies = [ [[package]] name = "libp2p-connection-limits" -version = "0.1.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4caa33f1d26ed664c4fe2cca81a08c8e07d4c1c04f2f4ac7655c2dd85467fda0" +checksum = "2f5107ad45cb20b2f6c3628c7b6014b996fcb13a88053f4569c872c6e30abf58" dependencies = [ "libp2p-core", "libp2p-identity", @@ -5370,9 +5632,9 @@ dependencies = [ [[package]] name = "libp2p-core" -version = "0.39.2" +version = "0.40.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c1df63c0b582aa434fb09b2d86897fa2b419ffeccf934b36f87fcedc8e835c2" +checksum = "dd44289ab25e4c9230d9246c475a22241e301b23e8f4061d3bdef304a1a99713" dependencies = [ "either", "fnv", @@ -5381,8 +5643,8 @@ dependencies = [ "instant", "libp2p-identity", "log", - "multiaddr", - "multihash 0.17.0", + "multiaddr 0.18.1", + "multihash 0.19.1", "multistream-select", "once_cell", "parking_lot 0.12.3", @@ -5392,18 +5654,20 @@ dependencies = [ "rw-stream-sink", "smallvec", "thiserror", - "unsigned-varint", + "unsigned-varint 0.7.2", "void", ] [[package]] name = "libp2p-dns" -version = "0.39.0" +version = "0.40.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "146ff7034daae62077c415c2376b8057368042df6ab95f5432ad5e88568b1554" +checksum = "e6a18db73084b4da2871438f6239fef35190b05023de7656e877c18a00541a3b" dependencies = [ + "async-trait", "futures", "libp2p-core", + "libp2p-identity", "log", "parking_lot 0.12.3", "smallvec", @@ -5412,19 +5676,20 @@ dependencies = [ [[package]] name = "libp2p-identify" -version = "0.42.2" +version = "0.43.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5455f472243e63b9c497ff320ded0314254a9eb751799a39c283c6f20b793f3c" +checksum = "45a96638a0a176bec0a4bcaebc1afa8cf909b114477209d7456ade52c61cd9cd" dependencies = [ "asynchronous-codec", "either", "futures", + "futures-bounded", "futures-timer", "libp2p-core", "libp2p-identity", "libp2p-swarm", "log", - "lru 0.10.1", + "lru 0.12.4", "quick-protobuf", "quick-protobuf-codec", "smallvec", @@ -5434,27 +5699,27 @@ dependencies = [ [[package]] name = "libp2p-identity" -version = "0.1.3" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "276bb57e7af15d8f100d3c11cbdd32c6752b7eef4ba7a18ecf464972c07abcce" +checksum = "55cca1eb2bc1fd29f099f3daaab7effd01e1a54b7c577d0ed082521034d912e8" dependencies = [ - "bs58 0.4.0", + "bs58 0.5.1", "ed25519-dalek", - "log", - "multiaddr", - "multihash 0.17.0", + "hkdf", + "multihash 0.19.1", "quick-protobuf", "rand", "sha2 0.10.8", "thiserror", + "tracing", "zeroize", ] [[package]] name = "libp2p-kad" -version = "0.43.3" +version = "0.44.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39d5ef876a2b2323d63c258e63c2f8e36f205fe5a11f0b3095d59635650790ff" +checksum = "16ea178dabba6dde6ffc260a8e0452ccdc8f79becf544946692fff9d412fc29d" dependencies = [ "arrayvec 0.7.4", "asynchronous-codec", @@ -5469,20 +5734,21 @@ dependencies = [ "libp2p-swarm", "log", "quick-protobuf", + "quick-protobuf-codec", "rand", "sha2 0.10.8", "smallvec", "thiserror", "uint", - "unsigned-varint", + "unsigned-varint 0.7.2", "void", ] [[package]] name = "libp2p-mdns" -version = "0.43.1" +version = "0.44.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19983e1f949f979a928f2c603de1cf180cc0dc23e4ac93a62651ccb18341460b" +checksum = "42a2567c305232f5ef54185e9604579a894fd0674819402bb0ac0246da82f52a" dependencies = [ "data-encoding", "futures", @@ -5493,38 +5759,43 @@ dependencies = [ "log", "rand", "smallvec", - "socket2 0.4.10", + "socket2 0.5.7", "tokio", - "trust-dns-proto", + "trust-dns-proto 0.22.0", "void", ] [[package]] name = "libp2p-metrics" -version = "0.12.0" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a42ec91e227d7d0dafa4ce88b333cdf5f277253873ab087555c92798db2ddd46" +checksum = "239ba7d28f8d0b5d77760dc6619c05c7e88e74ec8fbbe97f856f20a56745e620" dependencies = [ + "instant", "libp2p-core", "libp2p-identify", + "libp2p-identity", "libp2p-kad", "libp2p-ping", "libp2p-swarm", + "once_cell", "prometheus-client", ] [[package]] name = "libp2p-noise" -version = "0.42.2" +version = "0.43.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c3673da89d29936bc6435bafc638e2f184180d554ce844db65915113f86ec5e" +checksum = "d2eeec39ad3ad0677551907dd304b2f13f17208ccebe333bef194076cd2e8921" dependencies = [ "bytes", - "curve25519-dalek 3.2.0", + "curve25519-dalek", "futures", "libp2p-core", "libp2p-identity", "log", + "multiaddr 0.18.1", + "multihash 0.19.1", "once_cell", "quick-protobuf", "rand", @@ -5532,21 +5803,22 @@ dependencies = [ "snow", "static_assertions", "thiserror", - "x25519-dalek 1.1.1", + "x25519-dalek", "zeroize", ] [[package]] name = "libp2p-ping" -version = "0.42.0" +version = "0.43.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e57759c19c28a73ef1eb3585ca410cefb72c1a709fcf6de1612a378e4219202" +checksum = "e702d75cd0827dfa15f8fd92d15b9932abe38d10d21f47c50438c71dd1b5dae3" dependencies = [ "either", "futures", "futures-timer", "instant", "libp2p-core", + "libp2p-identity", "libp2p-swarm", "log", "rand", @@ -5555,9 +5827,9 @@ dependencies = [ [[package]] name = "libp2p-quic" -version = "0.7.0-alpha.3" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6b26abd81cd2398382a1edfe739b539775be8a90fa6914f39b2ab49571ec735" +checksum = "130d451d83f21b81eb7b35b360bc7972aeafb15177784adc56528db082e6b927" dependencies = [ "bytes", "futures", @@ -5568,18 +5840,20 @@ dependencies = [ "libp2p-tls", "log", "parking_lot 0.12.3", - "quinn-proto", + "quinn 0.10.2", "rand", - "rustls 0.20.9", + "ring 0.16.20", + "rustls 0.21.12", + "socket2 0.5.7", "thiserror", "tokio", ] [[package]] name = "libp2p-request-response" -version = "0.24.1" +version = "0.25.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ffdb374267d42dc5ed5bc53f6e601d4a64ac5964779c6e40bb9e4f14c1e30d5" +checksum = "d8e3b4d67870478db72bac87bfc260ee6641d0734e0e3e275798f089c3fecfd4" dependencies = [ "async-trait", "futures", @@ -5587,15 +5861,17 @@ dependencies = [ "libp2p-core", "libp2p-identity", "libp2p-swarm", + "log", "rand", "smallvec", + "void", ] [[package]] name = "libp2p-swarm" -version = "0.42.2" +version = "0.43.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "903b3d592d7694e56204d211f29d31bc004be99386644ba8731fc3e3ef27b296" +checksum = "580189e0074af847df90e75ef54f3f30059aedda37ea5a1659e8b9fca05c0141" dependencies = [ "either", "fnv", @@ -5606,6 +5882,8 @@ dependencies = [ "libp2p-identity", "libp2p-swarm-derive", "log", + "multistream-select", + "once_cell", "rand", "smallvec", "tokio", @@ -5614,36 +5892,39 @@ dependencies = [ [[package]] name = "libp2p-swarm-derive" -version = "0.32.0" +version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fba456131824ab6acd4c7bf61e9c0f0a3014b5fc9868ccb8e10d344594cdc4f" +checksum = "c4d5ec2a3df00c7836d7696c136274c9c59705bac69133253696a6c932cd1d74" dependencies = [ "heck 0.4.1", + "proc-macro-warning 0.4.2", + "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.66", ] [[package]] name = "libp2p-tcp" -version = "0.39.0" +version = "0.40.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33d33698596d7722d85d3ab0c86c2c322254fce1241e91208e3679b4eb3026cf" +checksum = "b558dd40d1bcd1aaaed9de898e9ec6a436019ecc2420dd0016e712fbb61c5508" dependencies = [ "futures", "futures-timer", "if-watch", "libc", "libp2p-core", + "libp2p-identity", "log", - "socket2 0.4.10", + "socket2 0.5.7", "tokio", ] [[package]] name = "libp2p-tls" -version = "0.1.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff08d13d0dc66e5e9ba6279c1de417b84fa0d0adc3b03e5732928c180ec02781" +checksum = "8218d1d5482b122ccae396bbf38abdcb283ecc96fa54760e1dfd251f0546ac61" dependencies = [ "futures", "futures-rustls", @@ -5651,51 +5932,69 @@ dependencies = [ "libp2p-identity", "rcgen", "ring 0.16.20", - "rustls 0.20.9", + "rustls 0.21.12", + "rustls-webpki 0.101.7", "thiserror", - "webpki", - "x509-parser", + "x509-parser 0.15.1", "yasna", ] +[[package]] +name = "libp2p-upnp" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82775a47b34f10f787ad3e2a22e2c1541e6ebef4fe9f28f3ac553921554c94c1" +dependencies = [ + "futures", + "futures-timer", + "igd-next", + "libp2p-core", + "libp2p-swarm", + "log", + "tokio", + "void", +] + [[package]] name = "libp2p-wasm-ext" -version = "0.39.0" +version = "0.40.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77dff9d32353a5887adb86c8afc1de1a94d9e8c3bc6df8b2201d7cdf5c848f43" +checksum = "1e5d8e3a9e07da0ef5b55a9f26c009c8fb3c725d492d8bb4b431715786eea79c" dependencies = [ "futures", "js-sys", "libp2p-core", - "parity-send-wrapper", + "send_wrapper", "wasm-bindgen", "wasm-bindgen-futures", ] [[package]] name = "libp2p-websocket" -version = "0.41.0" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "111273f7b3d3510524c752e8b7a5314b7f7a1fee7e68161c01a7d72cbb06db9f" +checksum = "004ee9c4a4631435169aee6aad2f62e3984dc031c43b6d29731e8e82a016c538" dependencies = [ "either", "futures", "futures-rustls", "libp2p-core", + "libp2p-identity", "log", "parking_lot 0.12.3", - "quicksink", + "pin-project-lite", "rw-stream-sink", - "soketto", + "soketto 0.8.0", + "thiserror", "url", - "webpki-roots", + "webpki-roots 0.25.4", ] [[package]] name = "libp2p-yamux" -version = "0.43.1" +version = "0.44.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4dcd21d950662700a385d4c6d68e2f5f54d778e97068cdd718522222ef513bda" +checksum = "8eedcb62824c4300efb9cfd4e2a6edaf3ca097b9e68b36dabe45a44469fd6a85" dependencies = [ "futures", "libp2p-core", @@ -5756,7 +6055,7 @@ checksum = "5be9b9bb642d8522a44d533eab56c16c738301965504753b03ad1de3425d5451" dependencies = [ "crunchy", "digest 0.9.0", - "subtle 2.4.1", + "subtle 2.5.0", ] [[package]] @@ -5857,6 +6156,61 @@ version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "643cb0b8d4fcc284004d5fd0d67ccf61dfffadb7f75e1e71bc420f4688a3a704" +[[package]] +name = "litep2p" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f46c51c205264b834ceed95c8b195026e700494bc3991aaba3b4ea9e20626d9" +dependencies = [ + "async-trait", + "bs58 0.4.0", + "bytes", + "cid 0.10.1", + "ed25519-dalek", + "futures", + "futures-timer", + "hex-literal", + "indexmap 2.2.6", + "libc", + "mockall 0.12.1", + "multiaddr 0.17.1", + "multihash 0.17.0", + "network-interface", + "nohash-hasher", + "parking_lot 0.12.3", + "pin-project", + "prost 0.12.6", + "prost-build 0.11.9", + "quinn 0.9.4", + "rand", + "rcgen", + "ring 0.16.20", + "rustls 0.20.9", + "serde", + "sha2 0.10.8", + "simple-dns", + "smallvec", + "snow", + "socket2 0.5.7", + "static_assertions", + "str0m", + "thiserror", + "tokio", + "tokio-stream", + "tokio-tungstenite", + "tokio-util", + "tracing", + "trust-dns-resolver", + "uint", + "unsigned-varint 0.8.0", + "url", + "webpki", + "x25519-dalek", + "x509-parser 0.16.0", + "yasna", + "zeroize", +] + [[package]] name = "lock_api" version = "0.4.12" @@ -5884,18 +6238,18 @@ dependencies = [ [[package]] name = "lru" -version = "0.10.1" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "718e8fae447df0c7e1ba7f5189829e63fd536945c8988d61444c19039f16b670" -dependencies = [ - "hashbrown 0.13.2", -] +checksum = "a4a83fb7698b3643a0e34f9ae6f2e8f0178c0fd42f8b59d493aa271ff3a5bf21" [[package]] name = "lru" -version = "0.11.1" +version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4a83fb7698b3643a0e34f9ae6f2e8f0178c0fd42f8b59d493aa271ff3a5bf21" +checksum = "37ee39891760e7d94734f6f63fedc29a2e4a152f836120753a72503f09fcf904" +dependencies = [ + "hashbrown 0.14.5", +] [[package]] name = "lru-cache" @@ -5937,9 +6291,9 @@ dependencies = [ [[package]] name = "macro_magic" -version = "0.5.1" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc33f9f0351468d26fbc53d9ce00a096c8522ecb42f19b50f34f2c422f76d21d" +checksum = "e03844fc635e92f3a0067e25fa4bf3e3dbf3f2927bf3aa01bb7bc8f1c428949d" dependencies = [ "macro_magic_core", "macro_magic_macros", @@ -5949,12 +6303,12 @@ dependencies = [ [[package]] name = "macro_magic_core" -version = "0.5.1" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1687dc887e42f352865a393acae7cf79d98fab6351cde1f58e9e057da89bf150" +checksum = "468155613a44cfd825f1fb0ffa532b018253920d404e6fca1e8d43155198a46d" dependencies = [ "const-random", - "derive-syn-parse 0.2.0", + "derive-syn-parse 0.1.5", "macro_magic_core_macros", "proc-macro2", "quote", @@ -5963,9 +6317,9 @@ dependencies = [ [[package]] name = "macro_magic_core_macros" -version = "0.5.1" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b02abfe41815b5bd98dbd4260173db2c116dda171dc0fe7838cb206333b83308" +checksum = "9ea73aa640dc01d62a590d48c0c3521ed739d53b27f919b25c3551e233481654" dependencies = [ "proc-macro2", "quote", @@ -5974,21 +6328,15 @@ dependencies = [ [[package]] name = "macro_magic_macros" -version = "0.5.1" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73ea28ee64b88876bf45277ed9a5817c1817df061a74f2b988971a12570e5869" +checksum = "ef9d79ae96aaba821963320eb2b6e34d17df1e5a83d8a1985c29cc5be59577b3" dependencies = [ "macro_magic_core", "quote", "syn 2.0.66", ] -[[package]] -name = "maplit" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e2e65a1a2e43cfcb47a895c4c8b10d1f4a61097f9f254f183aee60cad9c651d" - [[package]] name = "match_cfg" version = "0.1.0" @@ -6080,6 +6428,20 @@ dependencies = [ "hash-db", ] +[[package]] +name = "merkleized-metadata" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f313fcff1d2a4bcaa2deeaa00bf7530d77d5f7bd0467a117dde2e29a75a7a17a" +dependencies = [ + "array-bytes", + "blake3", + "frame-metadata", + "parity-scale-codec", + "scale-decode", + "scale-info", +] + [[package]] name = "merlin" version = "3.0.0" @@ -6088,7 +6450,7 @@ checksum = "58c38e2799fc0978b65dfff8023ec7843e2330bb462f19198840b34b6582397d" dependencies = [ "byteorder", "keccak", - "rand_core 0.6.4", + "rand_core", "zeroize", ] @@ -6118,15 +6480,6 @@ dependencies = [ "adler", ] -[[package]] -name = "miniz_oxide" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2d80299ef12ff69b16a84bb182e3b9df68b5a91574d3d4fa6e41b65deec4df1" -dependencies = [ - "adler2", -] - [[package]] name = "mio" version = "0.8.11" @@ -6135,7 +6488,7 @@ checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" dependencies = [ "libc", "log", - "wasi 0.11.0+wasi-snapshot-preview1", + "wasi", "windows-sys 0.48.0", ] @@ -6150,25 +6503,25 @@ dependencies = [ "bitflags 1.3.2", "blake2 0.10.6", "c2-chacha", - "curve25519-dalek 4.1.3", + "curve25519-dalek", "either", "hashlink", "lioness", "log", "parking_lot 0.12.3", "rand", - "rand_chacha 0.3.1", + "rand_chacha", "rand_distr", - "subtle 2.4.1", + "subtle 2.5.0", "thiserror", "zeroize", ] [[package]] name = "mmr-gadget" -version = "30.0.0" +version = "37.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f62cddc29c17965ab16a051a745520d41c28d8b4c2b6188aaf661db056d67c9" +checksum = "8f06f25f3b298799dbc20f7ffd40e667adc4fbd664cbb23ead5f7bbda52407ff" dependencies = [ "futures", "log", @@ -6186,9 +6539,9 @@ dependencies = [ [[package]] name = "mmr-rpc" -version = "29.0.0" +version = "35.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2634b45039e064c343a0a77ed45e03ca027c84e1b250b2f3988af7cde9b7e79e" +checksum = "7f9a252b1e03418e99c18ff6e2d4d9748d195395ed3749c8bfd9ca2c7530a43d" dependencies = [ "jsonrpsee", "parity-scale-codec", @@ -6210,8 +6563,23 @@ dependencies = [ "downcast", "fragile", "lazy_static", - "mockall_derive", - "predicates", + "mockall_derive 0.11.4", + "predicates 2.1.5", + "predicates-tree", +] + +[[package]] +name = "mockall" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43766c2b5203b10de348ffe19f7e54564b64f3d6018ff7648d1e2d6d3a0f0a48" +dependencies = [ + "cfg-if", + "downcast", + "fragile", + "lazy_static", + "mockall_derive 0.12.1", + "predicates 3.1.2", "predicates-tree", ] @@ -6227,6 +6595,24 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "mockall_derive" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af7cbce79ec385a1d4f54baa90a76401eb15d9cab93685f62e7e9f942aa00ae2" +dependencies = [ + "cfg-if", + "proc-macro2", + "quote", + "syn 2.0.66", +] + +[[package]] +name = "multi-stash" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "685a9ac4b61f4e728e1d2c6a7844609c16527aeb5e6c865915c08e619c16410f" + [[package]] name = "multiaddr" version = "0.17.1" @@ -6242,7 +6628,26 @@ dependencies = [ "percent-encoding", "serde", "static_assertions", - "unsigned-varint", + "unsigned-varint 0.7.2", + "url", +] + +[[package]] +name = "multiaddr" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b852bc02a2da5feed68cd14fa50d0774b92790a5bdbfa932a813926c8472070" +dependencies = [ + "arrayref", + "byteorder", + "data-encoding", + "libp2p-identity", + "multibase", + "multihash 0.19.1", + "percent-encoding", + "serde", + "static_assertions", + "unsigned-varint 0.7.2", "url", ] @@ -6268,10 +6673,10 @@ dependencies = [ "blake3", "core2", "digest 0.10.7", - "multihash-derive 0.8.1", + "multihash-derive", "sha2 0.10.8", "sha3", - "unsigned-varint", + "unsigned-varint 0.7.2", ] [[package]] @@ -6280,11 +6685,15 @@ version = "0.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cfd8a792c1694c6da4f68db0a9d707c72bd260994da179e6030a5dcee00bb815" dependencies = [ + "blake2b_simd", + "blake2s_simd", + "blake3", "core2", "digest 0.10.7", - "multihash-derive 0.8.1", + "multihash-derive", "sha2 0.10.8", - "unsigned-varint", + "sha3", + "unsigned-varint 0.7.2", ] [[package]] @@ -6294,27 +6703,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "076d548d76a0e2a0d4ab471d0b1c36c577786dfc4471242035d97a12a735c492" dependencies = [ "core2", - "unsigned-varint", -] - -[[package]] -name = "multihash-codetable" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6d815ecb3c8238d00647f8630ede7060a642c9f704761cd6082cb4028af6935" -dependencies = [ - "blake2b_simd", - "blake2s_simd", - "blake3", - "core2", - "digest 0.10.7", - "multihash-derive 0.9.0", - "ripemd", - "serde", - "sha1", - "sha2 0.10.8", - "sha3", - "strobe-rs", + "unsigned-varint 0.7.2", ] [[package]] @@ -6332,48 +6721,29 @@ dependencies = [ ] [[package]] -name = "multihash-derive" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "890e72cb7396cb99ed98c1246a97b243cc16394470d94e0bc8b0c2c11d84290e" -dependencies = [ - "core2", - "multihash 0.19.1", - "multihash-derive-impl", -] - -[[package]] -name = "multihash-derive-impl" -version = "0.1.1" +name = "multimap" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3958713ce794e12f7c6326fac9aa274c68d74c4881dd37b3e2662b8a2046bb19" -dependencies = [ - "proc-macro-crate 2.0.0", - "proc-macro-error", - "proc-macro2", - "quote", - "syn 2.0.66", - "synstructure 0.13.1", -] +checksum = "e5ce46fe64a9d73be07dcbe690a38ce1b293be448fd8ce1e6c1b8062c9f72c6a" [[package]] name = "multimap" -version = "0.8.3" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5ce46fe64a9d73be07dcbe690a38ce1b293be448fd8ce1e6c1b8062c9f72c6a" +checksum = "defc4c55412d89136f966bbb339008b474350e5e6e78d2714439c386b3137a03" [[package]] name = "multistream-select" -version = "0.12.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8552ab875c1313b97b8d20cb857b9fd63e2d1d6a0a1b53ce9821e575405f27a" +checksum = "ea0df8e5eec2298a62b326ee4f0d7fe1a6b90a09dfcf9df37b38f947a8c42f19" dependencies = [ "bytes", "futures", "log", "pin-project", "smallvec", - "unsigned-varint", + "unsigned-varint 0.7.2", ] [[package]] @@ -6484,6 +6854,18 @@ dependencies = [ "tokio", ] +[[package]] +name = "network-interface" +version = "1.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4a43439bf756eed340bdf8feba761e2d50c7d47175d87545cd5cbe4a137c4d1" +dependencies = [ + "cc", + "libc", + "thiserror", + "winapi", +] + [[package]] name = "nix" version = "0.24.3" @@ -6497,15 +6879,22 @@ dependencies = [ [[package]] name = "nix" -version = "0.27.1" +version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2eb04e9c688eff1c89d72b407f168cf79bb9e867a9d3323ed6c01519eb9cc053" +checksum = "ab2156c4fce2f8df6c499cc1c763e4394b7482525bf2a9701c9d79d215f519e4" dependencies = [ "bitflags 2.5.0", "cfg-if", + "cfg_aliases", "libc", ] +[[package]] +name = "no-std-compat" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b93853da6d84c2e3c7d730d6473e8817692dd89be387eb01b94d7f108ecb5b8c" + [[package]] name = "no-std-net" version = "0.6.0" @@ -6534,12 +6923,34 @@ dependencies = [ "minimal-lexical", ] +[[package]] +name = "nonempty" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e9e591e719385e6ebaeb5ce5d3887f7d5676fceca6411d1925ccc95745f3d6f7" + +[[package]] +name = "nonzero_ext" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38bf9645c8b145698bb0b18a4637dcacbc421ea49bef2317e4fd8065a387cf21" + [[package]] name = "normalize-line-endings" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "61807f77802ff30975e01f4f071c8ba10c022052f98b3294119f3e615d13e5be" +[[package]] +name = "nu-ansi-term" +version = "0.46.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" +dependencies = [ + "overload", + "winapi", +] + [[package]] name = "num-bigint" version = "0.4.5" @@ -6565,6 +6976,17 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" +[[package]] +name = "num-derive" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.66", +] + [[package]] name = "num-format" version = "0.4.4" @@ -6615,12 +7037,6 @@ dependencies = [ "libc", ] -[[package]] -name = "number_prefix" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3" - [[package]] name = "object" version = "0.30.4" @@ -6633,6 +7049,15 @@ dependencies = [ "memchr", ] +[[package]] +name = "object" +version = "0.32.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" +dependencies = [ + "memchr", +] + [[package]] name = "object" version = "0.36.0" @@ -6648,7 +7073,16 @@ version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9bedf36ffb6ba96c2eb7144ef6270557b52e54b20c0a8e1eb2ff99a6c6959bff" dependencies = [ - "asn1-rs", + "asn1-rs 0.5.2", +] + +[[package]] +name = "oid-registry" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c958dd45046245b9c3c2547369bb634eb461670b2e7e0de552905801a648d1d" +dependencies = [ + "asn1-rs 0.6.2", ] [[package]] @@ -6669,12 +7103,60 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" +[[package]] +name = "openssl" +version = "0.10.66" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9529f4786b70a3e8c61e11179af17ab6188ad8d0ded78c5529441ed39d4bd9c1" +dependencies = [ + "bitflags 2.5.0", + "cfg-if", + "foreign-types", + "libc", + "once_cell", + "openssl-macros", + "openssl-sys", +] + +[[package]] +name = "openssl-macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.66", +] + [[package]] name = "openssl-probe" version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" +[[package]] +name = "openssl-src" +version = "300.3.1+3.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7259953d42a81bf137fbbd73bd30a8e1914d6dce43c2b90ed575783a22608b91" +dependencies = [ + "cc", +] + +[[package]] +name = "openssl-sys" +version = "0.9.103" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f9e8deee91df40a943c71b917e5874b951d32a802526c85721ce3b776c929d6" +dependencies = [ + "cc", + "libc", + "openssl-src", + "pkg-config", + "vcpkg", +] + [[package]] name = "option-ext" version = "0.2.0" @@ -6704,7 +7186,7 @@ version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1344346d5af32c95bbddea91b18a88cc83eac394192d20ef2fc4c40a74332355" dependencies = [ - "expander 2.2.1", + "expander", "indexmap 2.2.6", "itertools 0.11.0", "petgraph", @@ -6733,6 +7215,12 @@ dependencies = [ "windows-sys 0.59.0", ] +[[package]] +name = "overload" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" + [[package]] name = "pallet-api" version = "0.1.0" @@ -6754,13 +7242,14 @@ dependencies = [ [[package]] name = "pallet-asset-conversion" -version = "11.0.0" +version = "18.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4079f12db3cf98daa717337ab5b7e5ef15aa3bec3b497f501dc715d129b500da" +checksum = "f726ebb59401c1844a4a8703047bdafcd99a1827cd5d8b2c82abeb8948a7f25b" dependencies = [ "frame-benchmarking", "frame-support", "frame-system", + "log", "parity-scale-codec", "scale-info", "sp-api", @@ -6773,9 +7262,9 @@ dependencies = [ [[package]] name = "pallet-asset-conversion-tx-payment" -version = "11.0.0" +version = "18.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2019e84d65bf6c6105edb61cd6b6f4c6d9a1b347e05d9380e92b0dcf2a29fd7" +checksum = "e0fde03a96382f4dbe37ef95cb4ef7aade7c0be410cb6c888eda911c94af3eaf" dependencies = [ "frame-support", "frame-system", @@ -6789,9 +7278,9 @@ dependencies = [ [[package]] name = "pallet-asset-rate" -version = "8.0.0" +version = "15.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "571ce57fd846911041749832b46a8c2b01f0b79ffebcd7585e3973865607036d" +checksum = "e806842bec955190ec64f8b2179f74f5355137c4cadf04f3269e6196cd19caf9" dependencies = [ "frame-benchmarking", "frame-support", @@ -6805,9 +7294,9 @@ dependencies = [ [[package]] name = "pallet-asset-tx-payment" -version = "29.0.0" +version = "36.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ed783679921ad8b96807d683d320c314e305753b230d5c04dc713bab7aca64c" +checksum = "100a180dfbf30a1c872100ec2dae8a61c0f5e8b3f2d3a5cbb34093826293e2ab" dependencies = [ "frame-benchmarking", "frame-support", @@ -6824,13 +7313,14 @@ dependencies = [ [[package]] name = "pallet-assets" -version = "30.0.0" +version = "37.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46728a98a910af13f6a77033dd053456650773bb7adc71e0ba845bff7e31b33e" +checksum = "f79ef6a7763fc08177f014052469ee12aefcdad0d99a747372360c2f648d2cc4" dependencies = [ "frame-benchmarking", "frame-support", "frame-system", + "impl-trait-for-tuples", "log", "parity-scale-codec", "scale-info", @@ -6841,9 +7331,9 @@ dependencies = [ [[package]] name = "pallet-aura" -version = "28.0.0" +version = "35.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a611bef3c8cf281e41a43f32a4153260bdc8b7b61b901e65c7a4442529224e11" +checksum = "0861b2a1ad6526948567bb59a3fdc4c7f02ee79b07be8b931a544350ec35ab0c" dependencies = [ "frame-support", "frame-system", @@ -6859,9 +7349,9 @@ dependencies = [ [[package]] name = "pallet-authority-discovery" -version = "29.0.1" +version = "36.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cd9a381c613e6538638391fb51f353fd13b16f849d0d1ac66a388326bd456f1" +checksum = "ed2c3666a476132f5846fe4d5e1961a923a58a0f54d873d84566f24ffaa3684f" dependencies = [ "frame-support", "frame-system", @@ -6876,9 +7366,9 @@ dependencies = [ [[package]] name = "pallet-authorship" -version = "29.0.0" +version = "36.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d83773e731a1760f99684b09961ed7b92acafe335f36f08ebb8313d3b9c72e2" +checksum = "38885846dbcf03b025fdbd7edb3649046dbc68fa0b419ffe8837ef853a10d31f" dependencies = [ "frame-support", "frame-system", @@ -6891,9 +7381,9 @@ dependencies = [ [[package]] name = "pallet-babe" -version = "29.0.0" +version = "36.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3f2020c52667a650d64e84a4bbb63388e25bc1c9bc872a8243d03bfcb285049" +checksum = "b23d2d814e3cb793659fcf84533f66fdf0ed9cccb66cb2225851f482843ed096" dependencies = [ "frame-benchmarking", "frame-support", @@ -6916,9 +7406,9 @@ dependencies = [ [[package]] name = "pallet-bags-list" -version = "28.0.0" +version = "35.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd27bfa4bfa5751652842b81241c7eff3e68f2806d9dacc17b03d2cb20a39756" +checksum = "af34fa3fb6a0abe3577e435988039a9e441f6705ae2d3ad627a23e3f705baa2d" dependencies = [ "aquamarine", "docify", @@ -6939,9 +7429,9 @@ dependencies = [ [[package]] name = "pallet-balances" -version = "29.0.2" +version = "37.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9a54b5d0c7c4c3731883d6b1ac18aff44db20c3d0a3470c8861001a17afdc85" +checksum = "6878e240962d3887f0e0654ac343a18845adb95ad493c9d4d5e803c015d4a4c3" dependencies = [ "docify", "frame-benchmarking", @@ -6956,9 +7446,9 @@ dependencies = [ [[package]] name = "pallet-beefy" -version = "29.0.0" +version = "36.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bedd80e9d8b196f31ea134efd271fdc1b8380ca3aa2d8af6ea8b5a0dc4fa460" +checksum = "715dfcd1bf3f1f37af6335d4eb3cef921e746ac54721e2258c4fd968b61eb009" dependencies = [ "frame-support", "frame-system", @@ -6977,11 +7467,11 @@ dependencies = [ [[package]] name = "pallet-beefy-mmr" -version = "29.0.0" +version = "36.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d334f24d3c0c016d16aa87d069485847d622e8ebebace18ec5cf56609ca3a67" +checksum = "01d70c6f872eb3f2635355ccbea944a4f9ea411c0aa25f6f1a15219e8da11ad2" dependencies = [ - "array-bytes 6.2.3", + "array-bytes", "binary-merkle-tree", "frame-support", "frame-system", @@ -7003,9 +7493,9 @@ dependencies = [ [[package]] name = "pallet-bounties" -version = "28.0.0" +version = "35.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4765879e96676c13cdbed746d66fd59dcde1e9e65fda1f064fa2fffa3bc5d597" +checksum = "0566499e74ba4b7ccbd1b667eef0dab76ca28402a8d501e22b73a363717b05a9" dependencies = [ "frame-benchmarking", "frame-support", @@ -7022,9 +7512,9 @@ dependencies = [ [[package]] name = "pallet-bridge-grandpa" -version = "0.8.0" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "085573f22a29f8108e2e374b4b4c90702a7449c21edc29d1d614889e9b0c8c0c" +checksum = "61d30a4860bb12559dc28b2d46dd865e2066bce83239230f748e2c569a3cadf4" dependencies = [ "bp-header-chain", "bp-runtime", @@ -7044,9 +7534,9 @@ dependencies = [ [[package]] name = "pallet-bridge-messages" -version = "0.8.0" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b0aac358f6781471f6fd667d5d5af6ee55c3eb11fc494de76787e942bc43726" +checksum = "e3c0fcb1b9ae50ece73cbe36b72c2778f5d4637e4fb0cfac30cb16f7d4b61d5e" dependencies = [ "bp-messages", "bp-runtime", @@ -7063,9 +7553,9 @@ dependencies = [ [[package]] name = "pallet-bridge-parachains" -version = "0.8.0" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6976281a13460098827ef61a368ef5c26f07bb4bfaf81a9ee4105577a73fc488" +checksum = "3974fb658cf1b9ca8c2d3c77bf080b2f94c054c2b466b709ef29f6d3726f2231" dependencies = [ "bp-header-chain", "bp-parachains", @@ -7085,9 +7575,9 @@ dependencies = [ [[package]] name = "pallet-bridge-relayers" -version = "0.8.0" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc71ebc287106596ae4d6026d1bdea6448c4b26f08f4477e8e9a2620e5a7c24b" +checksum = "2c92383f4c7d1eaced8413e39b948227a527a0136f705660580c57753dc11568" dependencies = [ "bp-messages", "bp-relayers", @@ -7106,9 +7596,9 @@ dependencies = [ [[package]] name = "pallet-broker" -version = "0.7.2" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "574c52fd629191c374c24a18036acac008ea92142309e5dd05e7f03149a667c3" +checksum = "cd0d652c399b6ed776ee3322e60f40e323f86b413719d7696eddb8f64c368ac0" dependencies = [ "bitvec", "frame-benchmarking", @@ -7117,6 +7607,7 @@ dependencies = [ "log", "parity-scale-codec", "scale-info", + "sp-api", "sp-arithmetic", "sp-core", "sp-runtime", @@ -7125,9 +7616,9 @@ dependencies = [ [[package]] name = "pallet-child-bounties" -version = "28.0.0" +version = "35.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00fd06f2d719f5bb16ab3e836c6b053bbd92631ba694f8c2bf810013b2548167" +checksum = "38e351f103ebbdd1eb095da8c2379caccc82ebc59a740c2731693d2204286b83" dependencies = [ "frame-benchmarking", "frame-support", @@ -7145,9 +7636,9 @@ dependencies = [ [[package]] name = "pallet-collator-selection" -version = "10.0.3" +version = "17.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a36858c4275b7d19671b321e95f545e07c9643f97dffed1b333774cb391a4456" +checksum = "f660cc09f2f277a3976da2eef856b5c725ab7ad1192902ef7f4e4bafd992f04f" dependencies = [ "frame-benchmarking", "frame-support", @@ -7166,9 +7657,9 @@ dependencies = [ [[package]] name = "pallet-collective" -version = "29.0.0" +version = "36.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c362a0b8f30895c15ecc7d8c24b0d94bb586c4b9bbd37ac8053b4629d9cc80b" +checksum = "771bf7f6c76c3ea5e965fee0bf1d8a8c79c8c52d75ead65ed3c4d385f333756f" dependencies = [ "frame-benchmarking", "frame-support", @@ -7184,9 +7675,9 @@ dependencies = [ [[package]] name = "pallet-contracts" -version = "28.0.0" +version = "35.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b56fe53df97911ed3ecd90d631f8093cedd795c756d4e42d386110e9fe6614f" +checksum = "3e6989ac82690f981959b0d38ac6d6d52fc06bf00a035548d62b9a2e9c220376" dependencies = [ "bitflags 1.3.2", "environmental", @@ -7199,6 +7690,7 @@ dependencies = [ "pallet-contracts-proc-macro", "pallet-contracts-uapi", "parity-scale-codec", + "paste", "rand", "rand_pcg", "scale-info", @@ -7212,14 +7704,14 @@ dependencies = [ "staging-xcm", "staging-xcm-builder", "wasm-instrument", - "wasmi", + "wasmi 0.32.3", ] [[package]] name = "pallet-contracts-proc-macro" -version = "19.0.0" +version = "23.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3163c6bc21b55a0ccb74c546ba784d9c9e69beb9240c059d28a3052f4cbce509" +checksum = "94226cbd48516b7c310eb5dae8d50798c1ce73a7421dc0977c55b7fc2237a283" dependencies = [ "proc-macro2", "quote", @@ -7228,9 +7720,9 @@ dependencies = [ [[package]] name = "pallet-contracts-uapi" -version = "6.0.0" +version = "11.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61eeda58538dc888c59ae6de2146f0e2f43e9ad0eb1d56c228e5cc7af90d4e52" +checksum = "e1330375dcced95509e3cca7ef6b1c3fac648df995b86d39467d082ba981dc46" dependencies = [ "bitflags 1.3.2", "parity-scale-codec", @@ -7241,9 +7733,9 @@ dependencies = [ [[package]] name = "pallet-conviction-voting" -version = "29.0.0" +version = "36.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6aee3a8b6fcde893f862993f9d45eb0fcd492dde0967fd56ef78d79fc7b53dc0" +checksum = "9033f0d23500bbc39298fd50c07b89a2f2d9f07300139b4df8005995ef683875" dependencies = [ "assert_matches", "frame-benchmarking", @@ -7257,11 +7749,26 @@ dependencies = [ "sp-std", ] +[[package]] +name = "pallet-delegated-staking" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0596ec5ab55e02b1b5637b3ec2b99027d036fe97a1ab4733ae105474dfa727cf" +dependencies = [ + "frame-support", + "frame-system", + "parity-scale-codec", + "scale-info", + "sp-runtime", + "sp-staking", + "sp-std", +] + [[package]] name = "pallet-democracy" -version = "29.0.0" +version = "36.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa781d632063087bcd3ff46eb1a668f15647ab116f1c8a7c573b7168f62d72c3" +checksum = "7ccd68a2bf5f2dfda2b810cbe1a779492d4c2e99338989fede4389d412ae325b" dependencies = [ "frame-benchmarking", "frame-support", @@ -7278,9 +7785,9 @@ dependencies = [ [[package]] name = "pallet-election-provider-multi-phase" -version = "28.0.0" +version = "35.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b54d1d3fe9ae61a144d581147e699b7c3009169de0019a0f87cca0bed82681e7" +checksum = "bd1090fdc6ccdd8ff08c60000c970428baaaf0b33e7a6b01a91ec8b697a650a3" dependencies = [ "frame-benchmarking", "frame-election-provider-support", @@ -7297,14 +7804,14 @@ dependencies = [ "sp-npos-elections", "sp-runtime", "sp-std", - "strum 0.24.1", + "strum 0.26.2", ] [[package]] name = "pallet-election-provider-support-benchmarking" -version = "28.0.0" +version = "35.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46ec87816a1e32a1ab6deececa99e21e6684b111efe87b11b8298328dbbefd01" +checksum = "93475989d2f6900caf8f1c847a55d909295c156525a7510c5f1dde176ec7c714" dependencies = [ "frame-benchmarking", "frame-election-provider-support", @@ -7317,9 +7824,9 @@ dependencies = [ [[package]] name = "pallet-elections-phragmen" -version = "30.0.0" +version = "37.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10cb0158cc7461fda5db04c5791d0df34635bec37181763aca449bade677d12d" +checksum = "9320d95c95e2d4d3ee24c9292b4ee8562ecb724b985613cfa7f274912bad2c9d" dependencies = [ "frame-benchmarking", "frame-support", @@ -7337,9 +7844,9 @@ dependencies = [ [[package]] name = "pallet-fast-unstake" -version = "28.0.0" +version = "35.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2222607a0dba10a9d57cab5360a6549b5fda925181c3c7af481246c0964998df" +checksum = "9155f4f762513e0287320411415c76a647152799ad33db1785c9b71c36a14575" dependencies = [ "docify", "frame-benchmarking", @@ -7357,9 +7864,9 @@ dependencies = [ [[package]] name = "pallet-grandpa" -version = "29.0.0" +version = "36.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5b20be8592eed7ebca2ee661fc43450088552ebe0bd483d7b101cf5968ab12d" +checksum = "8244b686d5cae6a8af1557ed0f49db08f812f0e7942a8d2da554b4da8a69daf0" dependencies = [ "frame-benchmarking", "frame-support", @@ -7381,9 +7888,9 @@ dependencies = [ [[package]] name = "pallet-identity" -version = "29.0.1" +version = "36.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "452bba25325b7f0148eeecbde13e7c26dfb677ad46b3f160b359d7643b44c94b" +checksum = "4555795a3e0e3aa49ea432b7afecb9c71a7db8793a99c68bd8dd3a52a12571f3" dependencies = [ "enumflags2", "frame-benchmarking", @@ -7399,9 +7906,9 @@ dependencies = [ [[package]] name = "pallet-im-online" -version = "28.0.0" +version = "35.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "598ea5c87351edc953d1f455f32ff456cf2f1daf7bbada1f1e03be8e384852ab" +checksum = "fa761292e95020304b58b50e5187f8bb82f557c8c2d013e3c96ab41d611873b0" dependencies = [ "frame-benchmarking", "frame-support", @@ -7420,9 +7927,9 @@ dependencies = [ [[package]] name = "pallet-indices" -version = "29.0.0" +version = "36.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e880ebdb429ca76fb400b1b361ed7fce018a5ea2fc2da4764de5156fffdfa73" +checksum = "b183880ad5efae06afe6066e76f2bac5acf67f34b3cfab7352ceec46accf4b45" dependencies = [ "frame-benchmarking", "frame-support", @@ -7438,9 +7945,9 @@ dependencies = [ [[package]] name = "pallet-membership" -version = "29.0.0" +version = "36.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad901cdf3de23daf23ff8b092ab318b13faebfc1aa4d84263f2fdc84feaf3e9b" +checksum = "34006cf047f47edbef33874cc64895918e2c5d7562795209068d5fb388c53a30" dependencies = [ "frame-benchmarking", "frame-support", @@ -7456,9 +7963,9 @@ dependencies = [ [[package]] name = "pallet-message-queue" -version = "32.0.0" +version = "39.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ccb23dee70b184a214d729db550117a0965a69107d466d35181d60a6feede38" +checksum = "20e65a37881d1998546254a5e50a1f768b3f82deabe774e750f4ea95aba8030c" dependencies = [ "environmental", "frame-benchmarking", @@ -7477,9 +7984,9 @@ dependencies = [ [[package]] name = "pallet-mmr" -version = "28.0.0" +version = "35.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6f1f23a70764dad2b4094d8be12ebbb82df210f2e80dd36fa941a5ac191c6cd" +checksum = "cf8ccec82827413f031689fef4c714fdb0213d58c7a6e208d33f5eab80483770" dependencies = [ "frame-benchmarking", "frame-support", @@ -7496,9 +8003,9 @@ dependencies = [ [[package]] name = "pallet-multisig" -version = "29.0.0" +version = "36.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "176f6a5c170185f892a047c0ae189bc52eb390f2c0b94d4261ed0ebc7f82a548" +checksum = "be58483d827602eb8353ecf36aed65c857f0974db5d27981831e5ebf853040bd" dependencies = [ "frame-benchmarking", "frame-support", @@ -7513,9 +8020,9 @@ dependencies = [ [[package]] name = "pallet-nft-fractionalization" -version = "11.0.0" +version = "18.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4225c31beb3a10235dd165c78f340c344ee78f6ebccd7c99d62a71fb76d2e39" +checksum = "7dcaa330221f60feaf3b23d495cccc3bf2a3d6254c596b3c032273c2b46d4078" dependencies = [ "frame-benchmarking", "frame-support", @@ -7531,9 +8038,9 @@ dependencies = [ [[package]] name = "pallet-nfts" -version = "23.0.0" +version = "30.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3a8978bd9c43ac5ebaa7a26e5bd0c130b037d7cde97189e1a62fa64e5ee1ef1" +checksum = "3e1cd476809de3840e19091a083d5a79178af1f108ad489706e1f9e04c8836a4" dependencies = [ "enumflags2", "frame-benchmarking", @@ -7550,9 +8057,9 @@ dependencies = [ [[package]] name = "pallet-nfts-runtime-api" -version = "15.0.0" +version = "22.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c412ca82207d43e651ef80a3be837220b82ad0d6c3174922c369ef301ea0e5af" +checksum = "b0ca7a0446d2d3c27f726a016c6366218df2e0bfef9ed35886b252cfa9757f6c" dependencies = [ "pallet-nfts", "parity-scale-codec", @@ -7562,9 +8069,9 @@ dependencies = [ [[package]] name = "pallet-nis" -version = "29.0.0" +version = "36.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32a64a0e80dec2c60d5962dd249061a47dc4356db440f26cdec50b8acaded1d3" +checksum = "e77cba0e15749c8de2be65efffa51e02bd051b4e6fcf23360d43c3b6a859187c" dependencies = [ "frame-benchmarking", "frame-support", @@ -7579,9 +8086,9 @@ dependencies = [ [[package]] name = "pallet-nomination-pools" -version = "26.0.1" +version = "33.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b62091305ec7426e71c3da2b0944c2df5a804109ee4d2e8f4fe34865e049f8ac" +checksum = "36f8c994eb7298a394b58f98afd520b521b5d46f6f39eade4657eeaac9962471" dependencies = [ "frame-support", "frame-system", @@ -7599,15 +8106,16 @@ dependencies = [ [[package]] name = "pallet-nomination-pools-benchmarking" -version = "27.0.0" +version = "34.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18a1eba3078e2492cad15e4695f90eb3fc570386d9f71f8b81f709c7123fc6b5" +checksum = "39ee599f2861e55fc6113c01e9b14d6e85fda46bac36a906b5dd5a951fa0455c" dependencies = [ "frame-benchmarking", "frame-election-provider-support", "frame-support", "frame-system", "pallet-bags-list", + "pallet-delegated-staking", "pallet-nomination-pools", "pallet-staking", "parity-scale-codec", @@ -7620,9 +8128,9 @@ dependencies = [ [[package]] name = "pallet-nomination-pools-runtime-api" -version = "24.0.0" +version = "31.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc5b35e6c471a669437b987ff02e11e2283412c9ebaeec5334dec3f73bcea652" +checksum = "2906899d8f029780f0d9da77b90ae86f42bcfda5ac402c931406cd84852012ed" dependencies = [ "pallet-nomination-pools", "parity-scale-codec", @@ -7632,9 +8140,9 @@ dependencies = [ [[package]] name = "pallet-offences" -version = "28.0.0" +version = "35.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60b5bcfdc4f6032d7570929094fd459de12d840c440c395fb4d365d679e13eda" +checksum = "4859e7bb2af46d2e0f137c2f777adf39f0e5d4d188226158d599f1cfcfb76b9e" dependencies = [ "frame-support", "frame-system", @@ -7650,9 +8158,9 @@ dependencies = [ [[package]] name = "pallet-offences-benchmarking" -version = "29.0.0" +version = "36.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbc33e3086c19235cb903cbbbde1bc1c4f428519ad4c23446dc84c75d0061582" +checksum = "4351b0edafcdf3240f0471c638b39d2c981bde9d17c0172536a0aa3b7c3097ef" dependencies = [ "frame-benchmarking", "frame-election-provider-support", @@ -7673,11 +8181,30 @@ dependencies = [ "sp-std", ] +[[package]] +name = "pallet-parameters" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58d9a81a93202105a660e6aa3d3f81638bdd109ca0497f3e528529cd52d034db" +dependencies = [ + "docify", + "frame-benchmarking", + "frame-support", + "frame-system", + "parity-scale-codec", + "paste", + "scale-info", + "serde", + "sp-core", + "sp-runtime", + "sp-std", +] + [[package]] name = "pallet-preimage" -version = "29.0.0" +version = "36.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7344a30c304771beb90aec34604100185e47cdc0366e268ad18922de602a0c7e" +checksum = "68ac726abc5b1bcd6c8f783514b8e1a48be32c7d15e0b263e4bc28cc1e4e7763" dependencies = [ "frame-benchmarking", "frame-support", @@ -7693,9 +8220,9 @@ dependencies = [ [[package]] name = "pallet-proxy" -version = "29.0.0" +version = "36.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7aa31a0b91e8060b808c3e3407e4578a5e94503b174b9e99769147b24fb2c56" +checksum = "b4e12680e176607815a78a0cd10a52af50790292cb950404f30a885e2a7229e9" dependencies = [ "frame-benchmarking", "frame-support", @@ -7709,9 +8236,9 @@ dependencies = [ [[package]] name = "pallet-ranked-collective" -version = "29.0.0" +version = "36.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3733dbfc44d8f5e1a08287a9064e5794e9d0e92b1bd68cdad2e22202b1964528" +checksum = "862ea8d386ed5737e859470c43cbfd9652c81398cad29e03ae7846c21aaee4c6" dependencies = [ "frame-benchmarking", "frame-support", @@ -7729,9 +8256,9 @@ dependencies = [ [[package]] name = "pallet-recovery" -version = "29.0.0" +version = "36.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "797b554ddc87082c18223440d61a81cf35ccab6573321ce473a099e7a709a760" +checksum = "b24d4131bc79fee0b07550136ca6329faa84c1c3e76ae62a74aef6b1da0b95b4" dependencies = [ "frame-benchmarking", "frame-support", @@ -7745,9 +8272,9 @@ dependencies = [ [[package]] name = "pallet-referenda" -version = "29.0.0" +version = "36.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da850889e7101b63cadb980b7f39df67feb6d63bc6092769b9b708e9eb596db1" +checksum = "b2c906a9c4573eb58de4134ec7180bf12c6769df2b9859dae8adcbc5fce78add" dependencies = [ "assert_matches", "frame-benchmarking", @@ -7765,9 +8292,9 @@ dependencies = [ [[package]] name = "pallet-root-testing" -version = "5.0.0" +version = "12.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59171cbf2b823c13685b1b80dd3e1e84425680ff4e006d8016f8c14d2ec44974" +checksum = "fa61642f7bdc1a393798aa1ff67bb8c29f8f184b6fce165e1079010d446a1e29" dependencies = [ "frame-support", "frame-system", @@ -7781,9 +8308,9 @@ dependencies = [ [[package]] name = "pallet-scheduler" -version = "30.0.0" +version = "37.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45e2a4ebe6a5f98b14a26deed8d7a1ea28bb2c2d3ad4d6dc129a725523a2042d" +checksum = "b170d6aa191197d3f50b1193925546972ffc394376ead4d2739eb40909b73c85" dependencies = [ "docify", "frame-benchmarking", @@ -7800,9 +8327,9 @@ dependencies = [ [[package]] name = "pallet-session" -version = "29.0.0" +version = "36.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7412ac59247b300feee53709f7009a23d1c6f8c70528599f48f44e102d896d03" +checksum = "7c92b24c911c2cfa5351616edc7f2f93427ea6f4f95efdb13f0f5d51997939c3" dependencies = [ "frame-support", "frame-system", @@ -7823,9 +8350,9 @@ dependencies = [ [[package]] name = "pallet-session-benchmarking" -version = "29.0.0" +version = "36.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9c2731415381020db1e78db8b40207f8423a16099e78f2fde599cbcb57ea8db" +checksum = "bd02aaf5f10734670346677042ece94fae20dcd5436eafeb9b429d8d6d5b6385" dependencies = [ "frame-benchmarking", "frame-support", @@ -7841,16 +8368,16 @@ dependencies = [ [[package]] name = "pallet-society" -version = "29.0.0" +version = "36.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dba64f96619c25ae7a0b41f4a5111c2d3102e8b8c6cbce80ece6955e825f9de2" +checksum = "66b60b1d726532317f9965bab4995aa49b73f9b7ca3b9a0f75d158bd84686c5f" dependencies = [ "frame-benchmarking", "frame-support", "frame-system", "log", "parity-scale-codec", - "rand_chacha 0.2.2", + "rand_chacha", "scale-info", "sp-arithmetic", "sp-io", @@ -7860,9 +8387,9 @@ dependencies = [ [[package]] name = "pallet-staking" -version = "29.0.3" +version = "36.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "061b00814eb794a40df4eca7972a7c67b26473cd85cc7c54f5816ae49ad6e11b" +checksum = "fbebdb060417654f215fc6f03675e5f44cfc83837d9e523e1b8fd9a4a2e1bdc2" dependencies = [ "frame-benchmarking", "frame-election-provider-support", @@ -7872,7 +8399,7 @@ dependencies = [ "pallet-authorship", "pallet-session", "parity-scale-codec", - "rand_chacha 0.2.2", + "rand_chacha", "scale-info", "serde", "sp-application-crypto", @@ -7884,9 +8411,9 @@ dependencies = [ [[package]] name = "pallet-staking-reward-curve" -version = "11.0.0" +version = "12.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "efca5a4a423427d2c83af5fe07ab648c16b91e3782c3cc23316fe0bd96b4c794" +checksum = "db5e6b1d8ee9d3f6894c5abd8c3e17737ed738c9854f87bfd16239741b7f4d5d" dependencies = [ "proc-macro-crate 3.1.0", "proc-macro2", @@ -7896,9 +8423,9 @@ dependencies = [ [[package]] name = "pallet-staking-reward-fn" -version = "20.0.0" +version = "22.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "505d45e08bad052f55fb51f00a6b6244d23ee46ffdc8091f6cddf4e3a880319d" +checksum = "988a7ebeacc84d4bdb0b12409681e956ffe35438447d8f8bc78db547cffb6ebc" dependencies = [ "log", "sp-arithmetic", @@ -7906,9 +8433,9 @@ dependencies = [ [[package]] name = "pallet-staking-runtime-api" -version = "15.0.1" +version = "21.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e47c73850103db30b61ef170107afe1ef0dab6905c495bd6dfb57b3c1dd81bc7" +checksum = "3350ef1795b832f4adc464e88fb6d44827bd3f98701b0b0bbee495267b444a92" dependencies = [ "parity-scale-codec", "sp-api", @@ -7917,9 +8444,9 @@ dependencies = [ [[package]] name = "pallet-state-trie-migration" -version = "30.0.0" +version = "37.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d76e52dedc146b7a9c3b7c5a6ff4c4c442a8ab8cc58ec30e90e1e98cdc51ad34" +checksum = "e07f8626f4ff62ac79d6ad0bd01fab7645897ce35706ddb95fa084e75be9306d" dependencies = [ "frame-benchmarking", "frame-support", @@ -7935,9 +8462,9 @@ dependencies = [ [[package]] name = "pallet-sudo" -version = "29.0.0" +version = "36.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6d02f7855d411913e77e57126f4a8b8a32d90d9bf47d0b747e367a1301729c3" +checksum = "1bd2a8797c1bb3d3897b4f87a7716111da5eeb8561345277b6e6d70349ec8b35" dependencies = [ "docify", "frame-benchmarking", @@ -7952,9 +8479,9 @@ dependencies = [ [[package]] name = "pallet-timestamp" -version = "28.0.0" +version = "35.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1b8810ddfb254c7fb8cd7698229cce513d309a43ff117b38798dae6120f477b" +checksum = "ae789d344be857679b0b98b28a67c747119724847f81d704d3fd03ee13fb6841" dependencies = [ "docify", "frame-benchmarking", @@ -7973,9 +8500,9 @@ dependencies = [ [[package]] name = "pallet-tips" -version = "28.0.0" +version = "35.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ca4b9921c9e9b59e8eeb64677ba6ec49743ef5fe98e0b63f77411b2b9f6cc99" +checksum = "f7dfec7872ee9e071209ae860094569745e8bd47564bacdba739256ee52cf78c" dependencies = [ "frame-benchmarking", "frame-support", @@ -7993,9 +8520,9 @@ dependencies = [ [[package]] name = "pallet-transaction-payment" -version = "29.0.2" +version = "36.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a5ba71f06f09e955b80dc313c333be3f8d9e8505b051558e0b7af4806b13310" +checksum = "74fb6114223c8d967c3c2f21cbc845e8ea604ff7e21a8e59d119d5a9257ba886" dependencies = [ "frame-support", "frame-system", @@ -8010,9 +8537,9 @@ dependencies = [ [[package]] name = "pallet-transaction-payment-rpc" -version = "31.0.0" +version = "38.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08ef209d2d5d077e325bf49b024fd2eff109a5c2ca0d84ce0d50a65839e6b026" +checksum = "a82898085607c7b00ef20fdce7c621790bf2b644c134918a172fe0a8f7f08e6c" dependencies = [ "jsonrpsee", "pallet-transaction-payment-rpc-runtime-api", @@ -8027,9 +8554,9 @@ dependencies = [ [[package]] name = "pallet-transaction-payment-rpc-runtime-api" -version = "29.0.0" +version = "36.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c78bcba80c7c61712b98a6b5640975ebd25ceb688c18e975af78a0fac81785b0" +checksum = "f4bad1700ad7eb5ab254189e1df894d1d16b3626a3c4b9c45259ec4d9efc262c" dependencies = [ "pallet-transaction-payment", "parity-scale-codec", @@ -8040,9 +8567,9 @@ dependencies = [ [[package]] name = "pallet-treasury" -version = "28.0.1" +version = "35.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3eca44990d0d759213744f2d1f6fe1fadec1079a3e4e4da40556d6b4e42abbcd" +checksum = "9c502615bb4fdd02856a131cb2a612ad40c26435ec938f65f11cae4ff230812b" dependencies = [ "docify", "frame-benchmarking", @@ -8060,9 +8587,9 @@ dependencies = [ [[package]] name = "pallet-uniques" -version = "29.0.0" +version = "36.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac9449d6e2cdcc4456466eff97a065c43dde678620551f5fd79072dec3b9f560" +checksum = "4a59e8599a8c19908e934645f845b5cb546cef1f08745319db7e5b9c24f9e0e4" dependencies = [ "frame-benchmarking", "frame-support", @@ -8076,9 +8603,9 @@ dependencies = [ [[package]] name = "pallet-utility" -version = "29.0.0" +version = "36.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "954f15b98c3fdebb763bb5cea4ec6803fd180d540ec5b07a9fcb2c118251d52c" +checksum = "3238fe6ad00da6a137be115904c39cab97eb5c7f03da0bb1a20de1bef03f0c71" dependencies = [ "frame-benchmarking", "frame-support", @@ -8093,9 +8620,9 @@ dependencies = [ [[package]] name = "pallet-vesting" -version = "29.0.0" +version = "36.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4525f3038cdf078fea39d913c563ca626f09a615e7724f0c9eac97743c75ff44" +checksum = "78f7f0f4fe5e1d851e85d81e5e73b6f929f0c35af786ce8be9c9e3363717c136" dependencies = [ "frame-benchmarking", "frame-support", @@ -8109,9 +8636,9 @@ dependencies = [ [[package]] name = "pallet-whitelist" -version = "28.0.0" +version = "35.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da0ad4ce05688bdddcdb682cbed2f3edff0ee5349f0b745ebacc27d179582432" +checksum = "3e4f27640279229eb73fde0cb06e98b799305e6b0bc724f4dfbef2001ab4ad00" dependencies = [ "frame-benchmarking", "frame-support", @@ -8125,9 +8652,9 @@ dependencies = [ [[package]] name = "pallet-xcm" -version = "8.0.5" +version = "15.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba9138b04168b07b1aff4a2079f5514753c31dddba40e5fb471b9cda7da27ad6" +checksum = "fe7409458b7fedc5c7d46459da154ccc2dc22a843ce08e8ab6c1743ef5cf972c" dependencies = [ "bounded-collections", "frame-benchmarking", @@ -8145,13 +8672,14 @@ dependencies = [ "staging-xcm", "staging-xcm-builder", "staging-xcm-executor", + "xcm-runtime-apis", ] [[package]] name = "pallet-xcm-benchmarks" -version = "8.0.2" +version = "15.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c10e1c92086ce2069a3d2387d9431f48660b6ec92054c4d0a4e30a9f54e7ad3" +checksum = "2f177a171203cc0bec3cff1bdd5d3b926abfbd0ecf347e044b147194e664f717" dependencies = [ "frame-benchmarking", "frame-support", @@ -8169,9 +8697,9 @@ dependencies = [ [[package]] name = "pallet-xcm-bridge-hub-router" -version = "0.6.0" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd5bd3947da7f031c86904f12b6690bbecd2efa122906a8dd838499150fe4322" +checksum = "f48bd38d4061a51f263f4c08021e66100e16cbda9978fba163d2544637b31dab" dependencies = [ "bp-xcm-bridge-hub-router", "frame-benchmarking", @@ -8189,9 +8717,9 @@ dependencies = [ [[package]] name = "parachains-common" -version = "8.0.1" +version = "15.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "711a4c073e7c83aac7e414ba16c7c641d6d9e22e6d32f9775ff35b2464ffd7ff" +checksum = "9319e656eebdf161666e54a4d8e24f73137f702f01600247f7be650bc4d46167" dependencies = [ "cumulus-primitives-core", "cumulus-primitives-utility", @@ -8221,9 +8749,9 @@ dependencies = [ [[package]] name = "parachains-runtimes-test-utils" -version = "8.0.0" +version = "15.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d295b9c391ce15f68ddcd7b0d428eb2d3338643a4d1f471b3dd8a15538865e17" +checksum = "c778447d2e71a418b083c0458579d0f8d13872f43c63142d9e5157edea000bdd" dependencies = [ "cumulus-pallet-parachain-system", "cumulus-pallet-xcmp-queue", @@ -8235,6 +8763,7 @@ dependencies = [ "pallet-balances", "pallet-collator-selection", "pallet-session", + "pallet-timestamp", "pallet-xcm", "parity-scale-codec", "polkadot-parachain-primitives", @@ -8250,6 +8779,19 @@ dependencies = [ "substrate-wasm-builder", ] +[[package]] +name = "parity-bip39" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e69bf016dc406eff7d53a7d3f7cf1c2e72c82b9088aac1118591e36dd2cd3e9" +dependencies = [ + "bitcoin_hashes 0.13.0", + "rand", + "rand_core", + "serde", + "unicode-normalization", +] + [[package]] name = "parity-bytes" version = "0.1.2" @@ -8304,12 +8846,6 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "parity-send-wrapper" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa9777aa91b8ad9dd5aaa04a9b6bcb02c7f1deb952fca5a66034d5e63afc5c6f" - [[package]] name = "parity-util-mem" version = "0.12.0" @@ -8406,113 +8942,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7924d1d0ad836f665c9065e26d016c673ece3993f30d340068b16f282afc1156" [[package]] -name = "paseo-runtime" -version = "1.2.5" -source = "git+https://github.com/paseo-network/runtimes/?tag=v1.2.5-system-chains#2fa66a19eef96bd2c079385057fab2564d09b751" -dependencies = [ - "binary-merkle-tree", - "frame-benchmarking", - "frame-election-provider-support", - "frame-executive", - "frame-metadata-hash-extension", - "frame-support", - "frame-system", - "frame-system-benchmarking", - "frame-system-rpc-runtime-api", - "frame-try-runtime", - "log", - "pallet-asset-rate", - "pallet-authority-discovery", - "pallet-authorship", - "pallet-babe", - "pallet-bags-list", - "pallet-balances", - "pallet-beefy", - "pallet-beefy-mmr", - "pallet-bounties", - "pallet-child-bounties", - "pallet-conviction-voting", - "pallet-election-provider-multi-phase", - "pallet-election-provider-support-benchmarking", - "pallet-fast-unstake", - "pallet-grandpa", - "pallet-identity", - "pallet-indices", - "pallet-message-queue", - "pallet-mmr", - "pallet-multisig", - "pallet-nomination-pools", - "pallet-nomination-pools-benchmarking", - "pallet-nomination-pools-runtime-api", - "pallet-offences", - "pallet-offences-benchmarking", - "pallet-preimage", - "pallet-proxy", - "pallet-referenda", - "pallet-scheduler", - "pallet-session", - "pallet-session-benchmarking", - "pallet-staking", - "pallet-staking-reward-curve", - "pallet-staking-reward-fn", - "pallet-staking-runtime-api", - "pallet-state-trie-migration", - "pallet-sudo", - "pallet-timestamp", - "pallet-transaction-payment", - "pallet-transaction-payment-rpc-runtime-api", - "pallet-treasury", - "pallet-utility", - "pallet-vesting", - "pallet-whitelist", - "pallet-xcm", - "pallet-xcm-benchmarks", - "parity-scale-codec", - "paseo-runtime-constants", - "polkadot-primitives", - "polkadot-runtime-common", - "polkadot-runtime-parachains", - "scale-info", - "sp-api", - "sp-application-crypto", - "sp-arithmetic", - "sp-authority-discovery", - "sp-block-builder", - "sp-consensus-babe", - "sp-consensus-beefy", - "sp-core", - "sp-debug-derive", - "sp-genesis-builder", - "sp-inherents", - "sp-io", - "sp-npos-elections", - "sp-offchain", - "sp-runtime", - "sp-session", - "sp-staking", - "sp-std", - "sp-storage", - "sp-transaction-pool", - "sp-version", - "staging-xcm", - "staging-xcm-builder", - "staging-xcm-executor", - "substrate-wasm-builder", -] - -[[package]] -name = "paseo-runtime-constants" -version = "1.0.0" -source = "git+https://github.com/paseo-network/runtimes/?tag=v1.2.5-system-chains#2fa66a19eef96bd2c079385057fab2564d09b751" +name = "password-hash" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "346f04948ba92c43e8469c1ee6736c7563d71012b17d40745260fe106aac2166" dependencies = [ - "frame-support", - "polkadot-primitives", - "polkadot-runtime-common", - "smallvec", - "sp-core", - "sp-runtime", - "sp-weights", - "staging-xcm-builder", + "base64ct", + "rand_core", + "subtle 2.5.0", ] [[package]] @@ -8521,15 +8958,6 @@ version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" -[[package]] -name = "pbkdf2" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d95f5254224e617595d2cc3cc73ff0a5eaf2637519e25f03388154e9378b6ffa" -dependencies = [ - "crypto-mac 0.11.1", -] - [[package]] name = "pbkdf2" version = "0.12.2" @@ -8537,6 +8965,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f8ed6a7761f76e3b9f92dfb0a60a6a6477c61024b775147ff0973a02653abaf2" dependencies = [ "digest 0.10.7", + "password-hash", ] [[package]] @@ -8635,12 +9064,6 @@ dependencies = [ "syn 2.0.66", ] -[[package]] -name = "pin-project-lite" -version = "0.1.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "257b64915a082f7811703966789728173279bdebb956b143dbcd23f6f970a777" - [[package]] name = "pin-project-lite" version = "0.2.14" @@ -8682,14 +9105,14 @@ checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" [[package]] name = "polkadot-approval-distribution" -version = "8.0.0" +version = "15.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8cdfa52beecc446ccf733dede1a0089e6396d3df13401004d27c0ce2530816bc" +checksum = "61d39d6552d00ade2d668b8171aa7d6a1f5da4c7ebff402b5a9877b5d1e45b4e" dependencies = [ "bitvec", "futures", "futures-timer", - "itertools 0.10.5", + "itertools 0.11.0", "polkadot-node-jaeger", "polkadot-node-metrics", "polkadot-node-network-protocol", @@ -8703,9 +9126,9 @@ dependencies = [ [[package]] name = "polkadot-availability-bitfield-distribution" -version = "8.0.0" +version = "15.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80ffc856dfbdb31178625760824ae320ddb7dd5694b217f489bd2832b8de15a5" +checksum = "cd0a8b5280959524f84b09c27ef0dbceeced6d19537f8fd43d03a08414f8b93d" dependencies = [ "always-assert", "futures", @@ -8720,9 +9143,9 @@ dependencies = [ [[package]] name = "polkadot-availability-distribution" -version = "8.0.0" +version = "15.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9d05c26cc8d6fa0f5f432d9de880f20ad0d24ca51a618834ea6612d1bd96ab1" +checksum = "adfe520a9c8dbe6c5db06c0b919c53441927babc1c02b9df76718fc4b80c5c4f" dependencies = [ "derive_more", "fatality", @@ -8735,6 +9158,7 @@ dependencies = [ "polkadot-node-subsystem-util", "polkadot-primitives", "rand", + "sc-network", "schnellru", "sp-core", "sp-keystore", @@ -8744,9 +9168,9 @@ dependencies = [ [[package]] name = "polkadot-availability-recovery" -version = "8.0.0" +version = "15.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d77e0b979f43861ab4c78c216c2729644bb12812f9bc859858bd3b8fc56b4d6" +checksum = "727f02306a3a51eb0b8efca3e1e14c5efa2daf921c9be7c46d9c5d68670a9b51" dependencies = [ "async-trait", "fatality", @@ -8766,11 +9190,21 @@ dependencies = [ "tracing-gum", ] +[[package]] +name = "polkadot-ckb-merkle-mountain-range" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4b44320e5f7ce2c18227537a3032ae5b2c476a7e8eddba45333e1011fc31b92" +dependencies = [ + "cfg-if", + "itertools 0.10.5", +] + [[package]] name = "polkadot-cli" -version = "8.0.0" +version = "15.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef362c44280e3883a39ca452acc4a4fb61a18250d634d68578b22df7edd8290c" +checksum = "141a62da626bba7c4a29b8e5d20a975efa6439095a352ebfc47f068e4dfd82fd" dependencies = [ "cfg-if", "clap", @@ -8790,16 +9224,16 @@ dependencies = [ "sp-io", "sp-keyring", "sp-maybe-compressed-blob", + "sp-runtime", "substrate-build-script-utils", "thiserror", - "try-runtime-cli", ] [[package]] name = "polkadot-collator-protocol" -version = "8.0.0" +version = "15.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "507391f1be9f9b9a8fbf28ca13b0ab3f04947a54a1115d423d115aacf8889bf4" +checksum = "75bd07cc8a0bfabe6464d40072e30bd87f52730fbc26c733f0a8ffa97918c0a8" dependencies = [ "bitvec", "fatality", @@ -8820,9 +9254,9 @@ dependencies = [ [[package]] name = "polkadot-core-primitives" -version = "8.0.0" +version = "14.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6a08e4e014c853b252ecbbe3ccd67b2d33d78e46988d309b8cccf4ac06e25ef" +checksum = "17c72ee63bcf920f963cd7ac066759b0b649350c8ab3781a85a6aac87b1488f2" dependencies = [ "parity-scale-codec", "scale-info", @@ -8833,9 +9267,9 @@ dependencies = [ [[package]] name = "polkadot-dispute-distribution" -version = "8.0.0" +version = "15.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae32e83ef6bc0ec2874c76c19dff8f3795832ccc27f0abc587a7137994c42d26" +checksum = "09c49e68add45aa6c2b85e97f0d09b81f26b1428117bdc9284eaa74a1eb63daf" dependencies = [ "derive_more", "fatality", @@ -8859,9 +9293,9 @@ dependencies = [ [[package]] name = "polkadot-erasure-coding" -version = "8.0.0" +version = "14.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b10514ace3272d38b602e1795a5a340b265285c4af875473d682a5c9d6c831c" +checksum = "6a39a54a269817e09d602b4e9c527905f9e367ff7c6337b1b3e1e048515f6b59" dependencies = [ "parity-scale-codec", "polkadot-node-primitives", @@ -8874,9 +9308,9 @@ dependencies = [ [[package]] name = "polkadot-gossip-support" -version = "8.0.0" +version = "15.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01f05f7f60022d4beb30414f1f7c7e4ae728fea02086a4a0f8ff0a73e73ea4aa" +checksum = "53b56e8fe08e4ed30af0d296870b12b5a7411695f2b79b3c5842d04b9a347200" dependencies = [ "futures", "futures-timer", @@ -8885,7 +9319,7 @@ dependencies = [ "polkadot-node-subsystem-util", "polkadot-primitives", "rand", - "rand_chacha 0.3.1", + "rand_chacha", "sc-network", "sc-network-common", "sp-application-crypto", @@ -8897,9 +9331,9 @@ dependencies = [ [[package]] name = "polkadot-network-bridge" -version = "8.0.0" +version = "15.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "049ec1298ac6e96bcf4d980cd5864aceeee73b3298ab5d6dd7a3193d47578abc" +checksum = "178b92197936c23ae8a936ec74b83a15a9fe0978c7f3de677db141ba9c524a63" dependencies = [ "always-assert", "async-trait", @@ -8921,9 +9355,9 @@ dependencies = [ [[package]] name = "polkadot-node-collation-generation" -version = "8.0.0" +version = "15.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f1211ab8b154c2e2b4b89c64f57f96056c881e4fcfa2ce29b6e5cbc978e74f1" +checksum = "869534f66d5a38443acf4b9fec3a4919f59f293e6fdee4177cd7cece1c4a85ef" dependencies = [ "futures", "parity-scale-codec", @@ -8940,15 +9374,15 @@ dependencies = [ [[package]] name = "polkadot-node-core-approval-voting" -version = "8.0.0" +version = "15.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c61a17b7e4edd3b73afbe0c6e8b5369bf3b721361a232baf11fb1698077067a4" +checksum = "ed3629b2d93b5f152bc75437fb68326ebf9267885ff89f2abede9b8a050e9288" dependencies = [ "bitvec", "derive_more", "futures", "futures-timer", - "itertools 0.10.5", + "itertools 0.11.0", "kvdb", "merlin", "parity-scale-codec", @@ -8959,8 +9393,8 @@ dependencies = [ "polkadot-overseer", "polkadot-primitives", "rand", - "rand_chacha 0.3.1", - "rand_core 0.6.4", + "rand_chacha", + "rand_core", "sc-keystore", "schnellru", "schnorrkel 0.11.4", @@ -8974,9 +9408,9 @@ dependencies = [ [[package]] name = "polkadot-node-core-av-store" -version = "8.0.0" +version = "15.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84b334f06423ff701e4b807d6832741ec24e0e97ebc13b560fc99bc0652926c0" +checksum = "8487c45eedaaf535ccc78bf4f459eae9443c4c9cfcca31dc3838950f3a3426e3" dependencies = [ "bitvec", "futures", @@ -8997,9 +9431,9 @@ dependencies = [ [[package]] name = "polkadot-node-core-backing" -version = "8.0.1" +version = "15.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f07f8840f3f2f0bee6264c18ce471c99c925f9afb65952e1d584b6d773cf4115" +checksum = "b493dff8562ce2675dbb0e5c8594e145085a4536de435f5061f577bdaba2195e" dependencies = [ "bitvec", "fatality", @@ -9018,9 +9452,9 @@ dependencies = [ [[package]] name = "polkadot-node-core-bitfield-signing" -version = "8.0.0" +version = "15.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0687006f843d6da8687eb24da735a04cbdcf4c3a98d82055b9b3a9047537e17e" +checksum = "5946d61086be5096e8dafd731d0881fa41e12f21a1f3a8b9d7ff6f1294914b98" dependencies = [ "futures", "polkadot-node-subsystem", @@ -9034,9 +9468,9 @@ dependencies = [ [[package]] name = "polkadot-node-core-candidate-validation" -version = "8.0.0" +version = "15.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3035acf9069801e980b91b5178591f8a7052b4409de13824db7a6c798b36b98" +checksum = "389b6d8da9a7cf825f97ff4da4ef754a1371de0358e896fbec973f4ff1dfe011" dependencies = [ "async-trait", "futures", @@ -9056,9 +9490,9 @@ dependencies = [ [[package]] name = "polkadot-node-core-chain-api" -version = "8.0.0" +version = "15.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c990b9ffdde6725fe79f55e3b7c4c32ce2134a06103708476fa595a4ac652e95" +checksum = "29086798f24839c9dc1c8b080ffc68bbfe2a5fdc5f29de557b9d224a45011094" dependencies = [ "futures", "polkadot-node-metrics", @@ -9071,9 +9505,9 @@ dependencies = [ [[package]] name = "polkadot-node-core-chain-selection" -version = "8.0.0" +version = "15.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "451965f3ace786d392c407872d61324765061b87027890b02ffd625554531f97" +checksum = "79c8bcae78a4562bc8b3b786e08cb1b3c96c29554da7d57b6806a6723b1540b0" dependencies = [ "futures", "futures-timer", @@ -9089,9 +9523,9 @@ dependencies = [ [[package]] name = "polkadot-node-core-dispute-coordinator" -version = "8.0.0" +version = "15.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c13ea9d5b4aa43b5b1f718c3ec951adff0b0d74909cb1fe28206f5d88492247d" +checksum = "459e1da76e61c2f5636123ae7c19097067dcc1d07e0d5e77eae4eb87e5cb999d" dependencies = [ "fatality", "futures", @@ -9109,9 +9543,9 @@ dependencies = [ [[package]] name = "polkadot-node-core-parachains-inherent" -version = "8.0.0" +version = "15.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6574c0bda4e10d722f761d4b8ab5d1708f0f963e5840370aa9cee8f559c90a23" +checksum = "18e4d2b44748657a68c8ff2995b0b39609f5186bc4b07040ebb6b389dbf1047b" dependencies = [ "async-trait", "futures", @@ -9127,9 +9561,9 @@ dependencies = [ [[package]] name = "polkadot-node-core-prospective-parachains" -version = "7.0.0" +version = "14.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "160f80a11b9d2b8e36e510ea54ce5b06e77179c0c502f7e19e5a5809bc1523ee" +checksum = "756205c36293216422775c6fa1be9fc4bdb99fa5cafd86b96e7feae13e669e79" dependencies = [ "bitvec", "fatality", @@ -9145,9 +9579,9 @@ dependencies = [ [[package]] name = "polkadot-node-core-provisioner" -version = "8.0.1" +version = "15.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0d0a64371700537c3dc15b3956536e4541f093b7c38ac21737ea9fea3562a83" +checksum = "d6f090dc90bbe0b452a57a3129b53a6129e357ff4607e9db27a54b291d7a747b" dependencies = [ "bitvec", "fatality", @@ -9157,24 +9591,23 @@ dependencies = [ "polkadot-node-subsystem", "polkadot-node-subsystem-util", "polkadot-primitives", + "schnellru", "thiserror", "tracing-gum", ] [[package]] name = "polkadot-node-core-pvf" -version = "8.0.0" +version = "15.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3bbb1b5f4b966f21a0336e94c0a0222958d2f3cba451da1157af271d07f9748" +checksum = "2eea57cb8ce66c2952b87b2476b46d6316ae58342f198abd09c391827ed5402d" dependencies = [ "always-assert", - "array-bytes 6.2.3", + "array-bytes", "blake3", "cfg-if", "futures", "futures-timer", - "is_executable", - "libc", "parity-scale-codec", "pin-project", "polkadot-core-primitives", @@ -9187,8 +9620,6 @@ dependencies = [ "rand", "slotmap", "sp-core", - "sp-maybe-compressed-blob", - "sp-wasm-interface", "tempfile", "thiserror", "tokio", @@ -9197,9 +9628,9 @@ dependencies = [ [[package]] name = "polkadot-node-core-pvf-checker" -version = "8.0.0" +version = "15.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94ab4a91e62a9f7e67cf400931578f2505417cc43a32ac29458163604f2b277b" +checksum = "6483e6db611d96b14deb298bcf877c44905ba2b45207183d62d0fda9c2fcfec2" dependencies = [ "futures", "polkadot-node-primitives", @@ -9214,16 +9645,15 @@ dependencies = [ [[package]] name = "polkadot-node-core-pvf-common" -version = "8.0.0" +version = "14.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "003981d3b63e4f527ef7f03cbe280e41ec649d9be365668887f0b107610640f4" +checksum = "d0eca24abc74c0c3f02f9986edbda12b3e8b6d294c39b238cf39e94e246aa2b9" dependencies = [ - "cfg-if", "cpu-time", "futures", "landlock", "libc", - "nix 0.27.1", + "nix 0.28.0", "parity-scale-codec", "polkadot-parachain-primitives", "polkadot-primitives", @@ -9242,9 +9672,9 @@ dependencies = [ [[package]] name = "polkadot-node-core-runtime-api" -version = "8.0.0" +version = "15.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ba6ea6a03f297b7387fc59c41c3c32285803971cb27e81d7e9ca696824d6773" +checksum = "0024b2f4e4a03e4fda348183bbfe5eb51dd6e90b57eabc83596ee4d0079fd0e8" dependencies = [ "futures", "polkadot-node-metrics", @@ -9258,9 +9688,9 @@ dependencies = [ [[package]] name = "polkadot-node-jaeger" -version = "8.0.0" +version = "15.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7d113b48e7b6126964c3a790b101d99e17fd3cb75a92e94d54587ce1340df21" +checksum = "b671c3407a7e325264af798664ca60c985873c04f54f53cc8f02aa81512fd40a" dependencies = [ "lazy_static", "log", @@ -9270,6 +9700,7 @@ dependencies = [ "polkadot-node-primitives", "polkadot-primitives", "sc-network", + "sc-network-types", "sp-core", "thiserror", "tokio", @@ -9277,9 +9708,9 @@ dependencies = [ [[package]] name = "polkadot-node-metrics" -version = "8.0.0" +version = "15.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aef2e2a934f0d0d606fcfc53fc26f4cacd8b9f18fb2118829203fa813af2cdae" +checksum = "bae429c6a40f782a615d7ec863c4eda83c36bee5f6b542bcf86f754342f97b5a" dependencies = [ "bs58 0.5.1", "futures", @@ -9297,9 +9728,9 @@ dependencies = [ [[package]] name = "polkadot-node-network-protocol" -version = "8.0.0" +version = "15.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07f9e67b0f25d695947a15b6fe8ee6f8e83f3dfcbca124a13281c0edd0dc4703" +checksum = "cf88dcc39ac21e12a65c255707b89933ddf3dadfb2c422d9f0fd8ff644229e77" dependencies = [ "async-channel 1.9.0", "async-trait", @@ -9315,16 +9746,18 @@ dependencies = [ "rand", "sc-authority-discovery", "sc-network", - "strum 0.24.1", + "sc-network-types", + "sp-runtime", + "strum 0.26.2", "thiserror", "tracing-gum", ] [[package]] name = "polkadot-node-primitives" -version = "8.0.0" +version = "14.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "375744eee7a53576387e14856e1c65be8ecef8b449567bb2cff85706266c8912" +checksum = "779833f70a1563ed042d3c6b831a45c5ea0f80caa8f4ede487f7bee3130168fb" dependencies = [ "bitvec", "bounded-vec", @@ -9346,9 +9779,9 @@ dependencies = [ [[package]] name = "polkadot-node-subsystem" -version = "8.0.0" +version = "15.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24d6c226cdbcd48ab1e506d8512f0fb01839f9a72eec2fc0cf7771f6d3352171" +checksum = "6a338e574c2416135b0004ebef226be22db13c44532e2a0f33b67648afb3ca12" dependencies = [ "polkadot-node-jaeger", "polkadot-node-subsystem-types", @@ -9357,13 +9790,14 @@ dependencies = [ [[package]] name = "polkadot-node-subsystem-types" -version = "8.0.0" +version = "15.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1404525da0ab9d44bac1041449bf0c5576240f9031b305dc41654567e98b6021" +checksum = "b0df39c7eef657b1e28917529f0b0c2aa5f0b013f4f298cfb3620b54449f0c95" dependencies = [ "async-trait", "bitvec", "derive_more", + "fatality", "futures", "orchestra", "polkadot-node-jaeger", @@ -9373,6 +9807,7 @@ dependencies = [ "polkadot-statement-table", "sc-client-api", "sc-network", + "sc-network-types", "sc-transaction-pool-api", "smallvec", "sp-api", @@ -9386,21 +9821,22 @@ dependencies = [ [[package]] name = "polkadot-node-subsystem-util" -version = "8.0.0" +version = "15.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65a7d101f28bf718d15f01a060ed8cf7a7e2d8d5705c494b49ece696cada0adf" +checksum = "a55a268e05c8c39aeb81b9ad59dfd18a7a711c8f8fa19bf83c75025de25466b7" dependencies = [ "async-trait", "derive_more", "fatality", "futures", "futures-channel", - "itertools 0.10.5", + "itertools 0.11.0", "kvdb", "parity-db", "parity-scale-codec", "parking_lot 0.12.3", "pin-project", + "polkadot-erasure-coding", "polkadot-node-jaeger", "polkadot-node-metrics", "polkadot-node-network-protocol", @@ -9422,9 +9858,9 @@ dependencies = [ [[package]] name = "polkadot-overseer" -version = "8.0.0" +version = "15.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd5ed988deffeddf440473586f62efc5dd498f6016e6650881db09dd60b3b24f" +checksum = "c2456c1b2d176550e91e2e1ddb092390b00e20898e5c4fd9b5978d56ab1bbf24" dependencies = [ "async-trait", "futures", @@ -9445,9 +9881,9 @@ dependencies = [ [[package]] name = "polkadot-parachain-primitives" -version = "7.0.0" +version = "13.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "248ab090959a92e61493277e33b7e85104280a4beb4cb0815137d3c8c50a07f4" +checksum = "f61070d0ff28f596890def0e0d03c231860796130b2a43e293106fa86a50c9a9" dependencies = [ "bounded-collections", "derive_more", @@ -9463,9 +9899,9 @@ dependencies = [ [[package]] name = "polkadot-primitives" -version = "8.0.1" +version = "14.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0d5f9930210cab0233d81204415c9ef4a8889cdf3e60de1435250481a2773ca" +checksum = "5a4879609f4340138930c3c7313256941104a3ff6f7ecb2569d15223da9b35b2" dependencies = [ "bitvec", "hex-literal", @@ -9491,9 +9927,9 @@ dependencies = [ [[package]] name = "polkadot-rpc" -version = "8.0.0" +version = "15.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb4747cb8faa532e8446b38b74266fd626d6b660fe6b00776dd6c4543cc0457f" +checksum = "0dc80e33ff0a7155588d7b6cadffbbad7e8e489c2275f6f49ce61cb5cdfedca7" dependencies = [ "jsonrpsee", "mmr-rpc", @@ -9513,21 +9949,121 @@ dependencies = [ "sc-sync-state-rpc", "sc-transaction-pool-api", "sp-api", + "sp-application-crypto", "sp-block-builder", "sp-blockchain", "sp-consensus", "sp-consensus-babe", + "sp-consensus-beefy", "sp-keystore", "sp-runtime", "substrate-frame-rpc-system", "substrate-state-trie-migration-rpc", ] +[[package]] +name = "polkadot-runtime" +version = "1.0.0" +source = "git+https://github.com/polkadot-fellows/runtimes#f42acab60edf4d6ded4d9e99b1a8fbacded85669" +dependencies = [ + "binary-merkle-tree", + "frame-benchmarking", + "frame-election-provider-support", + "frame-executive", + "frame-metadata-hash-extension", + "frame-support", + "frame-system", + "frame-system-benchmarking", + "frame-system-rpc-runtime-api", + "frame-try-runtime", + "log", + "pallet-asset-rate", + "pallet-authority-discovery", + "pallet-authorship", + "pallet-babe", + "pallet-bags-list", + "pallet-balances", + "pallet-beefy", + "pallet-beefy-mmr", + "pallet-bounties", + "pallet-broker", + "pallet-child-bounties", + "pallet-conviction-voting", + "pallet-election-provider-multi-phase", + "pallet-election-provider-support-benchmarking", + "pallet-fast-unstake", + "pallet-grandpa", + "pallet-im-online", + "pallet-indices", + "pallet-message-queue", + "pallet-mmr", + "pallet-multisig", + "pallet-nomination-pools", + "pallet-nomination-pools-benchmarking", + "pallet-nomination-pools-runtime-api", + "pallet-offences", + "pallet-offences-benchmarking", + "pallet-preimage", + "pallet-proxy", + "pallet-referenda", + "pallet-scheduler", + "pallet-session", + "pallet-session-benchmarking", + "pallet-staking", + "pallet-staking-reward-curve", + "pallet-staking-reward-fn", + "pallet-staking-runtime-api", + "pallet-state-trie-migration", + "pallet-timestamp", + "pallet-transaction-payment", + "pallet-transaction-payment-rpc-runtime-api", + "pallet-treasury", + "pallet-utility", + "pallet-vesting", + "pallet-whitelist", + "pallet-xcm", + "pallet-xcm-benchmarks", + "parity-scale-codec", + "polkadot-parachain-primitives", + "polkadot-primitives", + "polkadot-runtime-common", + "polkadot-runtime-constants", + "polkadot-runtime-parachains", + "scale-info", + "serde_json", + "sp-api", + "sp-application-crypto", + "sp-arithmetic", + "sp-authority-discovery", + "sp-block-builder", + "sp-consensus-babe", + "sp-consensus-beefy", + "sp-core", + "sp-debug-derive", + "sp-genesis-builder", + "sp-inherents", + "sp-io", + "sp-npos-elections", + "sp-offchain", + "sp-runtime", + "sp-session", + "sp-staking", + "sp-std", + "sp-storage", + "sp-transaction-pool", + "sp-version", + "staging-xcm", + "staging-xcm-builder", + "staging-xcm-executor", + "substrate-wasm-builder", + "xcm-runtime-apis", +] + [[package]] name = "polkadot-runtime-common" -version = "8.0.3" +version = "15.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12a70422ca43d30457e2d9502a5e4af35e20fa2ff3f7cd46e0d2997c784f2665" +checksum = "28fdcb41bb21c7b14d0341a9a17364ccc04ad34de05d41e7938cb03acbc11066" dependencies = [ "bitvec", "frame-benchmarking", @@ -9575,11 +10111,26 @@ dependencies = [ "static_assertions", ] +[[package]] +name = "polkadot-runtime-constants" +version = "1.0.0" +source = "git+https://github.com/polkadot-fellows/runtimes#f42acab60edf4d6ded4d9e99b1a8fbacded85669" +dependencies = [ + "frame-support", + "polkadot-primitives", + "polkadot-runtime-common", + "smallvec", + "sp-core", + "sp-runtime", + "sp-weights", + "staging-xcm-builder", +] + [[package]] name = "polkadot-runtime-metrics" -version = "8.0.0" +version = "15.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3566c6fd0c21b5dd555309427c984cf506f875ee90f710acea295b478fecbe0" +checksum = "ac75b3fea8464e5681b44733ed11cf09e22ff1e956f6703b918b637bd40e7427" dependencies = [ "bs58 0.5.1", "frame-benchmarking", @@ -9591,9 +10142,9 @@ dependencies = [ [[package]] name = "polkadot-runtime-parachains" -version = "8.0.3" +version = "15.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8d37cd3e014b06daf396d1483b5327782a0ebadc816423419665166b75b3e3e" +checksum = "cb7e68cb26f9025daaad694d8192fd0e63e92c8761c45a339dd7a5b7925a3cb6" dependencies = [ "bitflags 1.3.2", "bitvec", @@ -9619,8 +10170,7 @@ dependencies = [ "polkadot-primitives", "polkadot-runtime-metrics", "rand", - "rand_chacha 0.3.1", - "rustc-hex", + "rand_chacha", "scale-info", "serde", "sp-api", @@ -9641,9 +10191,9 @@ dependencies = [ [[package]] name = "polkadot-service" -version = "8.0.0" +version = "15.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2fd665185877bec296588c7cf1ec0ef75e0545050b5e1d42d94240a284149da" +checksum = "fa560fb67981865b895082845c4ec43fabb206da5bf583ec5ef3561a8e3fc333" dependencies = [ "async-trait", "frame-benchmarking", @@ -9659,7 +10209,6 @@ dependencies = [ "log", "mmr-gadget", "pallet-babe", - "pallet-im-online", "pallet-staking", "pallet-transaction-payment", "pallet-transaction-payment-rpc-runtime-api", @@ -9751,17 +10300,19 @@ dependencies = [ "sp-transaction-pool", "sp-version", "sp-weights", + "staging-xcm", "substrate-prometheus-endpoint", "thiserror", "tracing-gum", "westend-runtime", + "xcm-runtime-apis", ] [[package]] name = "polkadot-statement-distribution" -version = "8.0.0" +version = "15.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ff6d16cbd994987f48a9f107f12e4c7fff26cdd71df6288e9521adc7cff3427" +checksum = "16020ecadd1826ffbce2693ba1490123a0f7ca74d233c9bc8c0cbfc23bb4df2a" dependencies = [ "arrayvec 0.7.4", "bitvec", @@ -9783,9 +10334,9 @@ dependencies = [ [[package]] name = "polkadot-statement-table" -version = "8.0.1" +version = "14.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de5e010da3c6a65d8f263d0f825a04d995ffc8a37f886f674fcbbc73bf158d01" +checksum = "947e9e3c8f71b9678f39a01f371a808b574823967dd9da187e6f886f5f08691c" dependencies = [ "parity-scale-codec", "polkadot-primitives", @@ -9793,27 +10344,51 @@ dependencies = [ "tracing-gum", ] +[[package]] +name = "polkavm" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a3693e5efdb2bf74e449cd25fd777a28bd7ed87e41f5d5da75eb31b4de48b94" +dependencies = [ + "libc", + "log", + "polkavm-assembler", + "polkavm-common", + "polkavm-linux-raw", +] + +[[package]] +name = "polkavm-assembler" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fa96d6d868243acc12de813dd48e756cbadcc8e13964c70d272753266deadc1" +dependencies = [ + "log", +] + [[package]] name = "polkavm-common" -version = "0.5.0" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88b4e215c80fe876147f3d58158d5dfeae7dabdd6047e175af77095b78d0035c" +checksum = "1d9428a5cfcc85c5d7b9fc4b6a18c4b802d0173d768182a51cc7751640f08b92" +dependencies = [ + "log", +] [[package]] name = "polkavm-derive" -version = "0.5.0" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6380dbe1fb03ecc74ad55d841cfc75480222d153ba69ddcb00977866cbdabdb8" +checksum = "ae8c4bea6f3e11cd89bb18bcdddac10bd9a24015399bd1c485ad68a985a19606" dependencies = [ - "polkavm-derive-impl", - "syn 2.0.66", + "polkavm-derive-impl-macro", ] [[package]] name = "polkavm-derive-impl" -version = "0.5.0" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc8211b3365bbafb2fb32057d68b0e1ca55d079f5cf6f9da9b98079b94b3987d" +checksum = "5c4fdfc49717fb9a196e74a5d28e0bc764eb394a2c803eb11133a31ac996c60c" dependencies = [ "polkavm-common", "proc-macro2", @@ -9821,6 +10396,37 @@ dependencies = [ "syn 2.0.66", ] +[[package]] +name = "polkavm-derive-impl-macro" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ba81f7b5faac81e528eb6158a6f3c9e0bb1008e0ffa19653bc8dea925ecb429" +dependencies = [ + "polkavm-derive-impl", + "syn 2.0.66", +] + +[[package]] +name = "polkavm-linker" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c7be503e60cf56c0eb785f90aaba4b583b36bff00e93997d93fef97f9553c39" +dependencies = [ + "gimli 0.28.1", + "hashbrown 0.14.5", + "log", + "object 0.32.2", + "polkavm-common", + "regalloc2 0.9.3", + "rustc-demangle", +] + +[[package]] +name = "polkavm-linux-raw" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26e85d3456948e650dff0cfc85603915847faf893ed1e66b020bb82ef4557120" + [[package]] name = "polling" version = "2.8.0" @@ -9833,7 +10439,7 @@ dependencies = [ "concurrent-queue", "libc", "log", - "pin-project-lite 0.2.14", + "pin-project-lite", "windows-sys 0.48.0", ] @@ -9846,7 +10452,7 @@ dependencies = [ "cfg-if", "concurrent-queue", "hermit-abi 0.4.0", - "pin-project-lite 0.2.14", + "pin-project-lite", "rustix 0.38.34", "tracing", "windows-sys 0.52.0", @@ -9899,7 +10505,7 @@ dependencies = [ [[package]] name = "pop-node" -version = "0.1.0-alpha" +version = "0.2.0-alpha" dependencies = [ "clap", "color-print", @@ -9918,12 +10524,14 @@ dependencies = [ "futures", "jsonrpsee", "log", + "pallet-multisig", "pallet-transaction-payment-rpc", "parity-scale-codec", "polkadot-cli", "polkadot-primitives", "pop-runtime-common", "pop-runtime-devnet", + "pop-runtime-mainnet", "pop-runtime-testnet", "sc-basic-authorship", "sc-chain-spec", @@ -9993,10 +10601,13 @@ dependencies = [ "cumulus-pallet-xcmp-queue", "cumulus-primitives-aura", "cumulus-primitives-core", + "cumulus-primitives-storage-weight-reclaim", "cumulus-primitives-utility", + "enumflags2", "env_logger 0.11.5", "frame-benchmarking", "frame-executive", + "frame-metadata-hash-extension", "frame-support", "frame-system", "frame-system-benchmarking", @@ -10056,9 +10667,76 @@ dependencies = [ "substrate-wasm-builder", ] +[[package]] +name = "pop-runtime-mainnet" +version = "0.1.0" +dependencies = [ + "cumulus-pallet-aura-ext", + "cumulus-pallet-parachain-system", + "cumulus-pallet-session-benchmarking", + "cumulus-pallet-xcm", + "cumulus-pallet-xcmp-queue", + "cumulus-primitives-aura", + "cumulus-primitives-core", + "cumulus-primitives-storage-weight-reclaim", + "cumulus-primitives-utility", + "enumflags2", + "env_logger 0.11.5", + "frame-benchmarking", + "frame-executive", + "frame-metadata-hash-extension", + "frame-support", + "frame-system", + "frame-system-benchmarking", + "frame-system-rpc-runtime-api", + "frame-try-runtime", + "hex", + "pallet-aura", + "pallet-authorship", + "pallet-balances", + "pallet-collator-selection", + "pallet-message-queue", + "pallet-multisig", + "pallet-preimage", + "pallet-proxy", + "pallet-scheduler", + "pallet-session", + "pallet-sudo", + "pallet-timestamp", + "pallet-transaction-payment", + "pallet-transaction-payment-rpc-runtime-api", + "pallet-utility", + "pallet-xcm", + "parachains-common", + "parity-scale-codec", + "polkadot-parachain-primitives", + "polkadot-runtime-common", + "pop-runtime-common", + "scale-info", + "smallvec", + "sp-api", + "sp-block-builder", + "sp-consensus-aura", + "sp-core", + "sp-genesis-builder", + "sp-inherents", + "sp-io", + "sp-offchain", + "sp-runtime", + "sp-session", + "sp-std", + "sp-transaction-pool", + "sp-version", + "staging-parachain-info", + "staging-xcm", + "staging-xcm-builder", + "staging-xcm-executor", + "substrate-wasm-builder", +] + [[package]] name = "pop-runtime-testnet" -version = "0.2.0" +version = "0.4.1" dependencies = [ "cumulus-pallet-aura-ext", "cumulus-pallet-parachain-system", @@ -10067,10 +10745,13 @@ dependencies = [ "cumulus-pallet-xcmp-queue", "cumulus-primitives-aura", "cumulus-primitives-core", + "cumulus-primitives-storage-weight-reclaim", "cumulus-primitives-utility", + "enumflags2", "env_logger 0.11.5", "frame-benchmarking", "frame-executive", + "frame-metadata-hash-extension", "frame-support", "frame-system", "frame-system-benchmarking", @@ -10160,6 +10841,16 @@ dependencies = [ "regex", ] +[[package]] +name = "predicates" +version = "3.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e9086cc7640c29a356d1a29fd134380bee9d8f79a17410aa76e7ad295f42c97" +dependencies = [ + "anstyle", + "predicates-core", +] + [[package]] name = "predicates-core" version = "1.0.6" @@ -10237,15 +10928,6 @@ dependencies = [ "toml 0.5.11", ] -[[package]] -name = "proc-macro-crate" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e8366a6159044a37876a2b9817124296703c586a5c92e2c53751fa06d8d43e8" -dependencies = [ - "toml_edit 0.20.7", -] - [[package]] name = "proc-macro-crate" version = "3.1.0" @@ -10279,6 +10961,17 @@ dependencies = [ "version_check", ] +[[package]] +name = "proc-macro-warning" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d1eaa7fa0aa1929ffdf7eeb6eac234dde6268914a14ad44d23521ab6a9b258e" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.66", +] + [[package]] name = "proc-macro-warning" version = "1.0.2" @@ -10315,9 +11008,9 @@ dependencies = [ [[package]] name = "prometheus-client" -version = "0.19.0" +version = "0.21.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d6fa99d535dd930d1249e6c79cb3c2915f9172a540fe2b02a4c8f9ca954721e" +checksum = "3c99afa9a01501019ac3a14d71d9f94050346f55ca471ce90c799a15c58f61e2" dependencies = [ "dtoa", "itoa", @@ -10367,17 +11060,38 @@ dependencies = [ "itertools 0.10.5", "lazy_static", "log", - "multimap", + "multimap 0.8.3", "petgraph", "prettyplease 0.1.25", "prost 0.11.9", - "prost-types", + "prost-types 0.11.9", "regex", "syn 1.0.109", "tempfile", "which 4.4.2", ] +[[package]] +name = "prost-build" +version = "0.12.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22505a5c94da8e3b7c2996394d1c933236c4d743e81a410bcca4e6989fc066a4" +dependencies = [ + "bytes", + "heck 0.5.0", + "itertools 0.11.0", + "log", + "multimap 0.10.0", + "once_cell", + "petgraph", + "prettyplease 0.2.20", + "prost 0.12.6", + "prost-types 0.12.6", + "regex", + "syn 2.0.66", + "tempfile", +] + [[package]] name = "prost-derive" version = "0.11.9" @@ -10413,6 +11127,15 @@ dependencies = [ "prost 0.11.9", ] +[[package]] +name = "prost-types" +version = "0.12.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9091c90b0a32608e984ff2fa4091273cbdd755d54935c51d520887f4a1dbd5b0" +dependencies = [ + "prost 0.12.6", +] + [[package]] name = "psm" version = "0.1.21" @@ -10422,6 +11145,21 @@ dependencies = [ "cc", ] +[[package]] +name = "quanta" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e5167a477619228a0b284fac2674e3c388cba90631d7b7de620e6f1fcd08da5" +dependencies = [ + "crossbeam-utils", + "libc", + "once_cell", + "raw-cpuid", + "wasi", + "web-sys", + "winapi", +] + [[package]] name = "quick-error" version = "1.2.3" @@ -10439,44 +11177,112 @@ dependencies = [ [[package]] name = "quick-protobuf-codec" -version = "0.1.0" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1693116345026436eb2f10b677806169c1a1260c1c60eaaffe3fb5a29ae23d8b" +checksum = "f8ededb1cd78531627244d51dd0c7139fbe736c7d57af0092a76f0ffb2f56e98" dependencies = [ "asynchronous-codec", "bytes", "quick-protobuf", "thiserror", - "unsigned-varint", + "unsigned-varint 0.7.2", ] [[package]] -name = "quicksink" -version = "0.1.2" +name = "quinn" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e8b432585672228923edbbf64b8b12c14e1112f62e88737655b4a083dbcd78e" +dependencies = [ + "bytes", + "pin-project-lite", + "quinn-proto 0.9.6", + "quinn-udp 0.3.2", + "rustc-hash", + "rustls 0.20.9", + "thiserror", + "tokio", + "tracing", + "webpki", +] + +[[package]] +name = "quinn" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8cc2c5017e4b43d5995dcea317bc46c1e09404c0a9664d2908f7f02dfe943d75" +dependencies = [ + "bytes", + "futures-io", + "pin-project-lite", + "quinn-proto 0.10.6", + "quinn-udp 0.4.1", + "rustc-hash", + "rustls 0.21.12", + "thiserror", + "tokio", + "tracing", +] + +[[package]] +name = "quinn-proto" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94b0b33c13a79f669c85defaf4c275dc86a0c0372807d0ca3d78e0bb87274863" +dependencies = [ + "bytes", + "rand", + "ring 0.16.20", + "rustc-hash", + "rustls 0.20.9", + "slab", + "thiserror", + "tinyvec", + "tracing", + "webpki", +] + +[[package]] +name = "quinn-proto" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "141bf7dfde2fbc246bfd3fe12f2455aa24b0fbd9af535d8c86c7bd1381ff2b1a" +dependencies = [ + "bytes", + "rand", + "ring 0.16.20", + "rustc-hash", + "rustls 0.21.12", + "slab", + "thiserror", + "tinyvec", + "tracing", +] + +[[package]] +name = "quinn-udp" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77de3c815e5a160b1539c6592796801df2043ae35e123b46d73380cfa57af858" +checksum = "641538578b21f5e5c8ea733b736895576d0fe329bb883b937db6f4d163dbaaf4" dependencies = [ - "futures-core", - "futures-sink", - "pin-project-lite 0.1.12", + "libc", + "quinn-proto 0.9.6", + "socket2 0.4.10", + "tracing", + "windows-sys 0.42.0", ] [[package]] -name = "quinn-proto" -version = "0.9.6" +name = "quinn-udp" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94b0b33c13a79f669c85defaf4c275dc86a0c0372807d0ca3d78e0bb87274863" +checksum = "055b4e778e8feb9f93c4e439f71dc2156ef13360b432b799e179a8c4cdf0b1d7" dependencies = [ "bytes", - "rand", - "ring 0.16.20", - "rustc-hash", - "rustls 0.20.9", - "slab", - "thiserror", - "tinyvec", + "libc", + "socket2 0.5.7", "tracing", - "webpki", + "windows-sys 0.48.0", ] [[package]] @@ -10501,18 +11307,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ "libc", - "rand_chacha 0.3.1", - "rand_core 0.6.4", -] - -[[package]] -name = "rand_chacha" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" -dependencies = [ - "ppv-lite86", - "rand_core 0.5.1", + "rand_chacha", + "rand_core", ] [[package]] @@ -10522,16 +11318,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" dependencies = [ "ppv-lite86", - "rand_core 0.6.4", -] - -[[package]] -name = "rand_core" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" -dependencies = [ - "getrandom 0.1.16", + "rand_core", ] [[package]] @@ -10540,7 +11327,7 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ - "getrandom 0.2.15", + "getrandom", ] [[package]] @@ -10559,7 +11346,16 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "59cad018caf63deb318e5a4586d99a24424a364f40f1e5778c29aca23f4fc73e" dependencies = [ - "rand_core 0.6.4", + "rand_core", +] + +[[package]] +name = "raw-cpuid" +version = "11.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e29830cbb1290e404f24c73af91c5d8d631ce7e128691e9477556b540cd01ecd" +dependencies = [ + "bitflags 2.5.0", ] [[package]] @@ -10633,7 +11429,7 @@ version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bd283d9651eeda4b2a83a43c1c91b266c40fd76ecd39a50a8c630ae69dc72891" dependencies = [ - "getrandom 0.2.15", + "getrandom", "libredox", "thiserror", ] @@ -10682,6 +11478,19 @@ dependencies = [ "smallvec", ] +[[package]] +name = "regalloc2" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad156d539c879b7a24a363a2016d77961786e71f48f2e2fc8302a92abd2429a6" +dependencies = [ + "hashbrown 0.13.2", + "log", + "rustc-hash", + "slice-group-by", + "smallvec", +] + [[package]] name = "regex" version = "1.10.5" @@ -10743,7 +11552,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" dependencies = [ "hmac 0.12.1", - "subtle 2.4.1", + "subtle 2.5.0", ] [[package]] @@ -10769,22 +11578,13 @@ checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" dependencies = [ "cc", "cfg-if", - "getrandom 0.2.15", + "getrandom", "libc", "spin 0.9.8", "untrusted 0.9.0", "windows-sys 0.52.0", ] -[[package]] -name = "ripemd" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd124222d17ad93a644ed9d011a40f4fb64aa54275c08cc216524a9ea82fb09f" -dependencies = [ - "digest 0.10.7", -] - [[package]] name = "rlp" version = "0.5.2" @@ -10807,11 +11607,12 @@ dependencies = [ [[package]] name = "rococo-runtime" -version = "8.0.1" +version = "15.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfa4cc054efdd3bfbec965da01b1ae16475031308c109c173347717091f6e3a5" +checksum = "0874c053846cd50170370d88244fd00ed299d3d3833804f0929371a9ed836137" dependencies = [ "binary-merkle-tree", + "bitvec", "frame-benchmarking", "frame-executive", "frame-metadata-hash-extension", @@ -10837,7 +11638,6 @@ dependencies = [ "pallet-elections-phragmen", "pallet-grandpa", "pallet-identity", - "pallet-im-online", "pallet-indices", "pallet-membership", "pallet-message-queue", @@ -10845,6 +11645,7 @@ dependencies = [ "pallet-multisig", "pallet-nis", "pallet-offences", + "pallet-parameters", "pallet-preimage", "pallet-proxy", "pallet-ranked-collective", @@ -10876,6 +11677,7 @@ dependencies = [ "scale-info", "serde", "serde_derive", + "serde_json", "smallvec", "sp-api", "sp-arithmetic", @@ -10883,6 +11685,7 @@ dependencies = [ "sp-block-builder", "sp-consensus-babe", "sp-consensus-beefy", + "sp-consensus-grandpa", "sp-core", "sp-genesis-builder", "sp-inherents", @@ -10901,13 +11704,14 @@ dependencies = [ "staging-xcm-executor", "static_assertions", "substrate-wasm-builder", + "xcm-runtime-apis", ] [[package]] name = "rococo-runtime-constants" -version = "8.0.0" +version = "15.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b45c21ccb0f8777512a65510c106aeee4b59682944b9a5cb31cd7b8ed4ccb47" +checksum = "2ef330dc0657ac9e4ff93ff320e2ee1a120493bceb91010c7ef7b08fe8e27950" dependencies = [ "frame-support", "polkadot-primitives", @@ -11045,7 +11849,6 @@ version = "0.20.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b80e3dec595989ea8510028f30c408a4630db12c9cbb8de34203b89d6577e99" dependencies = [ - "log", "ring 0.16.20", "sct", "webpki", @@ -11059,10 +11862,25 @@ checksum = "3f56a14d1f48b391359b22f731fd4bd7e43c97f3c50eee276f3aa09c94784d3e" dependencies = [ "log", "ring 0.17.8", - "rustls-webpki", + "rustls-webpki 0.101.7", "sct", ] +[[package]] +name = "rustls" +version = "0.23.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05cff451f60db80f490f3c182b77c35260baace73209e9cdbbe526bfe3a4d402" +dependencies = [ + "log", + "once_cell", + "ring 0.17.8", + "rustls-pki-types", + "rustls-webpki 0.102.4", + "subtle 2.5.0", + "zeroize", +] + [[package]] name = "rustls-native-certs" version = "0.6.3" @@ -11070,7 +11888,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a9aace74cb666635c918e9c12bc0d348266037aa8eb599b5cba565709a8dff00" dependencies = [ "openssl-probe", - "rustls-pemfile", + "rustls-pemfile 1.0.4", + "schannel", + "security-framework", +] + +[[package]] +name = "rustls-native-certs" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f1fb85efa936c42c6d5fc28d2629bb51e4b2f4b8a5211e297d599cc5a093792" +dependencies = [ + "openssl-probe", + "rustls-pemfile 2.1.2", + "rustls-pki-types", "schannel", "security-framework", ] @@ -11084,6 +11915,49 @@ dependencies = [ "base64 0.21.7", ] +[[package]] +name = "rustls-pemfile" +version = "2.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29993a25686778eb88d4189742cd713c9bce943bc54251a33509dc63cbacf73d" +dependencies = [ + "base64 0.22.1", + "rustls-pki-types", +] + +[[package]] +name = "rustls-pki-types" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "976295e77ce332211c0d24d92c0e83e50f5c5f046d11082cea19f3df13a3562d" + +[[package]] +name = "rustls-platform-verifier" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93bda3f493b9abe5b93b3e7e3ecde0df292f2bd28c0296b90586ee0055ff5123" +dependencies = [ + "core-foundation", + "core-foundation-sys", + "jni", + "log", + "once_cell", + "rustls 0.23.10", + "rustls-native-certs 0.7.0", + "rustls-platform-verifier-android", + "rustls-webpki 0.102.4", + "security-framework", + "security-framework-sys", + "webpki-roots 0.26.3", + "winapi", +] + +[[package]] +name = "rustls-platform-verifier-android" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f87165f0995f63a9fbeea62b64d10b4d9d8e78ec6d7d51fb2125fda7bb36788f" + [[package]] name = "rustls-webpki" version = "0.101.7" @@ -11094,6 +11968,17 @@ dependencies = [ "untrusted 0.9.0", ] +[[package]] +name = "rustls-webpki" +version = "0.102.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff448f7e92e913c4b7d4c6d8e4540a1724b319b4152b8aef6d4cf8339712b33e" +dependencies = [ + "ring 0.17.8", + "rustls-pki-types", + "untrusted 0.9.0", +] + [[package]] name = "rustversion" version = "1.0.17" @@ -11113,9 +11998,9 @@ dependencies = [ [[package]] name = "rw-stream-sink" -version = "0.3.0" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26338f5e09bb721b85b135ea05af7767c90b52f6de4f087d4f4a3a9d64e7dc04" +checksum = "d8c9026ff5d2f23da5e45bbc283f156383001bfb09c4e44256d02c1a685fe9a1" dependencies = [ "futures", "pin-project", @@ -11148,9 +12033,9 @@ dependencies = [ [[package]] name = "sc-allocator" -version = "24.0.0" +version = "29.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "357127c91373ed6d1ae582f6e3300ab5b13bcde43bbf270a891f44194ef48b70" +checksum = "b975ee3a95eaacb611e7b415737a7fa2db4d8ad7b880cc1b97371b04e95c7903" dependencies = [ "log", "sp-core", @@ -11160,24 +12045,25 @@ dependencies = [ [[package]] name = "sc-authority-discovery" -version = "0.35.0" +version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fb3c14cb8022844835a6f7209196b8c6544d389fe5d2972d8df2ae4ca75afbe" +checksum = "7ae99d03b5cf657754241180c4aedd14c4851a08f3fa56814106b3cc02083d2c" dependencies = [ "async-trait", "futures", "futures-timer", "ip_network", "libp2p", + "linked_hash_set", "log", - "multihash 0.18.1", - "multihash-codetable", + "multihash 0.19.1", "parity-scale-codec", "prost 0.12.6", - "prost-build", + "prost-build 0.12.6", "rand", "sc-client-api", "sc-network", + "sc-network-types", "sp-api", "sp-authority-discovery", "sp-blockchain", @@ -11190,9 +12076,9 @@ dependencies = [ [[package]] name = "sc-basic-authorship" -version = "0.35.0" +version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "724c3a6eee5f0829a1b79a15e12d63ed81b33281b14004a6331a8883b2fd8fd1" +checksum = "5c31a124aa02343a17cb86cc714bc2b66ce18c7f17530178767388de8a37b152" dependencies = [ "futures", "futures-timer", @@ -11213,9 +12099,9 @@ dependencies = [ [[package]] name = "sc-block-builder" -version = "0.34.0" +version = "0.40.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e8b0640994965c6ff3afa13242d95a61611b83da21fd86ac2b1ebd03e241a02" +checksum = "d6345fb862e10aaa7d88d6689a7c247448c40ae465253c83566dc76a17ec1426" dependencies = [ "parity-scale-codec", "sp-api", @@ -11229,11 +12115,11 @@ dependencies = [ [[package]] name = "sc-chain-spec" -version = "28.0.0" +version = "35.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f73880050f8b04fed7f6301279ef3899df13a3891bd06156d56f9a1c50fefba" +checksum = "e04100ec7ff9cf1f2052b05086c77cc216ff7268b8c4fe41007de420bc1f70be" dependencies = [ - "array-bytes 6.2.3", + "array-bytes", "docify", "log", "memmap2 0.9.4", @@ -11252,13 +12138,14 @@ dependencies = [ "sp-io", "sp-runtime", "sp-state-machine", + "sp-tracing", ] [[package]] name = "sc-chain-spec-derive" -version = "11.0.0" +version = "12.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2e80fbdaea194762d4b4b0eec389037c25ad102676203b42d684774ae3019b8" +checksum = "b18cef11d2c69703e0d7c3528202ef4ed1cd2b47a6f063e9e17cad8255b1fa94" dependencies = [ "proc-macro-crate 3.1.0", "proc-macro2", @@ -11268,20 +12155,20 @@ dependencies = [ [[package]] name = "sc-cli" -version = "0.37.0" +version = "0.44.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8a284c10ea92b1fe789b9f0e5815d393f3a1e3bf6a4adaa884f24e36143b83b" +checksum = "23a50b5a5de473b38de8a909b125b9747a30158900159e59251bb716f80d6d22" dependencies = [ - "array-bytes 6.2.3", - "bip39", + "array-bytes", "chrono", "clap", "fdlimit", "futures", - "itertools 0.10.5", + "itertools 0.11.0", "libp2p-identity", "log", "names", + "parity-bip39", "parity-scale-codec", "rand", "regex", @@ -11310,9 +12197,9 @@ dependencies = [ [[package]] name = "sc-client-api" -version = "29.0.0" +version = "35.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e914dfadaaf384d8869ae47f3ec783bf6a1ac24e7827f5fec2e0e649a450a91" +checksum = "1bb517f4418644aeefd7c29bbe34bfc56ba8b5ea56e0b661a48a4d4d6afef40b" dependencies = [ "fnv", "futures", @@ -11338,9 +12225,9 @@ dependencies = [ [[package]] name = "sc-client-db" -version = "0.36.0" +version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f08c4f29e6d2b8915bab6435b8817fa39ef7708c04a7cf6226f803e133b017c" +checksum = "2e3c685871877f39df000ec446f65fc8d502a7cecfc437cdac59866349642dc3" dependencies = [ "hash-db", "kvdb", @@ -11365,18 +12252,17 @@ dependencies = [ [[package]] name = "sc-consensus" -version = "0.34.0" +version = "0.41.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8e1ac2c698b828073982b6f5b1a466fcc345a452983356af74254ade8e9987d" +checksum = "2b2927954d83d4c055a8699cad8ae093fc921ce73694da6773bd06d195e9a8dd" dependencies = [ "async-trait", "futures", - "futures-timer", - "libp2p-identity", "log", - "mockall", + "mockall 0.11.4", "parking_lot 0.12.3", "sc-client-api", + "sc-network-types", "sc-utils", "serde", "sp-api", @@ -11391,9 +12277,9 @@ dependencies = [ [[package]] name = "sc-consensus-aura" -version = "0.35.0" +version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a16fd09794291795ad43ea1df7190083f9a47fc0a73e9b8ec0ae98fbe53a2b34" +checksum = "017320849a7fce8200da88ccf07785d461c4d144032788f09eb4316742649a38" dependencies = [ "async-trait", "futures", @@ -11421,9 +12307,9 @@ dependencies = [ [[package]] name = "sc-consensus-babe" -version = "0.35.0" +version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82ec3dc31f8fd024684d1306488836680558b680a8ec38219e19f20854811f02" +checksum = "91c28b231f19a90917fde889a5077a796e2f9cb4dc6b62f861a8d859437a54cc" dependencies = [ "async-trait", "fork-tree", @@ -11458,9 +12344,9 @@ dependencies = [ [[package]] name = "sc-consensus-babe-rpc" -version = "0.35.0" +version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf2b3004672f9eea0d9af6c9b944fa3ef0bc72fd88cea9075cdf6dc96d1439ac" +checksum = "879efb0d8d0bd363d38ca314fbe4c44363dc1bdcab0ba1c21e78d9a68fd4398b" dependencies = [ "futures", "jsonrpsee", @@ -11481,11 +12367,11 @@ dependencies = [ [[package]] name = "sc-consensus-beefy" -version = "14.0.0" +version = "21.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9ce3ee15eff7fa642791966d427f185184df3c7f4e58893705f3e7781da8ef5" +checksum = "5ddcd779375dc2aa4abfb2ff8e001d0901593b58e5c70e1720472a001fe13105" dependencies = [ - "array-bytes 6.2.3", + "array-bytes", "async-channel 1.9.0", "async-trait", "fnv", @@ -11498,6 +12384,7 @@ dependencies = [ "sc-network", "sc-network-gossip", "sc-network-sync", + "sc-network-types", "sc-utils", "sp-api", "sp-application-crypto", @@ -11508,7 +12395,6 @@ dependencies = [ "sp-core", "sp-crypto-hashing", "sp-keystore", - "sp-mmr-primitives", "sp-runtime", "substrate-prometheus-endpoint", "thiserror", @@ -11518,9 +12404,9 @@ dependencies = [ [[package]] name = "sc-consensus-beefy-rpc" -version = "14.0.0" +version = "21.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a1ed5e8ac2cb53c6a248c8f469353f55bd23c72f23fe371ac19c1d46618de1a" +checksum = "54e88abb3353e3ed98bcb8ab829dc84dfdf9d17f5312568bdf2361a1bde7ce0a" dependencies = [ "futures", "jsonrpsee", @@ -11530,6 +12416,7 @@ dependencies = [ "sc-consensus-beefy", "sc-rpc", "serde", + "sp-application-crypto", "sp-consensus-beefy", "sp-core", "sp-runtime", @@ -11538,9 +12425,9 @@ dependencies = [ [[package]] name = "sc-consensus-epochs" -version = "0.34.0" +version = "0.41.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19f68ddb91626f901578515eed93c7919f739660161f4e9f7b9407e2d0ede981" +checksum = "8c983798bfea80e629ffa4faa7c299f8522d382703cd32f7a299beaf69631586" dependencies = [ "fork-tree", "parity-scale-codec", @@ -11552,12 +12439,12 @@ dependencies = [ [[package]] name = "sc-consensus-grandpa" -version = "0.20.0" +version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ae91e5b5a120be4d13a59eaf94fd85d7c7af528482b8e21d861fa1167df3083" +checksum = "c7c6c62a03b54973f1a608a405908af0fe957fefaf77483cce96bd213eee7ed0" dependencies = [ "ahash 0.8.11", - "array-bytes 6.2.3", + "array-bytes", "async-trait", "dyn-clone", "finality-grandpa", @@ -11576,6 +12463,7 @@ dependencies = [ "sc-network-common", "sc-network-gossip", "sc-network-sync", + "sc-network-types", "sc-telemetry", "sc-transaction-pool-api", "sc-utils", @@ -11596,9 +12484,9 @@ dependencies = [ [[package]] name = "sc-consensus-grandpa-rpc" -version = "0.20.0" +version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "697cbd528516561dbc818a8990d5477169e86d9335a0b29207cf6f6a90269e7c" +checksum = "9ef329f23bdafaeb57e131b81cc479a85b6ecb25e42435b6a6a544d048207685" dependencies = [ "finality-grandpa", "futures", @@ -11617,9 +12505,9 @@ dependencies = [ [[package]] name = "sc-consensus-slots" -version = "0.34.0" +version = "0.41.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "567bddd65d52951fb9bc7a7e05d1dfdfc47ff2c594ec5ca9756d27e7226635bb" +checksum = "4dca112d43c7785193362b33aa7941947bb84d65db9187abe72f1f7a969474c0" dependencies = [ "async-trait", "futures", @@ -11641,13 +12529,14 @@ dependencies = [ [[package]] name = "sc-executor" -version = "0.33.0" +version = "0.39.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa2ac6c356538d67987bbb867e11a12a84ba87250c70fd50005b6d74f570a4f7" +checksum = "39f5767bf6a6bad29365d6d08fcf940ee453d31457ed034cf14f0392877daafd" dependencies = [ "parity-scale-codec", "parking_lot 0.12.3", "sc-executor-common", + "sc-executor-polkavm", "sc-executor-wasmtime", "schnellru", "sp-api", @@ -11664,10 +12553,11 @@ dependencies = [ [[package]] name = "sc-executor-common" -version = "0.30.0" +version = "0.35.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07498138dee3ddf2c71299ca372d8449880bb3a8a8a299a483094e9c26b0823e" +checksum = "0c3b703a33dcb7cddf19176fdf12294b9a6408125836b0f4afee3e6969e7f190" dependencies = [ + "polkavm", "sc-allocator", "sp-maybe-compressed-blob", "sp-wasm-interface", @@ -11675,11 +12565,23 @@ dependencies = [ "wasm-instrument", ] +[[package]] +name = "sc-executor-polkavm" +version = "0.32.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26fe58d9cacfab73e5595fa84b80f7bd03efebe54a0574daaeb221a1d1f7ab80" +dependencies = [ + "log", + "polkavm", + "sc-executor-common", + "sp-wasm-interface", +] + [[package]] name = "sc-executor-wasmtime" -version = "0.30.0" +version = "0.35.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30a387779ab54ec1ffce0bf3a6631faada079459d42796c1895683767918a642" +checksum = "8cd498f2f77ec1f861c30804f5bfd796d4afcc8ce44ea1f11bfbe2847551d161" dependencies = [ "anyhow", "cfg-if", @@ -11696,9 +12598,9 @@ dependencies = [ [[package]] name = "sc-informant" -version = "0.34.0" +version = "0.41.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb603a0a703f1bc10a4e6462bec1036d8fb8b3e3eff5513a9c07f98ccb8d662d" +checksum = "74c3751acd690bc469b859d0ad899b076642db9b107e31c28cbd99749b6ecb91" dependencies = [ "ansi_term", "futures", @@ -11714,11 +12616,11 @@ dependencies = [ [[package]] name = "sc-keystore" -version = "26.0.0" +version = "32.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4cc4f6a558dd23e3bae2e9f195da822465258b9aaf211c34360d7f6efb944e54" +checksum = "267c8cfaceaeecb25484bad8668c17036016e46053a23509d44486474dbf44d3" dependencies = [ - "array-bytes 6.2.3", + "array-bytes", "parking_lot 0.12.3", "serde_json", "sp-application-crypto", @@ -11729,24 +12631,24 @@ dependencies = [ [[package]] name = "sc-mixnet" -version = "0.5.0" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45fb213c15679fe5b87c383815d7fb758c70d3e7c573948bd7fe26ff344d2272" +checksum = "a5a72a92dc72572a0facd73b410855d7f6edf38b32aef46c4798c74f25e595d5" dependencies = [ - "array-bytes 4.2.0", + "array-bytes", "arrayvec 0.7.4", "blake2 0.10.6", "bytes", "futures", "futures-timer", - "libp2p-identity", "log", "mixnet", - "multiaddr", + "multiaddr 0.18.1", "parity-scale-codec", "parking_lot 0.12.3", "sc-client-api", "sc-network", + "sc-network-types", "sc-transaction-pool-api", "sp-api", "sp-consensus", @@ -11759,15 +12661,16 @@ dependencies = [ [[package]] name = "sc-network" -version = "0.35.0" +version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f231c7d5e749ec428b4cfa669d759ae76cd3da4f50d7352a2d711acdc7532891" +checksum = "04be75f35cea819bae84be99cde138872b17494acf0e54f5f0ae8b0ed3fbe51a" dependencies = [ - "array-bytes 6.2.3", + "array-bytes", "async-channel 1.9.0", "async-trait", "asynchronous-codec", "bytes", + "cid 0.9.0", "either", "fnv", "futures", @@ -11775,16 +12678,22 @@ dependencies = [ "ip_network", "libp2p", "linked_hash_set", + "litep2p", "log", - "mockall", + "mockall 0.11.4", + "once_cell", "parity-scale-codec", "parking_lot 0.12.3", "partial_sort", "pin-project", + "prost 0.12.6", + "prost-build 0.12.6", "rand", "sc-client-api", "sc-network-common", + "sc-network-types", "sc-utils", + "schnellru", "serde", "serde_json", "smallvec", @@ -11796,45 +12705,26 @@ dependencies = [ "thiserror", "tokio", "tokio-stream", - "unsigned-varint", + "unsigned-varint 0.7.2", + "void", "wasm-timer", "zeroize", ] -[[package]] -name = "sc-network-bitswap" -version = "0.34.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2f89b0134738cb3d982b6e625ca93ae8dbe83ce2a06e4b6a396e4df09ed3499" -dependencies = [ - "async-channel 1.9.0", - "cid", - "futures", - "libp2p-identity", - "log", - "prost 0.12.6", - "prost-build", - "sc-client-api", - "sc-network", - "sp-blockchain", - "sp-runtime", - "thiserror", - "unsigned-varint", -] - [[package]] name = "sc-network-common" -version = "0.34.0" +version = "0.41.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3504bbff5ab016948dbab0f21a8be26324810b76eff3627ce744adb5bfc1b3ce" +checksum = "2ec0c3c5629a418fb26b56963d40c5ca3fd02dd94eb5753e9eb72cea5c2eeb2f" dependencies = [ "async-trait", "bitflags 1.3.2", "futures", "libp2p-identity", "parity-scale-codec", - "prost-build", + "prost-build 0.12.6", "sc-consensus", + "sc-network-types", "sp-consensus", "sp-consensus-grandpa", "sp-runtime", @@ -11842,18 +12732,18 @@ dependencies = [ [[package]] name = "sc-network-gossip" -version = "0.35.0" +version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dad02cf809c34b53614fa61377e3289064edf6c78eb11df071d11fbf7546d7e9" +checksum = "0ae1836528495b6aa5140da39ed0278f5086c21ce530c37964db1b2e2c101ab1" dependencies = [ "ahash 0.8.11", "futures", "futures-timer", - "libp2p", "log", "sc-network", "sc-network-common", "sc-network-sync", + "sc-network-types", "schnellru", "sp-runtime", "substrate-prometheus-endpoint", @@ -11862,20 +12752,20 @@ dependencies = [ [[package]] name = "sc-network-light" -version = "0.34.0" +version = "0.41.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38d84ef0b212c775f58e0304ec09166089f6b09afddf559b7c2b5702933b3be4" +checksum = "f5e6deda277664336c26ea251cc1ebff7a165df0e3ad4ae23113380d9863ea40" dependencies = [ - "array-bytes 6.2.3", + "array-bytes", "async-channel 1.9.0", "futures", - "libp2p-identity", "log", "parity-scale-codec", "prost 0.12.6", - "prost-build", + "prost-build 0.12.6", "sc-client-api", "sc-network", + "sc-network-types", "sp-blockchain", "sp-core", "sp-runtime", @@ -11884,11 +12774,11 @@ dependencies = [ [[package]] name = "sc-network-sync" -version = "0.34.0" +version = "0.41.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9aa9377059deece4e7d419d9ec456f657268c0c603e1cf98df4a920f6da83461" +checksum = "ee9ab31b84534c487b9fb84e83db47890fcbd350f354b1e6484892d3d42d0020" dependencies = [ - "array-bytes 6.2.3", + "array-bytes", "async-channel 1.9.0", "async-trait", "fork-tree", @@ -11896,14 +12786,15 @@ dependencies = [ "futures-timer", "libp2p", "log", - "mockall", + "mockall 0.11.4", "parity-scale-codec", "prost 0.12.6", - "prost-build", + "prost-build 0.12.6", "sc-client-api", "sc-consensus", "sc-network", "sc-network-common", + "sc-network-types", "sc-utils", "schnellru", "smallvec", @@ -11921,38 +12812,55 @@ dependencies = [ [[package]] name = "sc-network-transactions" -version = "0.34.0" +version = "0.41.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16c9cad4baf348725bd82eadcd1747fc112ec49c76b863755ce79c588fa73fe4" +checksum = "7c2eb55e29b0ca52ad3e209fe569b72dfe6b44cc1da7d722446d5a8333dff8e1" dependencies = [ - "array-bytes 6.2.3", + "array-bytes", "futures", - "libp2p", "log", "parity-scale-codec", "sc-network", "sc-network-common", "sc-network-sync", + "sc-network-types", "sc-utils", "sp-consensus", "sp-runtime", "substrate-prometheus-endpoint", ] +[[package]] +name = "sc-network-types" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c372dbda66644a1df0daa8c0d99c36b6f74db7dca213d2416cd84f507125224" +dependencies = [ + "bs58 0.5.1", + "ed25519-dalek", + "libp2p-identity", + "litep2p", + "log", + "multiaddr 0.18.1", + "multihash 0.19.1", + "rand", + "thiserror", + "zeroize", +] + [[package]] name = "sc-offchain" -version = "30.0.0" +version = "37.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1aee89f2abd406356bfd688bd7a51155dc963259e4b752bb85d1f8a061a194fd" +checksum = "038d77ad5f923ec4183d6b31c7432fdb56d12ee69cad2cff17d4a39caf933bcb" dependencies = [ - "array-bytes 6.2.3", + "array-bytes", "bytes", "fnv", "futures", "futures-timer", "hyper 0.14.29", "hyper-rustls", - "libp2p", "log", "num_cpus", "once_cell", @@ -11962,6 +12870,7 @@ dependencies = [ "sc-client-api", "sc-network", "sc-network-common", + "sc-network-types", "sc-transaction-pool-api", "sc-utils", "sp-api", @@ -11976,9 +12885,9 @@ dependencies = [ [[package]] name = "sc-proposer-metrics" -version = "0.17.0" +version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb8dadb2ae5a316e4d08cad6aacd5de1dec792f3bd94e3960795ff7ffd07211c" +checksum = "f680a0bed67dab19898624246376ba85d5f70a89859ba030830aacd079c28d3c" dependencies = [ "log", "substrate-prometheus-endpoint", @@ -11986,9 +12895,9 @@ dependencies = [ [[package]] name = "sc-rpc" -version = "30.0.0" +version = "37.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a5acf6d89f062d1334a0c5b67e9dea97666cd47a49acb2696eab55ff1a1bf74" +checksum = "ca9cb792ddb5d0c3df89018e80290de4c769315fa59271bda0a0d29b2d182fdc" dependencies = [ "futures", "jsonrpsee", @@ -12019,9 +12928,9 @@ dependencies = [ [[package]] name = "sc-rpc-api" -version = "0.34.0" +version = "0.41.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9db6aaabfa7e0c27ec15d0f0a11b994cd4bcf86e362f0d9732b4a414d793f0f" +checksum = "57b8adf62a207985cf7534abf0d940b335fda0a68eb902da05b7270ee30a6293" dependencies = [ "jsonrpsee", "parity-scale-codec", @@ -12040,13 +12949,20 @@ dependencies = [ [[package]] name = "sc-rpc-server" -version = "12.0.0" +version = "16.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "691440bbaddd3bc2675309c965cc75f8bf694f51e0a28039bfc9658299fbc394" +checksum = "3c14c236a01e03f55f16b92d89fd902cf2e4e9887357a3c36827a1e39b799c6b" dependencies = [ - "http 0.2.12", + "forwarded-header-value", + "futures", + "governor", + "http 1.1.0", + "http-body-util", + "hyper 1.4.1", + "ip_network", "jsonrpsee", "log", + "serde", "serde_json", "substrate-prometheus-endpoint", "tokio", @@ -12056,11 +12972,11 @@ dependencies = [ [[package]] name = "sc-rpc-spec-v2" -version = "0.35.0" +version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7f10275c62296a785f6e2ac716521e3b6e0fae470416fdf86491cbbfcc2e23d" +checksum = "4242d30df623f68d5b937ae264cce85e734c35922e0bf196d7a59b8e7f7843c2" dependencies = [ - "array-bytes 6.2.3", + "array-bytes", "futures", "futures-util", "hex", @@ -12068,11 +12984,13 @@ dependencies = [ "log", "parity-scale-codec", "parking_lot 0.12.3", + "rand", "sc-chain-spec", "sc-client-api", "sc-rpc", "sc-transaction-pool-api", "sc-utils", + "schnellru", "serde", "sp-api", "sp-blockchain", @@ -12087,9 +13005,9 @@ dependencies = [ [[package]] name = "sc-service" -version = "0.36.0" +version = "0.43.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e14ea779b8c5bdb0d0199c8beebcf1fdc5641e468c480e1c4684be660c8c90af" +checksum = "718b7e3a3963b09c2ab18ce13dbc43c0afa8b53169b67372fbcc4c4147b77e05" dependencies = [ "async-trait", "directories", @@ -12110,11 +13028,11 @@ dependencies = [ "sc-informant", "sc-keystore", "sc-network", - "sc-network-bitswap", "sc-network-common", "sc-network-light", "sc-network-sync", "sc-network-transactions", + "sc-network-types", "sc-rpc", "sc-rpc-server", "sc-rpc-spec-v2", @@ -12124,6 +13042,7 @@ dependencies = [ "sc-transaction-pool", "sc-transaction-pool-api", "sc-utils", + "schnellru", "serde", "serde_json", "sp-api", @@ -12151,9 +13070,9 @@ dependencies = [ [[package]] name = "sc-state-db" -version = "0.31.0" +version = "0.36.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa842052c41ad379eaecdfddc0d5c953d57e311ae688233f68f461b91d38da0a" +checksum = "f689d0b97c1bbdb2ca31b5f202bda195947f85c7fef990651cad202b99de896b" dependencies = [ "log", "parity-scale-codec", @@ -12163,9 +13082,9 @@ dependencies = [ [[package]] name = "sc-storage-monitor" -version = "0.17.0" +version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26cb401aad6732700c8d866cbbef1175b9aeb8230908aff27059ef14bd058ef3" +checksum = "1d117c3945c524b9c0e30966359895f5ad551c2cd4ccbb677b53917fbad5039a" dependencies = [ "clap", "fs4", @@ -12177,9 +13096,9 @@ dependencies = [ [[package]] name = "sc-sync-state-rpc" -version = "0.35.0" +version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9bc382c7d997f4531eee5e5d57f970eaf2761d722298d7747385a4ad69fa6b12" +checksum = "58fca6421f003249095557d97b674a27bf4bbf1f301406eb04c42878a43fc715" dependencies = [ "jsonrpsee", "parity-scale-codec", @@ -12197,9 +13116,9 @@ dependencies = [ [[package]] name = "sc-sysinfo" -version = "28.0.0" +version = "35.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25d2ab8f15021916a07cfbe7a08be484c5dc7d57f07bc0e2aa03260b55a5632f" +checksum = "7c00ab3d8f51c1905cc3c53cf441b9d94403c67f27968002ff7765248b0f3e6b" dependencies = [ "derive_more", "futures", @@ -12219,9 +13138,9 @@ dependencies = [ [[package]] name = "sc-telemetry" -version = "16.0.0" +version = "22.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0673a93aa0684b606abfc5fce6c882ada7bb5fad8a2ddc66a09a42bcc9664d91" +checksum = "b1fc8e8ad7f84f2ca864ee361b6207fe21e18c8182c60f209732b2a7c0dcbd31" dependencies = [ "chrono", "futures", @@ -12230,6 +13149,7 @@ dependencies = [ "parking_lot 0.12.3", "pin-project", "rand", + "sc-network", "sc-utils", "serde", "serde_json", @@ -12239,9 +13159,9 @@ dependencies = [ [[package]] name = "sc-tracing" -version = "29.0.0" +version = "35.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e77b4fdb4f359f19c395ba862430f3ca0efb50b0310b09753caaa06997edd606" +checksum = "61151f2d6b7ce3d7174484414dbc4e2f64b05a144c8f0a59ea02284e6c748a19" dependencies = [ "ansi_term", "chrono", @@ -12264,8 +13184,8 @@ dependencies = [ "sp-tracing", "thiserror", "tracing", - "tracing-log 0.1.4", - "tracing-subscriber 0.2.25", + "tracing-log 0.2.0", + "tracing-subscriber 0.3.18", ] [[package]] @@ -12282,9 +13202,9 @@ dependencies = [ [[package]] name = "sc-transaction-pool" -version = "29.0.0" +version = "35.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "326dc8ea417c53b6787bd1bb27431d44768504451f5ce4efdde0c15877c7c121" +checksum = "800e35d0d2f2b8e17170ec961d58756fe7891026b19d889be388b9585cb12f90" dependencies = [ "async-trait", "futures", @@ -12310,9 +13230,9 @@ dependencies = [ [[package]] name = "sc-transaction-pool-api" -version = "29.0.0" +version = "35.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93ae888ce3491acb1b489c3dba930d0c46c7ef9f9893ba0ab8af9125362f3d14" +checksum = "b3de6f60df6706970061e225e87d77aab9a764b258fe151b896a700419bc6b9d" dependencies = [ "async-trait", "futures", @@ -12327,9 +13247,9 @@ dependencies = [ [[package]] name = "sc-utils" -version = "15.0.0" +version = "17.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28b1a238f5baa56405db4e440e2d2f697583736fa2e2f1aac345c438a42975f1" +checksum = "acf1bad736c230f16beb1cf48af9e69564df23b13aca9e5751a61266340b4bb5" dependencies = [ "async-channel 1.9.0", "futures", @@ -12341,6 +13261,29 @@ dependencies = [ "sp-arithmetic", ] +[[package]] +name = "scale-bits" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e57b1e7f6b65ed1f04e79a85a57d755ad56d76fdf1e9bddcc9ae14f71fcdcf54" +dependencies = [ + "parity-scale-codec", + "scale-type-resolver", +] + +[[package]] +name = "scale-decode" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e98f3262c250d90e700bb802eb704e1f841e03331c2eb815e46516c4edbf5b27" +dependencies = [ + "derive_more", + "parity-scale-codec", + "scale-bits", + "scale-type-resolver", + "smallvec", +] + [[package]] name = "scale-info" version = "2.11.3" @@ -12367,6 +13310,12 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "scale-type-resolver" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0cded6518aa0bd6c1be2b88ac81bf7044992f0f154bfbabd5ad34f43512abcb" + [[package]] name = "schannel" version = "0.1.23" @@ -12397,7 +13346,7 @@ dependencies = [ "arrayvec 0.7.4", "curve25519-dalek-ng", "merlin", - "rand_core 0.6.4", + "rand_core", "sha2 0.9.9", "subtle-ng", "zeroize", @@ -12412,13 +13361,13 @@ dependencies = [ "aead", "arrayref", "arrayvec 0.7.4", - "curve25519-dalek 4.1.3", + "curve25519-dalek", "getrandom_or_panic", "merlin", - "rand_core 0.6.4", + "rand_core", "serde_bytes", "sha2 0.10.8", - "subtle 2.4.1", + "subtle 2.5.0", "zeroize", ] @@ -12444,6 +13393,21 @@ dependencies = [ "untrusted 0.9.0", ] +[[package]] +name = "sctp-proto" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6220f78bb44c15f326b0596113305f6101097a18755d53727a575c97e09fb24" +dependencies = [ + "bytes", + "crc", + "fxhash", + "log", + "rand", + "slab", + "thiserror", +] + [[package]] name = "sec1" version = "0.7.3" @@ -12454,7 +13418,8 @@ dependencies = [ "der", "generic-array 0.14.7", "pkcs8", - "subtle 2.4.1", + "serdect", + "subtle 2.5.0", "zeroize", ] @@ -12504,6 +13469,7 @@ dependencies = [ "core-foundation", "core-foundation-sys", "libc", + "num-bigint", "security-framework-sys", ] @@ -12541,6 +13507,12 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" +[[package]] +name = "send_wrapper" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd0b0ec5f1c1ca621c432a25813d8d60c88abe6d3e08a3eb9cf37d97a0fe3d73" + [[package]] name = "serde" version = "1.0.203" @@ -12639,6 +13611,16 @@ dependencies = [ "time", ] +[[package]] +name = "serdect" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a84f14a19e9a014bb9f4512488d9829a68e04ecabffb0f9904cd1ace94598177" +dependencies = [ + "base16ct", + "serde", +] + [[package]] name = "sha-1" version = "0.9.8" @@ -12652,6 +13634,18 @@ dependencies = [ "opaque-debug 0.3.1", ] +[[package]] +name = "sha-1" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5058ada175748e33390e40e872bd0fe59a19f265d0158daa551c5a88a76009c" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest 0.10.7", + "sha1-asm", +] + [[package]] name = "sha1" version = "0.10.6" @@ -12663,6 +13657,15 @@ dependencies = [ "digest 0.10.7", ] +[[package]] +name = "sha1-asm" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "286acebaf8b67c1130aedffad26f594eff0c1292389158135327d2e23aed582b" +dependencies = [ + "cc", +] + [[package]] name = "sha2" version = "0.9.9" @@ -12759,7 +13762,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" dependencies = [ "digest 0.10.7", - "rand_core 0.6.4", + "rand_core", ] [[package]] @@ -12775,6 +13778,15 @@ dependencies = [ "wide", ] +[[package]] +name = "simple-dns" +version = "0.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cae9a3fcdadafb6d97f4c0e007e4247b114ee0f119f650c3cbf3a8b3a1479694" +dependencies = [ + "bitflags 2.5.0", +] + [[package]] name = "simple-mermaid" version = "0.1.1" @@ -12804,9 +13816,9 @@ checksum = "826167069c09b99d56f31e9ae5c99049e932a98c9dc2dac47645b08dbbf76ba7" [[package]] name = "slot-range-helper" -version = "8.0.0" +version = "14.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d40fa5e14772407fd2ccffdd5971bf055bbf46a40727c0ea96d2bb6563d17e1c" +checksum = "a4d67aa9b1ccfd746c8529754c4ce06445b1d48e189567402ef856340a3a6b14" dependencies = [ "enumn", "parity-scale-codec", @@ -12863,7 +13875,7 @@ dependencies = [ "chacha20", "crossbeam-queue", "derive_more", - "ed25519-zebra 4.0.3", + "ed25519-zebra", "either", "event-listener 2.5.3", "fnv", @@ -12880,11 +13892,11 @@ dependencies = [ "num-bigint", "num-rational", "num-traits", - "pbkdf2 0.12.2", + "pbkdf2", "pin-project", "poly1305", "rand", - "rand_chacha 0.3.1", + "rand_chacha", "ruzstd", "schnorrkel 0.10.2", "serde", @@ -12894,10 +13906,10 @@ dependencies = [ "siphasher", "slab", "smallvec", - "soketto", + "soketto 0.7.1", "twox-hash", - "wasmi", - "x25519-dalek 2.0.1", + "wasmi 0.31.2", + "x25519-dalek", "zeroize", ] @@ -12927,7 +13939,7 @@ dependencies = [ "parking_lot 0.12.3", "pin-project", "rand", - "rand_chacha 0.3.1", + "rand_chacha", "serde", "serde_json", "siphasher", @@ -12952,12 +13964,12 @@ dependencies = [ "aes-gcm", "blake2 0.10.6", "chacha20poly1305", - "curve25519-dalek 4.1.3", - "rand_core 0.6.4", + "curve25519-dalek", + "rand_core", "ring 0.17.8", "rustc_version", "sha2 0.10.8", - "subtle 2.4.1", + "subtle 2.5.0", ] [[package]] @@ -12972,13 +13984,12 @@ dependencies = [ [[package]] name = "snowbridge-beacon-primitives" -version = "0.1.2" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5404af73550b39022e08e5500b30fba627e109a56407b7e80b08da2305b11bfe" +checksum = "a0ad61e3ab1c48d4c8060c7ef8571c5b6007df26687e8dbfdb6c857d840cfd2c" dependencies = [ "byte-slice-cast", "frame-support", - "frame-system", "hex", "parity-scale-codec", "rlp", @@ -12992,14 +14003,13 @@ dependencies = [ "sp-std", "ssz_rs", "ssz_rs_derive", - "static_assertions", ] [[package]] name = "snowbridge-core" -version = "0.1.3" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aed4ebefed4c40b9c00e9adf5f02ab2760a7a2dad8bf05110c0013a7a59f4097" +checksum = "668cd71582305168ed51cb0357a4b4ea814c68c7db3898a9ba4d492f712c54e1" dependencies = [ "ethabi-decode", "frame-support", @@ -13021,9 +14031,9 @@ dependencies = [ [[package]] name = "snowbridge-ethereum" -version = "0.2.0" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "315ad74f081734cb51f48bb10cd18a3f83cfec3c09a551bc936027708635e808" +checksum = "1ef1f6f60f6c8cc3cdb2a829d7452de946d8707f63f70c6f714d1c52cbc0fc17" dependencies = [ "ethabi-decode", "ethbloom", @@ -13032,11 +14042,9 @@ dependencies = [ "parity-bytes", "parity-scale-codec", "rlp", - "rustc-hex", "scale-info", "serde", "serde-big-array", - "sp-core", "sp-io", "sp-runtime", "sp-std", @@ -13059,25 +14067,21 @@ dependencies = [ [[package]] name = "snowbridge-router-primitives" -version = "0.1.0" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee5cc8e156f033971c5435676be92ab6f70a926b3497ca9c28c0dde9697b8da9" +checksum = "8e8e6707ced1308d763117bfe68f85e3f22fcdca7987b32e438c0485570f6ac7" dependencies = [ - "ethabi-decode", "frame-support", - "frame-system", "hex-literal", "log", "parity-scale-codec", "scale-info", - "serde", "snowbridge-core", "sp-core", "sp-io", "sp-runtime", "sp-std", "staging-xcm", - "staging-xcm-builder", "staging-xcm-executor", ] @@ -13109,20 +14113,34 @@ checksum = "41d1c5305e39e09653383c2c7244f2f78b3bcae37cf50c64cb4789c9f5096ec2" dependencies = [ "base64 0.13.1", "bytes", - "flate2", "futures", - "http 0.2.12", "httparse", "log", "rand", - "sha-1", + "sha-1 0.9.8", +] + +[[package]] +name = "soketto" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37468c595637c10857701c990f93a40ce0e357cedb0953d1c26c8d8027f9bb53" +dependencies = [ + "base64 0.22.1", + "bytes", + "futures", + "http 1.1.0", + "httparse", + "log", + "rand", + "sha1", ] [[package]] name = "sp-api" -version = "27.0.1" +version = "33.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e4f8702afd77f14a32733e2b589c02694bf79d0b3a641963c508016208724d0" +checksum = "b7e43fbf034e9dbaa8ffc6a238a22808777eb38c580f66fc6736d8511631789e" dependencies = [ "hash-db", "log", @@ -13133,6 +14151,7 @@ dependencies = [ "sp-externalities", "sp-metadata-ir", "sp-runtime", + "sp-runtime-interface", "sp-state-machine", "sp-std", "sp-trie", @@ -13142,13 +14161,13 @@ dependencies = [ [[package]] name = "sp-api-proc-macro" -version = "15.0.1" +version = "20.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0301e2f77afb450fbf2b093f8b324c7ad88cc82e5e69bd5dc8658a1f068b2a96" +checksum = "c9aadf9e97e694f0e343978aa632938c5de309cbcc8afed4136cb71596737278" dependencies = [ "Inflector", "blake2 0.10.6", - "expander 2.2.1", + "expander", "proc-macro-crate 3.1.0", "proc-macro2", "quote", @@ -13157,9 +14176,9 @@ dependencies = [ [[package]] name = "sp-application-crypto" -version = "31.0.0" +version = "37.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "547cad7a6eabb52c639ec117b3db9c6b43cf1b29a9393b18feb19e101a91833f" +checksum = "0d96d1fc0f1c741bbcbd0dd5470eff7b66f011708cc1942b088ebf0d4efb3d93" dependencies = [ "parity-scale-codec", "scale-info", @@ -13171,10 +14190,11 @@ dependencies = [ [[package]] name = "sp-arithmetic" -version = "24.0.0" +version = "26.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afa823ca5adc490d47dccb41d69ad482bc57a317bd341de275868378f48f131c" +checksum = "46d0d0a4c591c421d3231ddd5e27d828618c24456d51445d21a1f79fcee97c23" dependencies = [ + "docify", "integer-sqrt", "num-traits", "parity-scale-codec", @@ -13186,35 +14206,33 @@ dependencies = [ [[package]] name = "sp-authority-discovery" -version = "27.0.0" +version = "33.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c92b177c72b5d2973c36d60f6ef942d791d9fd91eae8b08c71882e4118d4fbfc" +checksum = "6a4a1e45abc3277f18484ee0b0f9808e4206eb696ad38500c892c72f33480d69" dependencies = [ "parity-scale-codec", "scale-info", "sp-api", "sp-application-crypto", "sp-runtime", - "sp-std", ] [[package]] name = "sp-block-builder" -version = "27.0.0" +version = "33.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b36ce171caa7eb2bbe682c089f755fdefa71d3702e4fb1ba30d10146aef99d5" +checksum = "2cf199dc4f9f77abd3fd91c409759118159ce6ffcd8bc90b229b684ccc8c981f" dependencies = [ "sp-api", "sp-inherents", "sp-runtime", - "sp-std", ] [[package]] name = "sp-blockchain" -version = "29.0.0" +version = "35.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a31303e766d2e53812641bbc1f1cec03a85793fc9e627e55f0a6854b28708758" +checksum = "f27eb18b6ddf7d663f4886f7edba3eb73bd102d68cf10802c1f862e3b3db32ab" dependencies = [ "futures", "log", @@ -13231,9 +14249,9 @@ dependencies = [ [[package]] name = "sp-consensus" -version = "0.33.0" +version = "0.39.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb6e512b862c4ff7a26cdcd364898cc42e181ff5cb35fbb226ff27d88c81569a" +checksum = "ab094e8a7e9e5c7f05f8d90592aa1d1cf9b3f547d0dd401daff7ed98af942e12" dependencies = [ "async-trait", "futures", @@ -13247,9 +14265,9 @@ dependencies = [ [[package]] name = "sp-consensus-aura" -version = "0.33.0" +version = "0.39.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bf13c293685319751f72fa5216c7fb5f25f3e8e8fe29b4503296ed5f5466b3d" +checksum = "05ebb90bf00f331b898eb729a1f707251846c1d5582d7467f083884799a69b89" dependencies = [ "async-trait", "parity-scale-codec", @@ -13259,15 +14277,14 @@ dependencies = [ "sp-consensus-slots", "sp-inherents", "sp-runtime", - "sp-std", "sp-timestamp", ] [[package]] name = "sp-consensus-babe" -version = "0.33.0" +version = "0.39.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9be2f86a2f0ce2a78b455feb547aa27604fd76a7f7a691995cbad44e0b1b9dd" +checksum = "3aa2de4c7100a3279658d8dd4affd8f92487528deae5cb4b40322717b9175ed5" dependencies = [ "async-trait", "parity-scale-codec", @@ -13279,15 +14296,14 @@ dependencies = [ "sp-core", "sp-inherents", "sp-runtime", - "sp-std", "sp-timestamp", ] [[package]] name = "sp-consensus-beefy" -version = "14.0.0" +version = "20.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90ff890a84ef57628b010df0e1d75b3a78fb7f575e4ceeba7215c276902c403e" +checksum = "b277bc109da8e1c3768d3a046e1cd1ab687aabac821c976c5f510deb6f0bc8d3" dependencies = [ "lazy_static", "parity-scale-codec", @@ -13298,17 +14314,17 @@ dependencies = [ "sp-core", "sp-crypto-hashing", "sp-io", + "sp-keystore", "sp-mmr-primitives", "sp-runtime", - "sp-std", - "strum 0.24.1", + "strum 0.26.2", ] [[package]] name = "sp-consensus-grandpa" -version = "14.0.0" +version = "20.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64b606164600db36e596db7abf32b4533dc9a74526d9444c4c45035427b2199b" +checksum = "21dd06bf366c60f69411668b26d6ab3c55120aa6d423e6af0373ec23d8957300" dependencies = [ "finality-grandpa", "log", @@ -13320,44 +14336,43 @@ dependencies = [ "sp-core", "sp-keystore", "sp-runtime", - "sp-std", ] [[package]] name = "sp-consensus-slots" -version = "0.33.0" +version = "0.39.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73a5bd1fcd84bbdc7255528c7cdb92f9357fd555f06ee553af7e340cbdab517c" +checksum = "c8ca60d713f8ddb03bbebcc755d5e6463fdc0b6259fabfc4221b20a5f1e428fd" dependencies = [ "parity-scale-codec", "scale-info", "serde", - "sp-std", "sp-timestamp", ] [[package]] name = "sp-core" -version = "29.0.0" +version = "34.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c33c7a1568175250628567d50c4e1c54a6ac5bc1190413b9be29a9e810cbe73" +checksum = "c961a5e33fb2962fa775c044ceba43df9c6f917e2c35d63bfe23738468fa76a7" dependencies = [ - "array-bytes 6.2.3", - "bip39", + "array-bytes", "bitflags 1.3.2", "blake2 0.10.6", "bounded-collections", "bs58 0.5.1", "dyn-clonable", - "ed25519-zebra 3.1.0", + "ed25519-zebra", "futures", "hash-db", "hash256-std-hasher", "impl-serde", - "itertools 0.10.5", + "itertools 0.11.0", + "k256", "libsecp256k1", "log", "merlin", + "parity-bip39", "parity-scale-codec", "parking_lot 0.12.3", "paste", @@ -13430,54 +14445,54 @@ dependencies = [ [[package]] name = "sp-externalities" -version = "0.26.0" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7096ed024cec397804864898b093b51e14c7299f1d00c67dd5800330e02bb82" +checksum = "a904407d61cb94228c71b55a9d3708e9d6558991f9e83bd42bd91df37a159d30" dependencies = [ "environmental", "parity-scale-codec", - "sp-std", "sp-storage", ] [[package]] name = "sp-genesis-builder" -version = "0.8.0" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd865540ec19479c7349b584ccd78cc34c3f3a628a2a69dbb6365ceec36295ee" +checksum = "fcd065854d96fd81521c103d0aaa287d4f08b9b15c9fae2a3bfb208b0812bf44" dependencies = [ + "parity-scale-codec", + "scale-info", "serde_json", "sp-api", "sp-runtime", - "sp-std", ] [[package]] name = "sp-inherents" -version = "27.0.0" +version = "33.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "607c9e35e96966645ff180a9e9f976433b96e905d0a91d8d5315e605a21f4bc0" +checksum = "53407ba38ec22ca4a16381722c4bd0b559a0428bc1713079b0d5163ada63186a" dependencies = [ "async-trait", "impl-trait-for-tuples", "parity-scale-codec", "scale-info", "sp-runtime", - "sp-std", "thiserror", ] [[package]] name = "sp-io" -version = "31.0.0" +version = "37.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec43aa073eab35fcb920d7592474d5427ea3be2bf938706a3ad955d7ba54fd8d" +checksum = "5036cad2e48d41f5caf6785226c8be1a7db15bec14a9fd7aa6cca84f34cf689f" dependencies = [ "bytes", "ed25519-dalek", "libsecp256k1", "log", "parity-scale-codec", + "polkavm-derive", "rustversion", "secp256k1", "sp-core", @@ -13495,26 +14510,25 @@ dependencies = [ [[package]] name = "sp-keyring" -version = "32.0.0" +version = "38.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69cf0a2f881958466fc92bc9b39bbc2c0d815ded4a21f8f953372b0ac2e11b02" +checksum = "b03536e1ff3ec2bd8181eeaa26c0d682ebdcbd01548a055cf591077188b8c3f0" dependencies = [ "sp-core", "sp-runtime", - "strum 0.24.1", + "strum 0.26.2", ] [[package]] name = "sp-keystore" -version = "0.35.0" +version = "0.40.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "444f2d53968b1ce5e908882710ff1f3873fcf3e95f59d57432daf685bbacb959" +checksum = "0248b4d784cb4a01472276928977121fa39d977a5bb24793b6b15e64b046df42" dependencies = [ "parity-scale-codec", "parking_lot 0.12.3", "sp-core", "sp-externalities", - "thiserror", ] [[package]] @@ -13529,53 +14543,50 @@ dependencies = [ [[package]] name = "sp-metadata-ir" -version = "0.6.0" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa0b5e87e56c1bb26d9524d48dd127121d630f895bd5914a34f0b017489f7c1d" +checksum = "a616fa51350b35326682a472ee8e6ba742fdacb18babac38ecd46b3e05ead869" dependencies = [ "frame-metadata", "parity-scale-codec", "scale-info", - "sp-std", ] [[package]] name = "sp-mixnet" -version = "0.5.0" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7bebd44b915c65aeb7e7eeaea466aba3b27cdd915c83ea83d4643c54f21ffbbf" +checksum = "2f65a570519da820ce3dc35053497a65f9fbd3f5a7dc81fa03078ca263e9311e" dependencies = [ "parity-scale-codec", "scale-info", "sp-api", "sp-application-crypto", - "sp-std", ] [[package]] name = "sp-mmr-primitives" -version = "27.0.0" +version = "33.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "891b7263b7c44a569173ee1078f68fb1a01991a44914607c0100aa5ae41f6562" +checksum = "47412a2d2e988430d5f59d7fec1473f229e1ef5ce24c1ea4f601b4b3679cac52" dependencies = [ - "ckb-merkle-mountain-range", "log", "parity-scale-codec", + "polkadot-ckb-merkle-mountain-range", "scale-info", "serde", "sp-api", "sp-core", "sp-debug-derive", "sp-runtime", - "sp-std", "thiserror", ] [[package]] name = "sp-npos-elections" -version = "27.0.0" +version = "33.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "195d7e1154c91cce5c3abc8c778689c3e5799da6411328dd32ac7a974c68e526" +checksum = "0b0c51a7b60cd663f2661e6949069eb316b092f22c239691d5272a4d0cfca0fb" dependencies = [ "parity-scale-codec", "scale-info", @@ -13583,14 +14594,13 @@ dependencies = [ "sp-arithmetic", "sp-core", "sp-runtime", - "sp-std", ] [[package]] name = "sp-offchain" -version = "27.0.0" +version = "33.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d83b955dce0b6d143bec3f60571311168f362b1c16cf044da7037a407b66c19" +checksum = "cbe721c367760bddf10fcfa24fb48edd64c442f71db971f043c8ac73f51aa6e9" dependencies = [ "sp-api", "sp-core", @@ -13610,9 +14620,9 @@ dependencies = [ [[package]] name = "sp-rpc" -version = "27.0.0" +version = "32.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9af4b73fe7ddd88b1641cca90048c4e525e721763199e6fd29c4f590884f4d16" +checksum = "45458f0955870a92b3969098d4f1f4e9b55b4282d9f1dc112a51bb5bb6584900" dependencies = [ "rustc-hash", "serde", @@ -13621,15 +14631,16 @@ dependencies = [ [[package]] name = "sp-runtime" -version = "32.0.0" +version = "38.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a95e71603a6281e91b0f1fd3d68057644be16d75a4602013187b8137db8abee" +checksum = "89ef409c414546b655ec1e94aaea178e4a97e21284a91b24c762aebf836d3b49" dependencies = [ "docify", "either", "hash256-std-hasher", "impl-trait-for-tuples", "log", + "num-traits", "parity-scale-codec", "paste", "rand", @@ -13646,13 +14657,14 @@ dependencies = [ [[package]] name = "sp-runtime-interface" -version = "25.0.0" +version = "28.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e2321ab29d4bcc31f1ba1b4f076a81fb2a666465231e5c981c72320d74dbe63" +checksum = "985eb981f40c689c6a0012c937b68ed58dabb4341d06f2dfe4dfd5ed72fa4017" dependencies = [ "bytes", "impl-trait-for-tuples", "parity-scale-codec", + "polkavm-derive", "primitive-types", "sp-externalities", "sp-runtime-interface-proc-macro", @@ -13665,12 +14677,12 @@ dependencies = [ [[package]] name = "sp-runtime-interface-proc-macro" -version = "17.0.0" +version = "18.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfaf6e85b2ec12a4b99cd6d8d57d083e30c94b7f1b0d8f93547121495aae6f0c" +checksum = "0195f32c628fee3ce1dfbbf2e7e52a30ea85f3589da9fe62a8b816d70fc06294" dependencies = [ "Inflector", - "expander 2.2.1", + "expander", "proc-macro-crate 3.1.0", "proc-macro2", "quote", @@ -13679,9 +14691,9 @@ dependencies = [ [[package]] name = "sp-session" -version = "28.0.0" +version = "34.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b86531090cc04d2ab3535df07146258e2fb3ab6257b0a77ef14aa08282c3d4a" +checksum = "4daf2e40ffc7e7e8de08efb860eb9534faf614a49c53dc282f430faedb4aed13" dependencies = [ "parity-scale-codec", "scale-info", @@ -13690,14 +14702,13 @@ dependencies = [ "sp-keystore", "sp-runtime", "sp-staking", - "sp-std", ] [[package]] name = "sp-staking" -version = "27.0.0" +version = "33.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e14d003ecf0b610bf1305a92bdab875289b39d514c073f30e75e78c2763a788" +checksum = "0a0b7abfe66c07a3b6eb99e1286dfa9b6f3b057b0e986e7da2ccbf707f6c781a" dependencies = [ "impl-trait-for-tuples", "parity-scale-codec", @@ -13705,14 +14716,13 @@ dependencies = [ "serde", "sp-core", "sp-runtime", - "sp-std", ] [[package]] name = "sp-state-machine" -version = "0.36.0" +version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a67297e702aa32027d7766803f362a420d6d3ec9e2f84961f3c64e2e52b5aaf9" +checksum = "211e528aa6e902261a343f7b40840aa3d66fe4ad3aadbd04a035f10baf96dbc5" dependencies = [ "hash-db", "log", @@ -13723,7 +14733,6 @@ dependencies = [ "sp-core", "sp-externalities", "sp-panic-handler", - "sp-std", "sp-trie", "thiserror", "tracing", @@ -13732,12 +14741,12 @@ dependencies = [ [[package]] name = "sp-statement-store" -version = "11.0.0" +version = "17.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "309a9ae4e8134bbed8ffc510cf4d461a4a651f9250b556de782cedd876abe1ff" +checksum = "b03aa86b1b46549889d32348bc85a8135c725665115567507231a6d85712aaac" dependencies = [ "aes-gcm", - "curve25519-dalek 4.1.3", + "curve25519-dalek", "ed25519-dalek", "hkdf", "parity-scale-codec", @@ -13751,9 +14760,8 @@ dependencies = [ "sp-externalities", "sp-runtime", "sp-runtime-interface", - "sp-std", "thiserror", - "x25519-dalek 2.0.1", + "x25519-dalek", ] [[package]] @@ -13764,40 +14772,37 @@ checksum = "12f8ee986414b0a9ad741776762f4083cd3a5128449b982a3919c4df36874834" [[package]] name = "sp-storage" -version = "20.0.0" +version = "21.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8dba5791cb3978e95daf99dad919ecb3ec35565604e88cd38d805d9d4981e8bd" +checksum = "99c82989b3a4979a7e1ad848aad9f5d0b4388f1f454cc131766526601ab9e8f8" dependencies = [ "impl-serde", "parity-scale-codec", "ref-cast", "serde", "sp-debug-derive", - "sp-std", ] [[package]] name = "sp-timestamp" -version = "27.0.0" +version = "33.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "249cd06624f2edb53b25af528ab216a508dc9d0870e158b43caac3a97e86699f" +checksum = "78becf144a76f6fd108dfe94a90e20a185b38c0b310dc5482328196143c8266b" dependencies = [ "async-trait", "parity-scale-codec", "sp-inherents", "sp-runtime", - "sp-std", "thiserror", ] [[package]] name = "sp-tracing" -version = "16.0.0" +version = "17.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0351810b9d074df71c4514c5228ed05c250607cba131c1c9d1526760ab69c05c" +checksum = "90b3decf116db9f1dfaf1f1597096b043d0e12c952d3bcdc018c6d6b77deec7e" dependencies = [ "parity-scale-codec", - "sp-std", "tracing", "tracing-core", "tracing-subscriber 0.2.25", @@ -13805,9 +14810,9 @@ dependencies = [ [[package]] name = "sp-transaction-pool" -version = "27.0.0" +version = "33.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9742861c5330bdcb42856a6eed3d3745b58ee1c92ca4c9260032ff4e6c387165" +checksum = "a3c9d1604aadc15b70e95f4388d0b1aa380215520b7ddfd372531a6d8262269c" dependencies = [ "sp-api", "sp-runtime", @@ -13815,9 +14820,9 @@ dependencies = [ [[package]] name = "sp-transaction-storage-proof" -version = "27.0.0" +version = "33.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ece8e22a5419c7a336a2544654e1389fec8cac19b93081a30912842b44e8167f" +checksum = "5b5a891cb913015bb99401e372255193cc3848c6fe5c2f6fe2383ef9588cb190" dependencies = [ "async-trait", "parity-scale-codec", @@ -13825,15 +14830,14 @@ dependencies = [ "sp-core", "sp-inherents", "sp-runtime", - "sp-std", "sp-trie", ] [[package]] name = "sp-trie" -version = "30.0.0" +version = "36.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eed48dfd05081e8b36741b10ce4eb686c135a2952227a11fe71caec89890ddbb" +checksum = "841d717c0f465f5371569e6fdc25b6f32d47c15d6e4c92b3b779e1c9b18b951d" dependencies = [ "ahash 0.8.11", "hash-db", @@ -13847,7 +14851,6 @@ dependencies = [ "schnellru", "sp-core", "sp-externalities", - "sp-std", "thiserror", "tracing", "trie-db", @@ -13856,9 +14859,9 @@ dependencies = [ [[package]] name = "sp-version" -version = "30.0.0" +version = "36.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff4a660c68995663d6778df324f4e2b4efc48d55a8e9c92c22a5fb7dae7899cd" +checksum = "bccf96fefae339dee7c4453f91be64eb28cce4c2fe82130445cf096b18b2c081" dependencies = [ "impl-serde", "parity-scale-codec", @@ -13874,9 +14877,9 @@ dependencies = [ [[package]] name = "sp-version-proc-macro" -version = "13.0.0" +version = "14.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9bc3fed32d6dacbbbfb28dd1fe0224affbb737cb6cbfca1d9149351c2b69a7d" +checksum = "5aee8f6730641a65fcf0c8f9b1e448af4b3bb083d08058b47528188bccc7b7a7" dependencies = [ "parity-scale-codec", "proc-macro2", @@ -13886,23 +14889,22 @@ dependencies = [ [[package]] name = "sp-wasm-interface" -version = "20.0.0" +version = "21.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ef97172c42eb4c6c26506f325f48463e9bc29b2034a587f1b9e48c751229bee" +checksum = "3b04b919e150b4736d85089d49327eab65507deb1485eec929af69daa2278eb3" dependencies = [ "anyhow", "impl-trait-for-tuples", "log", "parity-scale-codec", - "sp-std", "wasmtime", ] [[package]] name = "sp-weights" -version = "28.0.0" +version = "31.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3be30aec904994451dcacf841a9168cfbbaf817de6b24b6a1c1418cbf1af2fe" +checksum = "93cdaf72a1dad537bbb130ba4d47307ebe5170405280ed1aa31fa712718a400e" dependencies = [ "bounded-collections", "parity-scale-codec", @@ -13911,7 +14913,6 @@ dependencies = [ "smallvec", "sp-arithmetic", "sp-debug-derive", - "sp-std", ] [[package]] @@ -13927,14 +14928,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" [[package]] -name = "spinners" -version = "4.1.1" +name = "spinning_top" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0ef947f358b9c238923f764c72a4a9d42f2d637c46e059dbd319d6e7cfb4f82" +checksum = "d96d2d1d716fb500937168cc09353ffdc7a012be8475ac7308e1bdf0e3923300" dependencies = [ - "lazy_static", - "maplit", - "strum 0.24.1", + "lock_api", ] [[package]] @@ -13993,9 +14992,9 @@ checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" [[package]] name = "staging-parachain-info" -version = "0.8.0" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da7dc139d104f676a18c13380a09c3f72d59450a7471116387cbf8cb5f845a0e" +checksum = "cd00d586b0dac4f42736bdd0ad52213a891b240e011ea82b38938263dd821c25" dependencies = [ "cumulus-primitives-core", "frame-support", @@ -14008,11 +15007,11 @@ dependencies = [ [[package]] name = "staging-xcm" -version = "8.0.1" +version = "14.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48fa328b87de3466bc38cc9a07244c42c647b7755b81115e1dfeb47cc13fc6e6" +checksum = "f2b7b5f531c6bf9629514ef8e5fda0e9e80dd84516957f710940d0e01d3fb36c" dependencies = [ - "array-bytes 6.2.3", + "array-bytes", "bounded-collections", "derivative", "environmental", @@ -14027,9 +15026,9 @@ dependencies = [ [[package]] name = "staging-xcm-builder" -version = "8.0.3" +version = "15.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78b7447c38be3ca9fb21c7434de2243aa6ac74acde8944cda7bb6e2a4f765801" +checksum = "847fa2afe1bed2751eaabf7b91fa4043037947f17653d7cc59ea202cc44c6bb8" dependencies = [ "frame-support", "frame-system", @@ -14050,9 +15049,9 @@ dependencies = [ [[package]] name = "staging-xcm-executor" -version = "8.0.2" +version = "15.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74b5c5f2a1d610c5e20e5fae2680c9a28380f305afafeed62f341bfbce57b79a" +checksum = "26b98d8219449eaf02e71a7edf1a14b14d4c713dd01d9df66fde1ce30dba4d6d" dependencies = [ "environmental", "frame-benchmarking", @@ -14105,16 +15104,34 @@ dependencies = [ ] [[package]] -name = "strobe-rs" -version = "0.8.1" +name = "str0m" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fabb238a1cccccfa4c4fb703670c0d157e1256c1ba695abf1b93bd2bb14bab2d" +checksum = "6706347e49b13373f7ddfafad47df7583ed52083d6fc8a594eb2c80497ef959d" dependencies = [ - "bitflags 1.3.2", - "byteorder", - "keccak", - "subtle 2.4.1", - "zeroize", + "combine", + "crc", + "fastrand 2.1.0", + "hmac 0.12.1", + "once_cell", + "openssl", + "openssl-sys", + "sctp-proto", + "serde", + "sha-1 0.10.1", + "thiserror", + "tracing", +] + +[[package]] +name = "string-interner" +version = "0.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c6a0d765f5807e98a091107bae0a56ea3799f66a5de47b2c84c94a39c09974e" +dependencies = [ + "cfg-if", + "hashbrown 0.14.5", + "serde", ] [[package]] @@ -14128,9 +15145,6 @@ name = "strum" version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "063e6045c0e62079840579a7e47a355ae92f60eb74daaf156fb1e84ba164e63f" -dependencies = [ - "strum_macros 0.24.3", -] [[package]] name = "strum" @@ -14169,14 +15183,14 @@ dependencies = [ [[package]] name = "substrate-bip39" -version = "0.4.6" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a7590dc041b9bc2825e52ce5af8416c73dbe9d0654402bfd4b4941938b94d8f" +checksum = "ca58ffd742f693dc13d69bdbb2e642ae239e0053f6aab3b104252892f856700a" dependencies = [ - "hmac 0.11.0", - "pbkdf2 0.8.0", + "hmac 0.12.1", + "pbkdf2", "schnorrkel 0.11.4", - "sha2 0.9.9", + "sha2 0.10.8", "zeroize", ] @@ -14188,10 +15202,11 @@ checksum = "b285e7d183a32732fdc119f3d81b7915790191fad602b7c709ef247073c77a2e" [[package]] name = "substrate-frame-rpc-system" -version = "29.0.0" +version = "36.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "332f903d2f34703204f0003136c9abbc569d691028279996a1daf8f248a7369f" +checksum = "02b8837de37f5ea6316846a63dc48489b63ebde05df73ba7d7077b3135487560" dependencies = [ + "docify", "frame-system-rpc-runtime-api", "futures", "jsonrpsee", @@ -14212,32 +15227,18 @@ version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0d8fe06b03b8a291c09507c42f92a2c2c10dd3d62975d02c7f64a92d87bfe09b" dependencies = [ - "hyper 0.14.29", - "log", - "prometheus", - "thiserror", - "tokio", -] - -[[package]] -name = "substrate-rpc-client" -version = "0.34.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40e5235d8460ec81e9a382345aa80d75e2943f224a332559847344bb62fa13b3" -dependencies = [ - "async-trait", - "jsonrpsee", + "hyper 0.14.29", "log", - "sc-rpc-api", - "serde", - "sp-runtime", + "prometheus", + "thiserror", + "tokio", ] [[package]] name = "substrate-state-trie-migration-rpc" -version = "28.0.0" +version = "35.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5768a5d3c76eebfdf94c23a3fde6c832243a043d60561e5ac1a2b475b9ad09f3" +checksum = "df246ac77a641b23068e8c49cff4dfbaefc78405f80c9589a10909e02d525141" dependencies = [ "jsonrpsee", "parity-scale-codec", @@ -14253,17 +15254,27 @@ dependencies = [ [[package]] name = "substrate-wasm-builder" -version = "18.0.1" +version = "23.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a39a20e17c24ede36b5bd5e7543a4cef8d8a0daf6e1a046dc31832b837a54a0" +checksum = "7dc993ad871b63fbba60362f3ea86583f5e7e1256e8fdcb3b5b249c9ead354bf" dependencies = [ + "array-bytes", "build-helper", "cargo_metadata 0.15.4", "console", "filetime", + "frame-metadata", + "merkleized-metadata", + "parity-scale-codec", "parity-wasm", + "polkavm-linker", + "sc-executor", + "sp-core", + "sp-io", "sp-maybe-compressed-blob", - "strum 0.24.1", + "sp-tracing", + "sp-version", + "strum 0.26.2", "tempfile", "toml 0.8.14", "walkdir", @@ -14278,9 +15289,9 @@ checksum = "2d67a5a62ba6e01cb2192ff309324cb4875d0c451d55fe2319433abe7a05a8ee" [[package]] name = "subtle" -version = "2.4.1" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" +checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" [[package]] name = "subtle-ng" @@ -14357,15 +15368,19 @@ dependencies = [ [[package]] name = "system-parachains-constants" version = "1.0.0" -source = "git+https://github.com/paseo-network/runtimes/?tag=v1.2.5-system-chains#2fa66a19eef96bd2c079385057fab2564d09b751" +source = "git+https://github.com/polkadot-fellows/runtimes#f42acab60edf4d6ded4d9e99b1a8fbacded85669" dependencies = [ "frame-support", + "kusama-runtime-constants", "parachains-common", - "paseo-runtime-constants", "polkadot-core-primitives", "polkadot-primitives", + "polkadot-runtime-constants", "smallvec", + "sp-core", "sp-runtime", + "sp-std", + "staging-xcm", ] [[package]] @@ -14603,7 +15618,7 @@ dependencies = [ "mio", "num_cpus", "parking_lot 0.12.3", - "pin-project-lite 0.2.14", + "pin-project-lite", "signal-hook-registry", "socket2 0.5.7", "tokio-macros", @@ -14622,23 +15637,23 @@ dependencies = [ ] [[package]] -name = "tokio-retry" -version = "0.3.0" +name = "tokio-rustls" +version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f57eb36ecbe0fc510036adff84824dd3c24bb781e21bfa67b69d556aa85214f" +checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" dependencies = [ - "pin-project", - "rand", + "rustls 0.21.12", "tokio", ] [[package]] name = "tokio-rustls" -version = "0.24.1" +version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" +checksum = "0c7bc40d0e5a97695bb96e27995cd3a08538541b0a846f65bba7a359f36700d4" dependencies = [ - "rustls 0.21.12", + "rustls 0.23.10", + "rustls-pki-types", "tokio", ] @@ -14649,11 +15664,26 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "267ac89e0bec6e691e5813911606935d77c476ff49024f98abcea3e7b15e37af" dependencies = [ "futures-core", - "pin-project-lite 0.2.14", + "pin-project-lite", "tokio", "tokio-util", ] +[[package]] +name = "tokio-tungstenite" +version = "0.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "212d5dcb2a1ce06d81107c3d0ffa3121fe974b73f068c8282cb1c32328113b6c" +dependencies = [ + "futures-util", + "log", + "rustls 0.21.12", + "rustls-native-certs 0.6.3", + "tokio", + "tokio-rustls 0.24.1", + "tungstenite", +] + [[package]] name = "tokio-util" version = "0.7.11" @@ -14664,7 +15694,7 @@ dependencies = [ "futures-core", "futures-io", "futures-sink", - "pin-project-lite 0.2.14", + "pin-project-lite", "tokio", ] @@ -14698,17 +15728,6 @@ dependencies = [ "serde", ] -[[package]] -name = "toml_edit" -version = "0.20.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70f427fce4d84c72b5b732388bf4a9f4531b53f74e2887e3ecb2481f68f66d81" -dependencies = [ - "indexmap 2.2.6", - "toml_datetime", - "winnow 0.5.40", -] - [[package]] name = "toml_edit" version = "0.21.1" @@ -14742,7 +15761,7 @@ dependencies = [ "futures-core", "futures-util", "pin-project", - "pin-project-lite 0.2.14", + "pin-project-lite", "tokio", "tower-layer", "tower-service", @@ -14751,18 +15770,16 @@ dependencies = [ [[package]] name = "tower-http" -version = "0.4.4" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61c5bb1d698276a2443e5ecfabc1008bf15a36c12e6a7176e7bf089ea9131140" +checksum = "1e9cd434a998747dd2c4276bc96ee2e0c7a2eadf3cae88e52be55a05fa9053f5" dependencies = [ "bitflags 2.5.0", "bytes", - "futures-core", - "futures-util", - "http 0.2.12", - "http-body 0.4.6", - "http-range-header", - "pin-project-lite 0.2.14", + "http 1.1.0", + "http-body 1.0.1", + "http-body-util", + "pin-project-lite", "tower-layer", "tower-service", ] @@ -14786,7 +15803,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" dependencies = [ "log", - "pin-project-lite 0.2.14", + "pin-project-lite", "tracing-attributes", "tracing-core", ] @@ -14824,9 +15841,9 @@ dependencies = [ [[package]] name = "tracing-gum" -version = "8.0.0" +version = "14.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9690af7fe11d125786fa1b5ca802192f631b61a4411277865c8e0581c887e286" +checksum = "d07f52b2b1a1c1c21094bd0b6fdcf1b7dbe785b937b30e82dba688d55d988efb" dependencies = [ "coarsetime", "polkadot-primitives", @@ -14840,7 +15857,7 @@ version = "5.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0f074568687ffdfd0adb6005aa8d1d96840197f2c159f80471285f08694cf0ce" dependencies = [ - "expander 2.2.1", + "expander", "proc-macro-crate 3.1.0", "proc-macro2", "quote", @@ -14889,7 +15906,6 @@ dependencies = [ "chrono", "lazy_static", "matchers 0.0.1", - "parking_lot 0.11.2", "regex", "serde", "serde_json", @@ -14909,9 +15925,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" dependencies = [ "matchers 0.1.0", + "nu-ansi-term", "once_cell", + "parking_lot 0.12.3", "regex", "sharded-slab", + "smallvec", "thread_local", "tracing", "tracing-core", @@ -14920,12 +15939,11 @@ dependencies = [ [[package]] name = "trie-db" -version = "0.28.0" +version = "0.29.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff28e0f815c2fea41ebddf148e008b077d2faddb026c9555b29696114d602642" +checksum = "0c992b4f40c234a074d48a757efeabb1a6be88af84c0c23f7ca158950cb0ae7f" dependencies = [ "hash-db", - "hashbrown 0.13.2", "log", "rustc-hex", "smallvec", @@ -14949,7 +15967,7 @@ dependencies = [ "async-trait", "cfg-if", "data-encoding", - "enum-as-inner", + "enum-as-inner 0.5.1", "futures-channel", "futures-io", "futures-util", @@ -14966,24 +15984,50 @@ dependencies = [ "url", ] +[[package]] +name = "trust-dns-proto" +version = "0.23.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3119112651c157f4488931a01e586aa459736e9d6046d3bd9105ffb69352d374" +dependencies = [ + "async-trait", + "cfg-if", + "data-encoding", + "enum-as-inner 0.6.0", + "futures-channel", + "futures-io", + "futures-util", + "idna 0.4.0", + "ipnet", + "once_cell", + "rand", + "smallvec", + "thiserror", + "tinyvec", + "tokio", + "tracing", + "url", +] + [[package]] name = "trust-dns-resolver" -version = "0.22.0" +version = "0.23.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aff21aa4dcefb0a1afbfac26deb0adc93888c7d295fb63ab273ef276ba2b7cfe" +checksum = "10a3e6c3aff1718b3c73e395d1f35202ba2ffa847c6a62eea0db8fb4cfe30be6" dependencies = [ "cfg-if", "futures-util", "ipconfig", - "lazy_static", "lru-cache", + "once_cell", "parking_lot 0.12.3", + "rand", "resolv-conf", "smallvec", "thiserror", "tokio", "tracing", - "trust-dns-proto", + "trust-dns-proto 0.23.2", ] [[package]] @@ -14993,47 +16037,36 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" [[package]] -name = "try-runtime-cli" -version = "0.39.0" +name = "tt-call" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9454e1af0a0be675f837d63080ef8f43510c05df8c059570622386a0cf40b548" +checksum = "f4f195fd851901624eee5a58c4bb2b4f06399148fcd0ed336e6f1cb60a9881df" + +[[package]] +name = "tungstenite" +version = "0.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e3dac10fd62eaf6617d3a904ae222845979aec67c615d1c842b4002c7666fb9" dependencies = [ - "async-trait", - "clap", - "frame-remote-externalities", - "frame-try-runtime", - "hex", + "byteorder", + "bytes", + "data-encoding", + "http 0.2.12", + "httparse", "log", - "parity-scale-codec", - "sc-cli", - "sc-executor", - "serde", - "serde_json", - "sp-api", - "sp-consensus-aura", - "sp-consensus-babe", - "sp-core", - "sp-debug-derive", - "sp-externalities", - "sp-inherents", - "sp-io", - "sp-keystore", - "sp-rpc", - "sp-runtime", - "sp-state-machine", - "sp-timestamp", - "sp-transaction-storage-proof", - "sp-version", - "sp-weights", - "substrate-rpc-client", - "zstd 0.12.4", + "rand", + "rustls 0.21.12", + "sha1", + "thiserror", + "url", + "utf-8", ] [[package]] -name = "tt-call" -version = "1.0.9" +name = "tuplex" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4f195fd851901624eee5a58c4bb2b4f06399148fcd0ed336e6f1cb60a9881df" +checksum = "676ac81d5454c4dcf37955d34fa8626ede3490f744b86ca14a7b90168d2a08aa" [[package]] name = "twox-hash" @@ -15111,7 +16144,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07ea" dependencies = [ "crypto-common", - "subtle 2.4.1", + "subtle 2.5.0", ] [[package]] @@ -15126,6 +16159,16 @@ dependencies = [ "futures-util", ] +[[package]] +name = "unsigned-varint" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb066959b24b5196ae73cb057f45598450d2c5f71460e98c49b738086eff9c06" +dependencies = [ + "bytes", + "tokio-util", +] + [[package]] name = "untrusted" version = "0.7.1" @@ -15150,6 +16193,12 @@ dependencies = [ "serde", ] +[[package]] +name = "utf-8" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" + [[package]] name = "utf16_iter" version = "1.0.5" @@ -15218,8 +16267,8 @@ dependencies = [ "constcat", "digest 0.10.7", "rand", - "rand_chacha 0.3.1", - "rand_core 0.6.4", + "rand_chacha", + "rand_core", "sha2 0.10.8", "sha3", "thiserror", @@ -15251,12 +16300,6 @@ dependencies = [ "try-lock", ] -[[package]] -name = "wasi" -version = "0.9.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" - [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" @@ -15269,7 +16312,7 @@ version = "0.12.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c1fbb4ef9bbca0c1170e0b00dd28abc9e3b68669821600cad1caaed606583c6d" dependencies = [ - "wasi 0.11.0+wasi-snapshot-preview1", + "wasi", ] [[package]] @@ -15411,7 +16454,24 @@ dependencies = [ "smallvec", "spin 0.9.8", "wasmi_arena", - "wasmi_core", + "wasmi_core 0.13.0", + "wasmparser-nostd", +] + +[[package]] +name = "wasmi" +version = "0.32.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50386c99b9c32bd2ed71a55b6dd4040af2580530fae8bdb9a6576571a80d0cca" +dependencies = [ + "arrayvec 0.7.4", + "multi-stash", + "num-derive", + "num-traits", + "smallvec", + "spin 0.9.8", + "wasmi_collections", + "wasmi_core 0.32.3", "wasmparser-nostd", ] @@ -15421,6 +16481,17 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "104a7f73be44570cac297b3035d76b169d6599637631cf37a1703326a0727073" +[[package]] +name = "wasmi_collections" +version = "0.32.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c128c039340ffd50d4195c3f8ce31aac357f06804cfc494c8b9508d4b30dca4" +dependencies = [ + "ahash 0.8.11", + "hashbrown 0.14.5", + "string-interner", +] + [[package]] name = "wasmi_core" version = "0.13.0" @@ -15433,6 +16504,18 @@ dependencies = [ "paste", ] +[[package]] +name = "wasmi_core" +version = "0.32.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a23b3a7f6c8c3ceeec6b83531ee61f0013c56e51cbf2b14b0f213548b23a4b41" +dependencies = [ + "downcast-rs", + "libm", + "num-traits", + "paste", +] + [[package]] name = "wasmparser" version = "0.102.0" @@ -15669,18 +16752,24 @@ dependencies = [ [[package]] name = "webpki-roots" -version = "0.22.6" +version = "0.25.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1" + +[[package]] +name = "webpki-roots" +version = "0.26.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6c71e40d7d2c34a5106301fb632274ca37242cd0c9d3e64dbece371a40a2d87" +checksum = "bd7c23921eeb1713a4e851530e9b9756e4fb0e89978582942612524cf09f01cd" dependencies = [ - "webpki", + "rustls-pki-types", ] [[package]] name = "westend-runtime" -version = "8.0.1" +version = "15.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4aa5580861b05668a6af845aa271c4f699a2fc26646d524e5b0d9375fb0647e" +checksum = "56b8918bb9fe4938757d4f003b7fa26598a632e350feac4e7477bb6b36e2f2af" dependencies = [ "binary-merkle-tree", "bitvec", @@ -15705,6 +16794,7 @@ dependencies = [ "pallet-beefy-mmr", "pallet-collective", "pallet-conviction-voting", + "pallet-delegated-staking", "pallet-democracy", "pallet-election-provider-multi-phase", "pallet-election-provider-support-benchmarking", @@ -15712,7 +16802,6 @@ dependencies = [ "pallet-fast-unstake", "pallet-grandpa", "pallet-identity", - "pallet-im-online", "pallet-indices", "pallet-membership", "pallet-message-queue", @@ -15751,7 +16840,6 @@ dependencies = [ "polkadot-primitives", "polkadot-runtime-common", "polkadot-runtime-parachains", - "rustc-hex", "scale-info", "serde", "serde_derive", @@ -15782,13 +16870,14 @@ dependencies = [ "staging-xcm-executor", "substrate-wasm-builder", "westend-runtime-constants", + "xcm-runtime-apis", ] [[package]] name = "westend-runtime-constants" -version = "8.0.0" +version = "15.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b080c193714605ce1033311d85035247adca170181cd68a3ad7e3ca87755a14" +checksum = "8c7a91c27c398b11f7633cc2382cbba53b02e7196ebe8fff13c170e54a54e9d8" dependencies = [ "frame-support", "polkadot-primitives", @@ -15891,6 +16980,21 @@ dependencies = [ "windows-targets 0.48.5", ] +[[package]] +name = "windows-sys" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" +dependencies = [ + "windows_aarch64_gnullvm 0.42.2", + "windows_aarch64_msvc 0.42.2", + "windows_i686_gnu 0.42.2", + "windows_i686_msvc 0.42.2", + "windows_x86_64_gnu 0.42.2", + "windows_x86_64_gnullvm 0.42.2", + "windows_x86_64_msvc 0.42.2", +] + [[package]] name = "windows-sys" version = "0.45.0" @@ -16162,40 +17266,45 @@ dependencies = [ [[package]] name = "x25519-dalek" -version = "1.1.1" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a0c105152107e3b96f6a00a65e86ce82d9b125230e1c4302940eca58ff71f4f" +checksum = "c7e468321c81fb07fa7f4c636c3972b9100f0346e5b6a9f2bd0603a52f7ed277" dependencies = [ - "curve25519-dalek 3.2.0", - "rand_core 0.5.1", + "curve25519-dalek", + "rand_core", + "serde", "zeroize", ] [[package]] -name = "x25519-dalek" -version = "2.0.1" +name = "x509-parser" +version = "0.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7e468321c81fb07fa7f4c636c3972b9100f0346e5b6a9f2bd0603a52f7ed277" +checksum = "7069fba5b66b9193bd2c5d3d4ff12b839118f6bcbef5328efafafb5395cf63da" dependencies = [ - "curve25519-dalek 4.1.3", - "rand_core 0.6.4", - "serde", - "zeroize", + "asn1-rs 0.5.2", + "data-encoding", + "der-parser 8.2.0", + "lazy_static", + "nom", + "oid-registry 0.6.1", + "rusticata-macros", + "thiserror", + "time", ] [[package]] name = "x509-parser" -version = "0.14.0" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0ecbeb7b67ce215e40e3cc7f2ff902f94a223acf44995934763467e7b1febc8" +checksum = "fcbc162f30700d6f3f82a24bf7cc62ffe7caea42c0b2cba8bf7f3ae50cf51f69" dependencies = [ - "asn1-rs", - "base64 0.13.1", + "asn1-rs 0.6.2", "data-encoding", - "der-parser", + "der-parser 9.0.0", "lazy_static", "nom", - "oid-registry", + "oid-registry 0.7.0", "rusticata-macros", "thiserror", "time", @@ -16203,9 +17312,9 @@ dependencies = [ [[package]] name = "xcm-emulator" -version = "0.6.0" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b49681988880dd6d08a4d5f6b7cb612a0f12172270349655c1e2f870b3526fd" +checksum = "be630e9b41c5d19d227162afe4cf642be24058b179fb1edbfe132f6328c7bde8" dependencies = [ "cumulus-pallet-parachain-system", "cumulus-pallet-xcmp-queue", @@ -16238,9 +17347,9 @@ dependencies = [ [[package]] name = "xcm-procedural" -version = "8.0.0" +version = "10.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4717a97970a9cda70d7db53cf50d2615c2f6f6b7c857445325b4a39ea7aa2cd" +checksum = "87fb4f14094d65c500a59bcf540cf42b99ee82c706edd6226a92e769ad60563e" dependencies = [ "Inflector", "proc-macro2", @@ -16248,16 +17357,48 @@ dependencies = [ "syn 2.0.66", ] +[[package]] +name = "xcm-runtime-apis" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30fffcd9128a46abd836c37dd001c2cbe122aeb8904cd7b9bac8358564fb7b56" +dependencies = [ + "frame-support", + "parity-scale-codec", + "scale-info", + "sp-api", + "sp-std", + "sp-weights", + "staging-xcm", + "staging-xcm-executor", +] + +[[package]] +name = "xml-rs" +version = "0.8.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "539a77ee7c0de333dcc6da69b177380a0b81e0dacfa4f7344c465a36871ee601" + +[[package]] +name = "xmltree" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7d8a75eaf6557bb84a65ace8609883db44a29951042ada9b393151532e41fcb" +dependencies = [ + "xml-rs", +] + [[package]] name = "yamux" -version = "0.10.2" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5d9ba232399af1783a58d8eb26f6b5006fbefe2dc9ef36bd283324792d03ea5" +checksum = "9ed0164ae619f2dc144909a9f082187ebb5893693d8c0196e8085283ccd4b776" dependencies = [ "futures", "log", "nohash-hasher", "parking_lot 0.12.3", + "pin-project", "rand", "static_assertions", ] diff --git a/Cargo.toml b/Cargo.toml index 7027423c..3c2f5a1c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,175 +2,184 @@ panic = "unwind" [profile.production] +codegen-units = 1 inherits = "release" lto = true -codegen-units = 1 [workspace.package] -authors = ["R0GUE "] +authors = [ "R0GUE " ] +description = "Pop Network makes it easy for smart contract developers to use the Power of Polkadot." edition = "2021" homepage = "https://r0gue.io" license = "Unlicense" repository = "https://github.com/r0gue-io/pop-node/" -description = "Pop Network makes it easy for smart contract developers to use the Power of Polkadot." [workspace] +exclude = [ "extension/contract", "pop-api", "tests/contracts" ] members = [ - "node", - "runtime/devnet", - "runtime/testnet", - "integration-tests", - "pallets/*", - "primitives", + "integration-tests", + "node", + "pallets/*", + "primitives", + "runtime/devnet", + "runtime/mainnet", + "runtime/testnet", ] -exclude = ["extension/contract", "pop-api", "tests/contracts"] resolver = "2" [workspace.dependencies] -codec = { package = "parity-scale-codec", version = "3.0.0", default-features = false, features = [ - "derive", +clap = { version = "4.4.18", features = [ "derive" ] } +codec = { package = "parity-scale-codec", version = "3.6.12", default-features = false, features = [ + "derive", ] } contract-build = "4.1.1" env_logger = "0.11.5" +futures = "0.3.28" hex-literal = "0.4.1" impl-trait-for-tuples = "0.2.2" -log = { version = "0.4.20", default-features = false } -scale-info = { version = "2.10.0", default-features = false, features = [ - "derive", -] } -smallvec = "1.11.0" -serde = "1.0.195" -clap = { version = "4.4.18", features = ["derive"] } -jsonrpsee = { version = "0.20.3", features = ["server"] } -futures = "0.3.28" +jsonrpsee = { version = "0.23.2", features = [ "server" ] } +log = { version = "0.4.21", default-features = false } rand = "0.8.5" -serde_json = "1.0.111" -tracing-subscriber = { version = "0.3", default-features = false } +scale-info = { version = "2.11.1", default-features = false, features = [ + "derive", +] } +serde = "1.0.197" +serde_json = "1.0.114" +smallvec = "1.11.2" subxt = "0.34.0" subxt-signer = "0.34.0" -tokio = { version = "1.36", features = ["macros", "time", "rt-multi-thread"] } +tokio = { version = "1.36", features = [ "macros", "rt-multi-thread", "time" ] } +tracing-subscriber = { version = "0.3", default-features = false } # Build -substrate-wasm-builder = "18.0.1" substrate-build-script-utils = "11.0.0" +substrate-wasm-builder = "23.0.0" # Local pallet-api = { path = "pallets/api", default-features = false } pop-chain-extension = { path = "./extension", default-features = false } +pop-primitives = { path = "./primitives", default-features = false } +pop-runtime-common = { path = "runtime/common", default-features = false } pop-runtime-devnet = { path = "runtime/devnet", default-features = true } # default-features=true required for `-p pop-node` builds +pop-runtime-mainnet = { path = "runtime/mainnet", default-features = true } # default-features=true required for `-p pop-node` builds pop-runtime-testnet = { path = "runtime/testnet", default-features = true } # default-features=true required for `-p pop-node` builds -pop-runtime-common = { path = "runtime/common", default-features = false } -pop-primitives = { path = "./primitives", default-features = false } # Substrate -sc-basic-authorship = "0.35.0" -sc-chain-spec = "28.0.0" -sc-cli = "0.37.0" -sc-client-api = "29.0.0" -sc-offchain = "30.0.0" -sc-consensus = "0.34.0" -sc-executor = "0.33.0" -sc-network = "0.35.0" -sc-network-sync = "0.34.0" -sc-rpc = "30.0.0" -sc-service = "0.36.0" -sc-sysinfo = "28.0.0" -sc-telemetry = "16.0.0" -sc-tracing = "29.0.0" -sc-transaction-pool = "29.0.0" -sc-transaction-pool-api = "29.0.0" -frame-benchmarking = { version = "29.0.0", default-features = false } -frame-benchmarking-cli = "33.0.0" -frame-executive = { version = "29.0.0", default-features = false } -frame-support = { version = "29.0.2", default-features = false } -frame-system = { version = "29.0.0", default-features = false } -frame-system-benchmarking = { version = "29.0.0", default-features = false } -frame-system-rpc-runtime-api = { version = "27.0.0", default-features = false } -frame-try-runtime = { version = "0.35.0", default-features = false } -pallet-aura = { version = "28.0.0", default-features = false, features = [ - "experimental", -] } -pallet-authorship = { version = "29.0.0", default-features = false } -pallet-assets = { version = "30.0.0", default-features = false } -pallet-balances = { version = "29.0.2", default-features = false } -pallet-contracts = { version = "28.0.0", default-features = false } -pallet-message-queue = { version = "32.0.0", default-features = false } -pallet-multisig = { version = "29.0.0", default-features = false } -pallet-nft-fractionalization = { version = "11.0.0", default-features = false } -pallet-nfts = { version = "23.0.0", default-features = false } -pallet-nfts-runtime-api = { version = "15.0.0", default-features = false } -pallet-preimage = { version = "29.0.0", default-features = false } -pallet-proxy = { version = "29.0.0", default-features = false } -pallet-scheduler = { version = "30.0.0", default-features = false } -pallet-session = { version = "29.0.0", default-features = false } -pallet-sudo = { version = "29.0.0", default-features = false } -pallet-timestamp = { version = "28.0.0", default-features = false } -pallet-transaction-payment = { version = "29.0.2", default-features = false } -pallet-transaction-payment-rpc = "31.0.0" -pallet-transaction-payment-rpc-runtime-api = { version = "29.0.0", default-features = false } -pallet-utility = { version = "29.0.0", default-features = false } -sp-api = { version = "27.0.1", default-features = false } -sp-authority-discovery = { version = "27.0.0", default-features = false } -sp-block-builder = { version = "27.0.0", default-features = false } -sp-blockchain = "29.0.0" -sp-consensus-aura = { version = "0.33.0", default-features = false } -sp-consensus-babe = { version = "0.33.0", default-features = false } -sp-consensus-beefy = { version = "14.0.0", default-features = false } -sp-consensus-grandpa = { version = "14.0.0", default-features = false } -sp-core = { version = "29.0.0", default-features = false } -sp-keystore = "0.35.0" -sp-io = { version = "31.0.0", default-features = false } -sp-genesis-builder = { version = "0.8.0", default-features = false } -sp-inherents = { version = "27.0.0", default-features = false } -sp-offchain = { version = "27.0.0", default-features = false } -sp-runtime = { version = "32.0.0", default-features = false } -sp-timestamp = "27.0.0" -substrate-frame-rpc-system = "29.0.0" -substrate-prometheus-endpoint = "0.17.0" -sp-session = { version = "28.0.0", default-features = false } +frame-benchmarking = { version = "36.0.0", default-features = false } +frame-benchmarking-cli = "40.0.0" +frame-executive = { version = "36.0.0", default-features = false } +frame-metadata-hash-extension = { version = "0.4.0", default-features = false } +frame-support = { version = "36.0.0", default-features = false } +frame-support-procedural = { version = "=30.0.1", default-features = false } +frame-system = { version = "36.1.0", default-features = false } +frame-system-benchmarking = { version = "36.0.0", default-features = false } +frame-system-rpc-runtime-api = { version = "33.0.0", default-features = false } +frame-try-runtime = { version = "0.42.0", default-features = false } +pallet-assets = { version = "37.0.0", default-features = false } +pallet-aura = { version = "35.0.0", default-features = false } +pallet-authorship = { version = "36.0.0", default-features = false } +pallet-balances = { version = "37.0.0", default-features = false } +pallet-contracts = { version = "35.0.0", default-features = false } +pallet-message-queue = { version = "39.0.0", default-features = false } +pallet-multisig = { version = "36.0.0", default-features = false } +pallet-nft-fractionalization = { version = "18.0.0", default-features = false } +pallet-nfts = { version = "30.0.0", default-features = false } +pallet-nfts-runtime-api = { version = "22.0.0", default-features = false } +pallet-preimage = { version = "36.0.0", default-features = false } +pallet-proxy = { version = "36.0.0", default-features = false } +pallet-scheduler = { version = "37.0.0", default-features = false } +pallet-session = { version = "36.0.0", default-features = false } +pallet-sudo = { version = "36.0.0", default-features = false } +pallet-timestamp = { version = "35.0.0", default-features = false } +pallet-transaction-payment = { version = "36.0.0", default-features = false } +pallet-transaction-payment-rpc = "38.0.0" +pallet-transaction-payment-rpc-runtime-api = { version = "36.0.0", default-features = false } +pallet-utility = { version = "36.0.0", default-features = false } +prometheus-endpoint = { version = "0.17.0", default-features = false, package = "substrate-prometheus-endpoint" } +sc-basic-authorship = "0.42.0" +sc-chain-spec = "35.0.0" +sc-cli = "0.44.0" +sc-client-api = "35.1.0" +sc-consensus = "0.41.0" +sc-executor = "0.39.0" +sc-network = "0.42.0" +sc-network-sync = "0.41.0" +sc-offchain = "37.0.0" +sc-rpc = "37.0.0" +sc-service = "0.43.0" +sc-sysinfo = "35.0.0" +sc-telemetry = "22.0.0" +sc-tracing = "35.0.0" +sc-transaction-pool = "35.0.0" +sc-transaction-pool-api = "35.0.0" +sp-api = { version = "33.0.0", default-features = false } +sp-authority-discovery = { version = "33.0.0", default-features = false } +sp-block-builder = { version = "33.0.0", default-features = false } +sp-blockchain = "35.1.0" +sp-consensus-aura = { version = "0.39.0", default-features = false } +sp-consensus-babe = { version = "0.39.0", default-features = false } +sp-consensus-beefy = { version = "20.0.0", default-features = false } +sp-consensus-grandpa = { version = "20.0.0", default-features = false } +sp-core = { version = "34.0.0", default-features = false } +sp-genesis-builder = { version = "0.14.0", default-features = false } +sp-inherents = { version = "33.0.0", default-features = false } +sp-io = { version = "37.0.0", default-features = false } +sp-keystore = "0.40.0" +sp-offchain = { version = "33.0.0", default-features = false } +sp-runtime = { version = "=38.0.0", default-features = false } +sp-session = { version = "34.0.0", default-features = false } sp-std = { version = "14.0.0", default-features = false } -sp-transaction-pool = { version = "27.0.0", default-features = false } -sp-version = { version = "30.0.0", default-features = false } +sp-timestamp = "33.0.0" +sp-transaction-pool = { version = "33.0.0", default-features = false } +sp-version = { version = "36.0.0", default-features = false } +substrate-frame-rpc-system = "36.0.0" # Polkadot -pallet-xcm = { version = "8.0.5", default-features = false } -polkadot-cli = "8.0.0" -polkadot-parachain-primitives = { version = "7.0.0", default-features = false } -polkadot-runtime-parachains = { version = "8.0.3", default-features = false } -polkadot-primitives = { version = "8.0.1", default-features = false } -polkadot-runtime-common = { version = "8.0.3", default-features = false } -xcm = { package = "staging-xcm", version = "8.0.1", default-features = false } -xcm-builder = { package = "staging-xcm-builder", version = "8.0.3", default-features = false } -xcm-executor = { package = "staging-xcm-executor", version = "8.0.2", default-features = false } +pallet-xcm = { version = "15.0.0", default-features = false } +polkadot-cli = "15.0.0" +polkadot-parachain-primitives = { version = "13.0.0", default-features = false } +polkadot-primitives = { version = "14.0.0", default-features = false } +polkadot-runtime-common = { version = "15.0.0", default-features = false } +polkadot-runtime-parachains = { version = "15.0.3", default-features = false } +rococo-runtime = { version = "15.0.0", default-features = false } +rococo-runtime-constants = { version = "15.0.0", default-features = false } +xcm = { version = "14.0.3", package = "staging-xcm", default-features = false } +xcm-builder = { version = "15.0.0", package = "staging-xcm-builder", default-features = false } +xcm-executor = { version = "15.0.0", package = "staging-xcm-executor", default-features = false } # Cumulus -asset-test-utils = { version = "8.0.1", default-features = false } -cumulus-pallet-aura-ext = { version = "0.8.0", default-features = false } -cumulus-pallet-parachain-system = { version = "0.8.1", default-features = false, features = [ - "parameterized-consensus-hook", -] } -cumulus-pallet-session-benchmarking = { version = "10.0.0", default-features = false } -cumulus-pallet-xcm = { version = "0.8.0", default-features = false } -cumulus-pallet-xcmp-queue = { version = "0.8.0", default-features = false } -cumulus-primitives-aura = { version = "0.8.0", default-features = false } -cumulus-primitives-core = { version = "0.8.0", default-features = false } -cumulus-primitives-utility = { version = "0.8.1", default-features = false } -emulated-integration-tests-common = { version = "4.0.0", default-features = false } -pallet-collator-selection = { version = "10.0.3", default-features = false } -parachains-common = { version = "8.0.1", default-features = false } -parachain-info = { package = "staging-parachain-info", version = "0.8.0", default-features = false } -cumulus-primitives-parachain-inherent = "0.8.0" -cumulus-relay-chain-interface = "0.8.0" +asset-hub-rococo-runtime = { version = "0.19.0", default-features = false } +asset-test-utils = { version = "15.0.0", default-features = false } color-print = "0.3.4" -cumulus-client-cli = "0.8.0" -cumulus-client-collator = "0.8.0" -cumulus-client-consensus-aura = "0.8.0" -cumulus-client-consensus-common = "0.8.0" -cumulus-client-consensus-proposer = "0.8.0" -cumulus-client-service = "0.8.0" +cumulus-client-cli = "0.15.0" +cumulus-client-collator = "0.15.0" +cumulus-client-consensus-aura = "0.15.0" +cumulus-client-consensus-common = "0.15.0" +cumulus-client-consensus-proposer = "0.14.0" +cumulus-client-service = "0.15.0" +cumulus-pallet-aura-ext = { version = "0.15.0", default-features = false } +cumulus-pallet-parachain-system = { version = "0.15.0", default-features = false } +cumulus-pallet-session-benchmarking = { version = "17.0.0", default-features = false } +cumulus-pallet-xcm = { version = "0.15.0", default-features = false } +cumulus-pallet-xcmp-queue = { version = "0.15.0", default-features = false } +cumulus-primitives-aura = { version = "0.14.0", default-features = false } +cumulus-primitives-core = { version = "0.14.0", default-features = false } +cumulus-primitives-parachain-inherent = "0.14.0" +cumulus-primitives-storage-weight-reclaim = { version = "6.0.2", default-features = false } +cumulus-primitives-utility = { version = "0.15.0", default-features = false } +cumulus-relay-chain-interface = "0.15.0" +emulated-integration-tests-common = { version = "11.0.0", default-features = false } +pallet-collator-selection = { version = "17.0.0", default-features = false } +parachain-info = { version = "0.15.0", package = "staging-parachain-info", default-features = false } +parachains-common = { version = "15.0.0", default-features = false } + +# TODO: Paseo (note: using polkadot as stopgap until paseo updated to polkadot sdk v1.14.0) +asset-hub-paseo-runtime = { git = "https://github.com/polkadot-fellows/runtimes", default-features = false, package = "asset-hub-polkadot-runtime" } +paseo-runtime = { git = "https://github.com/polkadot-fellows/runtimes", default-features = false, package = "polkadot-runtime" } +paseo-runtime-constants = { git = "https://github.com/polkadot-fellows/runtimes", default-features = false, package = "polkadot-runtime-constants" } # Paseo -asset-hub-paseo-runtime = { git = "https://github.com/paseo-network/runtimes/", tag = "v1.2.5-system-chains", default-features = false } -paseo-runtime = { git = "https://github.com/paseo-network/runtimes/", tag = "v1.2.5-system-chains", default-features = false } -paseo-runtime-constants = { git = "https://github.com/paseo-network/runtimes/", tag = "v1.2.5-system-chains", default-features = false } +# asset-hub-paseo-runtime = { git = "https://github.com/paseo-network/runtimes/", tag = "v1.2.5-system-chains", default-features = false } +# paseo-runtime = { git = "https://github.com/paseo-network/runtimes/", tag = "v1.2.5-system-chains", default-features = false } +# paseo-runtime-constants = { git = "https://github.com/paseo-network/runtimes/", tag = "v1.2.5-system-chains", default-features = false } diff --git a/README.md b/README.md index 2ad8d31d..f178037d 100644 --- a/README.md +++ b/README.md @@ -34,7 +34,7 @@ cargo install pop-cli You can spawn a local network as follows: ```shell -pop up parachain -f ./networks/paseo.toml +pop up parachain -f ./networks/testnet.toml ``` Note: `pop` will automatically source the necessary `polkadot` binaries. Currently, these will have to be built if on a diff --git a/extension/Cargo.toml b/extension/Cargo.toml index 268365be..6ca5e071 100644 --- a/extension/Cargo.toml +++ b/extension/Cargo.toml @@ -1,16 +1,16 @@ [package] -name = "pop-chain-extension" -version = "0.1.0" authors.workspace = true description.workspace = true -license.workspace = true -homepage.workspace = true -repository.workspace = true edition.workspace = true +homepage.workspace = true +license.workspace = true +name = "pop-chain-extension" publish = false +repository.workspace = true +version = "0.1.0" [package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] +targets = [ "x86_64-unknown-linux-gnu" ] [dependencies] codec.workspace = true @@ -36,25 +36,25 @@ scale-info.workspace = true sp-io.workspace = true [features] -default = ["std"] -std = [ - "log/std", - "codec/std", - "frame-support/std", - "frame-system/std", - "pallet-balances/std", - "pallet-contracts/std", - "pallet-timestamp/std", - "sp-runtime/std", - "sp-core/std", - "sp-io/std", - "sp-std/std", -] +default = [ "std" ] runtime-benchmarks = [ - "frame-support/runtime-benchmarks", - "frame-system/runtime-benchmarks", - "pallet-balances/runtime-benchmarks", - "pallet-contracts/runtime-benchmarks", - "pallet-timestamp/runtime-benchmarks", - "sp-runtime/runtime-benchmarks", + "frame-support/runtime-benchmarks", + "frame-system/runtime-benchmarks", + "pallet-balances/runtime-benchmarks", + "pallet-contracts/runtime-benchmarks", + "pallet-timestamp/runtime-benchmarks", + "sp-runtime/runtime-benchmarks", +] +std = [ + "codec/std", + "frame-support/std", + "frame-system/std", + "log/std", + "pallet-balances/std", + "pallet-contracts/std", + "pallet-timestamp/std", + "sp-core/std", + "sp-io/std", + "sp-runtime/std", + "sp-std/std", ] diff --git a/extension/contract/Cargo.toml b/extension/contract/Cargo.toml index 97ecabf9..52c56f66 100755 --- a/extension/contract/Cargo.toml +++ b/extension/contract/Cargo.toml @@ -1,9 +1,9 @@ [package] -authors = ["R0GUE "] -name = "proxy" +authors = [ "R0GUE " ] description = "Simple contract for proxying a call to a chain extension." -version = "0.1.0" edition = "2021" +name = "proxy" +version = "0.1.0" [dependencies] ink = { version = "5.0.0", default-features = false } @@ -12,5 +12,5 @@ ink = { version = "5.0.0", default-features = false } path = "lib.rs" [features] -default = ["std"] -std = ["ink/std"] +default = [ "std" ] +std = [ "ink/std" ] diff --git a/extension/src/decoding.rs b/extension/src/decoding.rs index 9405aa5b..7269a49a 100644 --- a/extension/src/decoding.rs +++ b/extension/src/decoding.rs @@ -1,7 +1,8 @@ -use super::*; use sp_runtime::DispatchError; use sp_std::vec::Vec; +use super::*; + /// Trait for decoding data read from contract memory. pub trait Decode { /// The output type to be decoded. @@ -42,6 +43,7 @@ pub trait Processor { pub struct Identity(PhantomData); impl Processor for Identity { type Value = Value; + const LOG_TARGET: &'static str = ""; fn process(value: Self::Value, _env: &impl Environment) -> Self::Value { @@ -59,9 +61,10 @@ impl< Logger: LogTarget, > Decode for Decodes { + type Error = Error; type Output = Output; type Processor = ValueProcessor; - type Error = Error; + const LOG_TARGET: &'static str = Logger::LOG_TARGET; /// Decodes data read from contract memory. @@ -99,13 +102,14 @@ impl Get for DecodingFailed { #[cfg(test)] mod tests { + use codec::{Decode as OriginalDecode, Encode}; + use frame_support::assert_ok; + use super::*; use crate::{ extension::read_from_buffer_weight, mock::{MockEnvironment, RemoveFirstByte, Test}, }; - use codec::{Decode as OriginalDecode, Encode}; - use frame_support::assert_ok; type EnumDecodes = Decodes, DecodingFailed>; diff --git a/extension/src/environment.rs b/extension/src/environment.rs index e5eff083..dc3818e8 100644 --- a/extension/src/environment.rs +++ b/extension/src/environment.rs @@ -1,9 +1,11 @@ -use crate::AccountIdOf; use core::fmt::Debug; + use frame_support::pallet_prelude::Weight; use pallet_contracts::chain_extension::{BufInBufOutState, ChargedAmount, Result, State}; use sp_std::vec::Vec; +use crate::AccountIdOf; + /// Provides access to the parameters passed to a chain extension and its execution environment. /// /// A wrapper trait for `pallet_contracts::chain_extension::Environment`. All comments have been @@ -182,6 +184,7 @@ pub(crate) struct ExternalEnvironment<'a, T: pallet_contracts::chain_extension:: impl<'a, E: pallet_contracts::chain_extension::Ext> Ext for ExternalEnvironment<'a, E> { type AccountId = AccountIdOf; + fn address(&self) -> &Self::AccountId { self.0.address() } diff --git a/extension/src/functions.rs b/extension/src/functions.rs index 16ca1f1c..b1a046ea 100644 --- a/extension/src/functions.rs +++ b/extension/src/functions.rs @@ -1,6 +1,7 @@ -use super::*; use core::fmt::Debug; +use super::*; + /// A chain extension function. pub trait Function { /// The configuration of the contracts module. @@ -167,6 +168,7 @@ pub struct DefaultConverter(PhantomData); impl>> Converter for DefaultConverter { type Source = T; type Target = Vec; + const LOG_TARGET: &'static str = ""; fn convert(value: Self::Source, _env: &impl Environment) -> Self::Target { @@ -199,10 +201,11 @@ impl ErrorConverter for () { #[impl_trait_for_tuples::impl_for_tuples(1, 10)] #[tuple_types_custom_trait_bound(Function + Matches)] impl Function for Tuple { - for_tuples!( where #( Tuple: Function )* ); type Config = Runtime; type Error = (); + for_tuples!( where #( Tuple: Function )* ); + fn execute( env: &mut (impl Environment> + BufIn + BufOut), ) -> Result { @@ -222,17 +225,18 @@ impl Function for Tuple { #[cfg(test)] mod tests { + use codec::Encode; + use frame_support::traits::{Everything, Nothing}; + use frame_system::Call; + use mock::{new_test_ext, Functions, MockEnvironment, RuntimeCall, RuntimeRead, Test}; + use sp_core::ConstU32; + use super::*; use crate::{ extension::{read_from_buffer_weight, write_to_contract_weight}, matching::WithFuncId, mock::{Noop, NoopFuncId, INVALID_FUNC_ID}, }; - use codec::Encode; - use frame_support::traits::{Everything, Nothing}; - use frame_system::Call; - use mock::{new_test_ext, Functions, MockEnvironment, RuntimeCall, RuntimeRead, Test}; - use sp_core::ConstU32; type FuncId = ConstU32<42>; @@ -352,21 +356,26 @@ mod tests { #[test] fn dispatch_call_adjusts_weight() { + let migrate_weight = ::WeightInfo::migrate(); + let migration_noop_weight = + ::WeightInfo::migration_noop(); new_test_ext().execute_with(|| { // Attempt to perform non-existent migration with additional weight limit specified. - let weight_limit = Weight::from_parts(123456789, 12345); + let extra_weight = Weight::from_parts(123456789, 12345); + let weight_limit = migration_noop_weight.saturating_add(extra_weight); let call = RuntimeCall::Contracts(pallet_contracts::Call::migrate { weight_limit }); let encoded_call = call.encode(); let mut env = MockEnvironment::new(FuncId::get(), encoded_call.clone()); let expected: DispatchError = pallet_contracts::Error::::NoMigrationPerformed.into(); assert_eq!(DispatchCall::execute(&mut env).err().unwrap(), expected); + // Ensure pre-dispatch weight is weight function + weight limit + assert_eq!(call.get_dispatch_info().weight, migrate_weight + weight_limit); assert_eq!( env.charged(), read_from_buffer_weight(encoded_call.len() as u32) + - // Weight limit subtracted from pre-dispatch weight charged on failure. call.get_dispatch_info().weight - - weight_limit + extra_weight ); }) } diff --git a/extension/src/lib.rs b/extension/src/lib.rs index 875867f8..c2480c06 100644 --- a/extension/src/lib.rs +++ b/extension/src/lib.rs @@ -1,6 +1,7 @@ #![cfg_attr(not(feature = "std"), no_std)] use core::marker::PhantomData; + pub use decoding::{Decode, Decodes, DecodingFailed, Identity, Processor}; pub use environment::{BufIn, BufOut, Environment, Ext}; use frame_support::{ @@ -109,13 +110,14 @@ fn default_log_target_works() { #[cfg(test)] mod extension { + use codec::Encode; + use frame_system::Call; + use super::*; use crate::mock::{ new_test_ext, DispatchExtFuncId, MockEnvironment, NoopFuncId, ReadExtFuncId, RuntimeCall, RuntimeRead, Test, INVALID_FUNC_ID, }; - use codec::Encode; - use frame_system::Call; #[test] fn call_works() { diff --git a/extension/src/matching.rs b/extension/src/matching.rs index 5966b9ff..0dcdd34d 100644 --- a/extension/src/matching.rs +++ b/extension/src/matching.rs @@ -37,9 +37,10 @@ impl> Matches for WithFuncId { #[cfg(test)] mod tests { + use sp_core::{ConstU16, ConstU32}; + use super::*; use crate::mock::MockEnvironment; - use sp_core::{ConstU16, ConstU32}; #[test] fn equals_matches() { diff --git a/extension/src/mock.rs b/extension/src/mock.rs index 688bad51..13ffbf47 100644 --- a/extension/src/mock.rs +++ b/extension/src/mock.rs @@ -1,8 +1,5 @@ -use crate::{ - decoding::Identity, environment, matching::WithFuncId, AccountIdOf, ContractWeightsOf, - Converter, Decodes, DecodingFailed, DefaultConverter, DispatchCall, Extension, Function, - Matches, Processor, ReadState, Readable, -}; +use std::marker::PhantomData; + use codec::{Decode, Encode}; use frame_support::{ derive_impl, @@ -10,10 +7,15 @@ use frame_support::{ parameter_types, traits::{fungible::Inspect, ConstU32, Everything, Nothing}, }; -use frame_system::pallet_prelude::BlockNumberFor; +use frame_system::{pallet_prelude::BlockNumberFor, EnsureSigned}; use pallet_contracts::{chain_extension::RetVal, DefaultAddressGenerator, Frame, Schedule}; use sp_runtime::{BuildStorage, Perbill}; -use std::marker::PhantomData; + +use crate::{ + decoding::Identity, environment, matching::WithFuncId, AccountIdOf, ContractWeightsOf, + Converter, Decodes, DecodingFailed, DefaultConverter, DispatchCall, Extension, Function, + Matches, Processor, ReadState, Readable, +}; pub(crate) const ALICE: u64 = 1; pub(crate) const DEBUG_OUTPUT: pallet_contracts::DebugInfo = @@ -65,8 +67,8 @@ frame_support::construct_runtime!( #[derive_impl(frame_system::config_preludes::TestDefaultConfig as frame_system::DefaultConfig)] impl frame_system::Config for Test { - type AccountId = u64; type AccountData = pallet_balances::AccountData; + type AccountId = u64; type Block = frame_system::mocking::MockBlock; } @@ -80,31 +82,39 @@ impl pallet_balances::Config for Test { impl pallet_timestamp::Config for Test {} impl pallet_contracts::Config for Test { - type Time = Timestamp; - type Randomness = Test; - type Currency = Balances; - type RuntimeEvent = RuntimeEvent; - type RuntimeCall = RuntimeCall; - type CallFilter = (); //TestFilter; + type AddressGenerator = DefaultAddressGenerator; + type ApiVersion = (); + type CallFilter = (); + // TestFilter; type CallStack = [Frame; 5]; - type WeightPrice = (); //Self; - type WeightInfo = (); type ChainExtension = Extension; - type Schedule = MySchedule; + type CodeHashLockupDepositPercent = CodeHashLockupDepositPercent; + type Currency = Balances; + type Debug = (); + // TestDebug; + type DefaultDepositLimit = DefaultDepositLimit; type DepositPerByte = DepositPerByte; type DepositPerItem = DepositPerItem; - type DefaultDepositLimit = DefaultDepositLimit; - type AddressGenerator = DefaultAddressGenerator; + type Environment = (); + type InstantiateOrigin = EnsureSigned; type MaxCodeLen = ConstU32<{ 100 * 1024 }>; - type MaxStorageKeyLen = ConstU32<128>; - type UnsafeUnstableInterface = (); //UnstableInterface; type MaxDebugBufferLen = ConstU32<{ 2 * 1024 * 1024 }>; - type RuntimeHoldReason = RuntimeHoldReason; - type Migrations = (); //crate::migration::codegen::BenchMigrations; - type CodeHashLockupDepositPercent = CodeHashLockupDepositPercent; type MaxDelegateDependencies = MaxDelegateDependencies; - type Debug = (); //TestDebug; - type Environment = (); + type MaxStorageKeyLen = ConstU32<128>; + type Migrations = (); + // crate::migration::codegen::BenchMigrations; + type Randomness = Test; + type RuntimeCall = RuntimeCall; + type RuntimeEvent = RuntimeEvent; + type RuntimeHoldReason = RuntimeHoldReason; + type Schedule = MySchedule; + type Time = Timestamp; + type UnsafeUnstableInterface = (); + // UnstableInterface; + type UploadOrigin = EnsureSigned; + type WeightInfo = (); + type WeightPrice = (); + // Self; type Xcm = (); } @@ -201,6 +211,7 @@ pub(crate) type Functions = ( pub struct Config; impl super::Config for Config { type Functions = Functions; + const LOG_TARGET: &'static str = "pop-chain-extension"; } @@ -209,6 +220,7 @@ impl super::Config for Config { pub struct RemoveFirstByte; impl Processor for RemoveFirstByte { type Value = Vec; + const LOG_TARGET: &'static str = ""; fn process(mut value: Self::Value, _env: &impl crate::Environment) -> Self::Value { @@ -363,6 +375,7 @@ pub(crate) struct UppercaseConverter; impl Converter for UppercaseConverter { type Source = RuntimeResult; type Target = Vec; + const LOG_TARGET: &'static str = ""; fn convert(value: Self::Source, _env: &impl crate::Environment) -> Self::Target { diff --git a/extension/src/tests.rs b/extension/src/tests.rs index 8d527df6..c9588cd3 100644 --- a/extension/src/tests.rs +++ b/extension/src/tests.rs @@ -1,10 +1,6 @@ use core::fmt::Debug; use std::{path::Path, sync::LazyLock}; -use crate::{ - mock::{self, *}, - ErrorConverter, -}; use codec::{Decode, Encode}; use frame_support::weights::Weight; use frame_system::Call; @@ -14,6 +10,11 @@ use sp_runtime::{ ModuleError, }; +use crate::{ + mock::{self, *}, + ErrorConverter, +}; + static CONTRACT: LazyLock> = LazyLock::new(|| initialize_contract("contract/target/ink/proxy.wasm")); diff --git a/integration-tests/Cargo.toml b/integration-tests/Cargo.toml index 0a427f8a..0bbdc053 100644 --- a/integration-tests/Cargo.toml +++ b/integration-tests/Cargo.toml @@ -1,34 +1,39 @@ [package] -name = "integration-tests" authors.workspace = true edition.workspace = true homepage.workspace = true license.workspace = true +name = "integration-tests" repository.workspace = true [dev-dependencies] codec.workspace = true -tracing-subscriber = { workspace = true, features = ["env-filter", "fmt", "std", "tracing-log"] } +tracing-subscriber = { workspace = true, features = [ + "env-filter", + "fmt", + "std", + "tracing-log", +] } # Substrate frame-support.workspace = true pallet-assets.workspace = true pallet-balances.workspace = true pallet-message-queue.workspace = true -sp-core.workspace = true sp-authority-discovery.workspace = true sp-consensus-aura.workspace = true sp-consensus-babe.workspace = true sp-consensus-beefy.workspace = true sp-consensus-grandpa.workspace = true +sp-core.workspace = true sp-runtime.workspace = true # Polkadot +pallet-xcm.workspace = true polkadot-primitives.workspace = true +polkadot-runtime-parachains.workspace = true xcm.workspace = true xcm-executor.workspace = true -polkadot-runtime-parachains.workspace = true -pallet-xcm.workspace = true # Cumulus asset-test-utils.workspace = true @@ -41,56 +46,63 @@ paseo-runtime.workspace = true paseo-runtime-constants.workspace = true # Local -pop-runtime-devnet.workspace = true pop-runtime-common.workspace = true +pop-runtime-devnet.workspace = true +pop-runtime-mainnet.workspace = true [features] -default = ["std"] +default = [ "std" ] +mainnet = [ "pop-runtime-mainnet/default" ] std = [ - "asset-hub-paseo-runtime/std", - "cumulus-primitives-core/std", - "frame-support/std", - "pallet-assets/std", - "pallet-balances/std", - "pallet-message-queue/std", - "pallet-xcm/std", - "paseo-runtime/std", - "paseo-runtime-constants/std", - "polkadot-primitives/std", - "polkadot-runtime-parachains/std", - "pop-runtime-devnet/std", - "sp-authority-discovery/std", - "sp-consensus-aura/std", - "sp-consensus-babe/std", - "sp-consensus-beefy/std", - "sp-consensus-grandpa/std", - "sp-core/std", - "sp-runtime/std", - "xcm-executor/std", - "xcm/std", + "asset-hub-paseo-runtime/std", + "cumulus-primitives-core/std", + "frame-support/std", + "pallet-assets/std", + "pallet-balances/std", + "pallet-message-queue/std", + "pallet-xcm/std", + "paseo-runtime-constants/std", + "paseo-runtime/std", + "polkadot-primitives/std", + "polkadot-runtime-parachains/std", + "pop-runtime-common/std", + "pop-runtime-devnet/std", + "pop-runtime-mainnet/std", + "sp-authority-discovery/std", + "sp-consensus-aura/std", + "sp-consensus-babe/std", + "sp-consensus-beefy/std", + "sp-consensus-grandpa/std", + "sp-core/std", + "sp-runtime/std", + "xcm-executor/std", + "xcm/std", ] runtime-benchmarks = [ - "asset-hub-paseo-runtime/runtime-benchmarks", - "cumulus-primitives-core/runtime-benchmarks", - "frame-support/runtime-benchmarks", - "pallet-assets/runtime-benchmarks", - "pallet-balances/runtime-benchmarks", - "pallet-message-queue/runtime-benchmarks", - "paseo-runtime/runtime-benchmarks", - "polkadot-primitives/runtime-benchmarks", - "pop-runtime-devnet/runtime-benchmarks", - "sp-runtime/runtime-benchmarks", - "xcm-executor/runtime-benchmarks", + "asset-hub-paseo-runtime/runtime-benchmarks", + "cumulus-primitives-core/runtime-benchmarks", + "frame-support/runtime-benchmarks", + "pallet-assets/runtime-benchmarks", + "pallet-balances/runtime-benchmarks", + "pallet-message-queue/runtime-benchmarks", + "paseo-runtime/runtime-benchmarks", + "polkadot-primitives/runtime-benchmarks", + "pop-runtime-common/runtime-benchmarks", + "pop-runtime-devnet/runtime-benchmarks", + "pop-runtime-mainnet/runtime-benchmarks", + "sp-runtime/runtime-benchmarks", + "xcm-executor/runtime-benchmarks", ] try-runtime = [ - "asset-hub-paseo-runtime/try-runtime", - "frame-support/try-runtime", - "pallet-assets/try-runtime", - "pallet-balances/std", - "pallet-message-queue/try-runtime", - "paseo-runtime/try-runtime", - "pop-runtime-devnet/try-runtime", - "sp-runtime/try-runtime", + "asset-hub-paseo-runtime/try-runtime", + "frame-support/try-runtime", + "pallet-assets/try-runtime", + "pallet-balances/std", + "pallet-message-queue/try-runtime", + "paseo-runtime/try-runtime", + "pop-runtime-devnet/try-runtime", + "pop-runtime-mainnet/try-runtime", + "sp-runtime/try-runtime", ] diff --git a/integration-tests/src/chains/asset_hub_paseo/mod.rs b/integration-tests/src/chains/asset_hub_paseo/mod.rs index 51dae063..0a9620e3 100644 --- a/integration-tests/src/chains/asset_hub_paseo/mod.rs +++ b/integration-tests/src/chains/asset_hub_paseo/mod.rs @@ -1,6 +1,5 @@ pub(crate) mod genesis; -use crate::chains::paseo::Paseo; use emulated_integration_tests_common::{ impl_accounts_helpers_for_parachain, impl_assert_events_helpers_for_parachain, impl_assets_helpers_for_parachain, impl_foreign_assets_helpers_for_parachain, @@ -34,6 +33,6 @@ decl_test_parachains! { // AssetHubPaseo implementation impl_accounts_helpers_for_parachain!(AssetHubPaseo); impl_assert_events_helpers_for_parachain!(AssetHubPaseo); -impl_assets_helpers_for_parachain!(AssetHubPaseo, Paseo); -impl_foreign_assets_helpers_for_parachain!(AssetHubPaseo, Paseo); +impl_assets_helpers_for_parachain!(AssetHubPaseo); +impl_foreign_assets_helpers_for_parachain!(AssetHubPaseo, xcm::v3::Location); impl_xcm_helpers_for_parachain!(AssetHubPaseo); diff --git a/integration-tests/src/chains/paseo/genesis.rs b/integration-tests/src/chains/paseo/genesis.rs index d4c29ca2..0ecdb1ff 100644 --- a/integration-tests/src/chains/paseo/genesis.rs +++ b/integration-tests/src/chains/paseo/genesis.rs @@ -1,6 +1,5 @@ use emulated_integration_tests_common::{ - accounts, build_genesis_storage, get_account_id_from_seed, get_from_seed, get_host_config, - validators, + accounts, build_genesis_storage, get_from_seed, get_host_config, validators, }; use paseo_runtime_constants::currency::UNITS as PAS; use polkadot_primitives::{AssignmentId, Balance, ValidatorId}; @@ -8,7 +7,7 @@ use sp_authority_discovery::AuthorityId as AuthorityDiscoveryId; use sp_consensus_babe::AuthorityId as BabeId; use sp_consensus_beefy::ecdsa_crypto::AuthorityId as BeefyId; use sp_consensus_grandpa::AuthorityId as GrandpaId; -use sp_core::{sr25519, storage::Storage}; +use sp_core::storage::Storage; pub(crate) const ED: Balance = paseo_runtime_constants::currency::EXISTENTIAL_DEPOSIT; const ENDOWMENT: u128 = 1_000_000 * PAS; @@ -58,12 +57,13 @@ pub(crate) fn genesis() -> Storage { }, babe: paseo_runtime::BabeConfig { authorities: Default::default(), - epoch_config: Some(paseo_runtime::BABE_GENESIS_EPOCH_CONFIG), + epoch_config: paseo_runtime::BABE_GENESIS_EPOCH_CONFIG, ..Default::default() }, - sudo: paseo_runtime::SudoConfig { - key: Some(get_account_id_from_seed::("Alice")), - }, + // TODO: sudo pallet is not configured in polkadot runtime + // sudo: runtime::SudoConfig { + // key: Some(get_account_id_from_seed::("Alice")), + // }, configuration: paseo_runtime::ConfigurationConfig { config: get_host_config() }, registrar: paseo_runtime::RegistrarConfig { next_free_para_id: polkadot_primitives::LOWEST_PUBLIC_ID, diff --git a/integration-tests/src/chains/paseo/mod.rs b/integration-tests/src/chains/paseo/mod.rs index 735807e5..4df1d2af 100644 --- a/integration-tests/src/chains/paseo/mod.rs +++ b/integration-tests/src/chains/paseo/mod.rs @@ -8,7 +8,7 @@ use emulated_integration_tests_common::{ // Paseo declaration decl_test_relay_chains! { - #[api_version(10)] + #[api_version(11)] pub struct Paseo { genesis = genesis::genesis(), on_init = (), @@ -18,7 +18,8 @@ decl_test_relay_chains! { }, pallets = { XcmPallet: paseo_runtime::XcmPallet, - Sudo: paseo_runtime::Sudo, + // TODO: sudo pallet is not configured in polkadot runtime + // Sudo: paseo_runtime::Sudo, Balances: paseo_runtime::Balances, Hrmp: paseo_runtime::Hrmp, } diff --git a/integration-tests/src/chains/pop_network/mod.rs b/integration-tests/src/chains/pop_network/mod.rs index 42b2cc2e..41daed27 100644 --- a/integration-tests/src/chains/pop_network/mod.rs +++ b/integration-tests/src/chains/pop_network/mod.rs @@ -1,31 +1,32 @@ pub(crate) mod genesis; -use crate::chains::paseo::Paseo; use emulated_integration_tests_common::{ impl_accounts_helpers_for_parachain, impl_assert_events_helpers_for_parachain, - impl_assets_helpers_for_parachain, impl_xcm_helpers_for_parachain, impls::Parachain, - xcm_emulator::decl_test_parachains, + impl_xcm_helpers_for_parachain, impls::Parachain, xcm_emulator::decl_test_parachains, }; use frame_support::traits::OnInitialize; +#[cfg(not(feature = "mainnet"))] +use pop_runtime_devnet as runtime; +#[cfg(feature = "mainnet")] +use pop_runtime_mainnet as runtime; // PopNetwork Parachain declaration decl_test_parachains! { pub struct PopNetwork { genesis = genesis::genesis(), on_init = { - pop_runtime_devnet::AuraExt::on_initialize(1); + runtime::AuraExt::on_initialize(1); }, - runtime = pop_runtime_devnet, + runtime = runtime, core = { - XcmpMessageHandler: pop_runtime_devnet::XcmpQueue, - LocationToAccountId: pop_runtime_devnet::config::xcm::LocationToAccountId, - ParachainInfo: pop_runtime_devnet::ParachainInfo, + XcmpMessageHandler: runtime::XcmpQueue, + LocationToAccountId: runtime::config::xcm::LocationToAccountId, + ParachainInfo: runtime::ParachainInfo, MessageOrigin: cumulus_primitives_core::AggregateMessageOrigin, }, pallets = { - PolkadotXcm: pop_runtime_devnet::PolkadotXcm, - Assets: pop_runtime_devnet::Assets, - Balances: pop_runtime_devnet::Balances, + PolkadotXcm: runtime::PolkadotXcm, + Balances: runtime::Balances, } }, } @@ -33,5 +34,4 @@ decl_test_parachains! { // PopNetwork implementation impl_accounts_helpers_for_parachain!(PopNetwork); impl_assert_events_helpers_for_parachain!(PopNetwork); -impl_assets_helpers_for_parachain!(PopNetwork, Paseo); impl_xcm_helpers_for_parachain!(PopNetwork); diff --git a/integration-tests/src/lib.rs b/integration-tests/src/lib.rs index eddbc103..50513a3e 100644 --- a/integration-tests/src/lib.rs +++ b/integration-tests/src/lib.rs @@ -1,10 +1,5 @@ #![cfg(test)] -use crate::chains::{ - asset_hub_paseo::{genesis::ED as ASSET_HUB_PASEO_ED, AssetHubPaseoParaPallet}, - paseo::{genesis::ED as PASEO_ED, PaseoRelayPallet}, - pop_network::PopNetworkParaPallet, -}; use asset_hub_paseo_runtime::xcm_config::XcmConfig as AssetHubPaseoXcmConfig; use asset_test_utils::xcm_helpers; use chains::{asset_hub_paseo::AssetHubPaseo, paseo::Paseo, pop_network::PopNetwork}; @@ -22,6 +17,12 @@ use pop_runtime_common::Balance; use pop_runtime_devnet::config::xcm::XcmConfig as PopNetworkXcmConfig; use xcm::prelude::*; +use crate::chains::{ + asset_hub_paseo::{genesis::ED as ASSET_HUB_PASEO_ED, AssetHubPaseoParaPallet}, + paseo::{genesis::ED as PASEO_ED, PaseoRelayPallet}, + pop_network::PopNetworkParaPallet, +}; + mod chains; decl_test_networks! { @@ -95,7 +96,7 @@ fn para_receiver_assertions(_: Test) { assert_expected_events!( PopNetworkPara, vec![ - RuntimeEvent::Balances(pallet_balances::Event::Deposit { .. }) => {}, + RuntimeEvent::Balances(pallet_balances::Event::Minted { .. }) => {}, RuntimeEvent::MessageQueue( pallet_message_queue::Event::Processed { success: true, .. } ) => {}, @@ -113,9 +114,7 @@ fn para_to_system_para_sender_assertions(t: ParaToSystemParaTest) { PopNetworkPara, vec![ // Amount to reserve transfer is transferred to Parachain's Sovereign account - RuntimeEvent::Balances( - pallet_balances::Event::Withdraw { who, amount } - ) => { + RuntimeEvent::Balances(pallet_balances::Event::Burned { who, amount }) => { who: *who == t.sender.account_id, amount: *amount == t.args.amount, }, @@ -133,9 +132,7 @@ fn para_to_relay_sender_assertions(t: ParaToRelayTest) { PopNetworkPara, vec![ // Amount to reserve transfer is transferred to Parachain's Sovereign account - RuntimeEvent::Balances( - pallet_balances::Event::Withdraw { who, amount } - ) => { + RuntimeEvent::Balances(pallet_balances::Event::Burned { who, amount }) => { who: *who == t.sender.account_id, amount: *amount == t.args.amount, }, @@ -297,7 +294,7 @@ fn reserve_transfer_native_asset_from_relay_to_para() { test.assert(); let delivery_fees = PaseoRelay::execute_with(|| { - xcm_helpers::transfer_assets_delivery_fees::< + xcm_helpers::teleport_assets_delivery_fees::< ::XcmSender, >( test.args.assets.clone(), 0, test.args.weight_limit, test.args.beneficiary, test.args.dest @@ -353,7 +350,7 @@ fn reserve_transfer_native_asset_from_para_to_relay() { let receiver_balance_after = test.receiver.balance; let delivery_fees = PopNetworkPara::execute_with(|| { - xcm_helpers::transfer_assets_delivery_fees::< + xcm_helpers::teleport_assets_delivery_fees::< ::XcmSender, >( test.args.assets.clone(), 0, test.args.weight_limit, test.args.beneficiary, test.args.dest @@ -401,7 +398,7 @@ fn reserve_transfer_native_asset_from_system_para_to_para() { let receiver_balance_after = test.receiver.balance; let delivery_fees = AssetHubPaseoPara::execute_with(|| { - xcm_helpers::transfer_assets_delivery_fees::< + xcm_helpers::teleport_assets_delivery_fees::< ::XcmSender, >( test.args.assets.clone(), 0, test.args.weight_limit, test.args.beneficiary, test.args.dest @@ -467,7 +464,7 @@ fn reserve_transfer_native_asset_from_para_to_system_para() { let receiver_balance_after = test.receiver.balance; let delivery_fees = PopNetworkPara::execute_with(|| { - xcm_helpers::transfer_assets_delivery_fees::< + xcm_helpers::teleport_assets_delivery_fees::< ::XcmSender, >( test.args.assets.clone(), 0, test.args.weight_limit, test.args.beneficiary, test.args.dest diff --git a/networks/mainnet.toml b/networks/mainnet.toml new file mode 100644 index 00000000..dc1fda4b --- /dev/null +++ b/networks/mainnet.toml @@ -0,0 +1,40 @@ +# pop up parachain -f ./networks/mainnet.toml + +[relaychain] +chain = "paseo-local" + +[relaychain.runtime_genesis_patch.balances] +balances = [ + # Pop sovereign account + ["5Ec4AhPKXY9B4ayGshkz2wFMh7N8gP7XKfAvtt1cigpG9FkJ", 60000000000000000], +] + +[[relaychain.nodes]] +name = "alice" +rpc_port = 8833 +validator = true + +[[relaychain.nodes]] +name = "bob" +validator = true + +[[parachains]] +id = 4001 +chain = "mainnet" +default_command = "./target/release/pop-node" + +[parachains.genesis_overrides.balances] +balances = [ + # Dev accounts + ["5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY", 10000000000000000], + ["5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty", 10000000000000000], + ["5FLSigC9HGRKVhB9FiEo4Y3koPsNmBmLJbpXg2mp1hXcS59Y", 10000000000000000], + ["5DAAnrj7VHTznn2AWBemMuyBwZWs6FNFjdyVXUeYum3PTXFy", 10000000000000000], + ["5HGjWAeFDfFCWPsjFQdVV2Msvz2XtMktvgocEZcCj68kUMaw", 10000000000000000], + ["5CiPPseXPECbkjWCa6MnjNokrgYjMqmKndv2rSnekmSK2DjL", 10000000000000000], +] + +[[parachains.collators]] +name = "pop" +rpc_port = 9944 +args = ["-lruntime::contracts=debug", "-lpopapi::extension=debug"] \ No newline at end of file diff --git a/networks/testnet.toml b/networks/testnet.toml index 15ac9b03..450f0532 100644 --- a/networks/testnet.toml +++ b/networks/testnet.toml @@ -37,4 +37,12 @@ balances = [ [[parachains.collators]] name = "pop" rpc_port = 9944 -args = ["-lruntime::contracts=debug", "-lpopapi::extension=debug"] \ No newline at end of file +args = ["-lruntime::contracts=debug", "-lpopapi::extension=debug", "-lxcm=trace"] + +[[parachains]] +id = 1000 +chain = "asset-hub-rococo-local" + +[[parachains.collators]] +name = "asset-hub" +args = ["-lxcm=trace"] \ No newline at end of file diff --git a/node/Cargo.toml b/node/Cargo.toml index b6f258c4..04de08e0 100644 --- a/node/Cargo.toml +++ b/node/Cargo.toml @@ -1,42 +1,44 @@ [package] -name = "pop-node" -version = "0.1.0-alpha" authors.workspace = true +build = "build.rs" description.workspace = true -license = "Unlicense" -homepage.workspace = true -repository.workspace = true edition.workspace = true -build = "build.rs" +homepage.workspace = true +license = "Unlicense" +name = "pop-node" publish = false +repository.workspace = true +version = "0.2.0-alpha" [dependencies] clap.workspace = true -log.workspace = true codec.workspace = true -serde.workspace = true -jsonrpsee.workspace = true futures.workspace = true +jsonrpsee.workspace = true +log.workspace = true +serde.workspace = true serde_json.workspace = true # Local +pop-runtime-common.workspace = true pop-runtime-devnet.workspace = true +pop-runtime-mainnet.workspace = true pop-runtime-testnet.workspace = true -pop-runtime-common.workspace = true # Substrate frame-benchmarking.workspace = true frame-benchmarking-cli.workspace = true pallet-transaction-payment-rpc.workspace = true +prometheus-endpoint.workspace = true sc-basic-authorship.workspace = true sc-chain-spec.workspace = true sc-cli.workspace = true sc-client-api.workspace = true -sc-offchain.workspace = true sc-consensus.workspace = true sc-executor.workspace = true sc-network.workspace = true sc-network-sync.workspace = true +sc-offchain.workspace = true sc-rpc.workspace = true sc-service.workspace = true sc-sysinfo.workspace = true @@ -49,15 +51,14 @@ sp-block-builder.workspace = true sp-blockchain.workspace = true sp-consensus-aura.workspace = true sp-core.workspace = true -sp-keystore.workspace = true sp-io.workspace = true +sp-keystore.workspace = true sp-offchain.workspace = true sp-runtime.workspace = true sp-session.workspace = true sp-timestamp.workspace = true sp-transaction-pool.workspace = true substrate-frame-rpc-system.workspace = true -substrate-prometheus-endpoint.workspace = true # Polkadot polkadot-cli.workspace = true @@ -65,37 +66,44 @@ polkadot-primitives.workspace = true xcm.workspace = true # Cumulus +color-print.workspace = true cumulus-client-cli.workspace = true cumulus-client-collator.workspace = true cumulus-client-consensus-aura.workspace = true cumulus-client-consensus-common.workspace = true cumulus-client-consensus-proposer.workspace = true -cumulus-primitives-aura.workspace = true cumulus-client-service.workspace = true +cumulus-primitives-aura.workspace = true cumulus-primitives-core.workspace = true cumulus-primitives-parachain-inherent.workspace = true cumulus-relay-chain-interface.workspace = true -color-print.workspace = true [build-dependencies] substrate-build-script-utils.workspace = true +[dev-dependencies] +pallet-multisig.workspace = true + [features] -default = [] runtime-benchmarks = [ - "cumulus-primitives-core/runtime-benchmarks", - "frame-benchmarking-cli/runtime-benchmarks", - "frame-benchmarking/runtime-benchmarks", - "pop-runtime-devnet/runtime-benchmarks", - "pop-runtime-testnet/runtime-benchmarks", - "polkadot-cli/runtime-benchmarks", - "polkadot-primitives/runtime-benchmarks", - "sc-service/runtime-benchmarks", - "sp-runtime/runtime-benchmarks", + "cumulus-primitives-core/runtime-benchmarks", + "frame-benchmarking-cli/runtime-benchmarks", + "frame-benchmarking/runtime-benchmarks", + "polkadot-cli/runtime-benchmarks", + "polkadot-primitives/runtime-benchmarks", + "pop-runtime-common/runtime-benchmarks", + "pop-runtime-devnet/runtime-benchmarks", + "pop-runtime-mainnet/runtime-benchmarks", + "pop-runtime-testnet/runtime-benchmarks", + "sc-service/runtime-benchmarks", + "sp-runtime/runtime-benchmarks", ] try-runtime = [ - "pop-runtime-devnet/try-runtime", - "pop-runtime-testnet/try-runtime", - "polkadot-cli/try-runtime", - "sp-runtime/try-runtime", + "polkadot-cli/try-runtime", + "pop-runtime-devnet/try-runtime", + "pop-runtime-mainnet/try-runtime", + "pop-runtime-testnet/try-runtime", + "sp-runtime/try-runtime", ] + +on-chain-release-build = [ "pop-runtime-mainnet/on-chain-release-build" ] diff --git a/node/src/chain_spec.rs b/node/src/chain_spec.rs index ca6c9542..b41ea8aa 100644 --- a/node/src/chain_spec.rs +++ b/node/src/chain_spec.rs @@ -1,5 +1,6 @@ use cumulus_primitives_core::ParaId; use pop_runtime_common::{AccountId, AuraId, Signature}; +use pop_runtime_mainnet::SudoAddress; use sc_chain_spec::{ChainSpecExtension, ChainSpecGroup}; use sc_service::ChainType; use serde::{Deserialize, Serialize}; @@ -7,12 +8,13 @@ use sp_core::{crypto::Ss58Codec, sr25519, Pair, Public}; use sp_runtime::traits::{IdentifyAccount, Verify}; /// Specialized `ChainSpec` for the development parachain runtime. -pub type DevnetChainSpec = - sc_service::GenericChainSpec; +pub type DevnetChainSpec = sc_service::GenericChainSpec; /// Specialized `ChainSpec` for the testnet parachain runtime. -pub type TestnetChainSpec = - sc_service::GenericChainSpec; +pub type TestnetChainSpec = sc_service::GenericChainSpec; + +/// Specialized `ChainSpec` for the mainnet parachain runtime. +pub type MainnetChainSpec = sc_service::GenericChainSpec; /// The default XCM version to set in genesis config. const SAFE_XCM_VERSION: u32 = xcm::prelude::XCM_VERSION; @@ -20,6 +22,7 @@ const SAFE_XCM_VERSION: u32 = xcm::prelude::XCM_VERSION; pub(crate) enum Relay { Paseo, PaseoLocal, + Polkadot, } /// Helper function to generate a crypto pair from seed @@ -31,11 +34,12 @@ pub fn get_from_seed(seed: &str) -> ::Pu /// The extensions for the [`ChainSpec`]. #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, ChainSpecGroup, ChainSpecExtension)] -#[serde(deny_unknown_fields)] pub struct Extensions { /// The relay chain of the Parachain. + #[serde(alias = "relayChain", alias = "RelayChain")] pub relay_chain: String, /// The id of the Parachain. + #[serde(alias = "paraId", alias = "ParaId")] pub para_id: u32, } @@ -75,12 +79,17 @@ pub fn pop_devnet_session_keys(keys: AuraId) -> pop_runtime_devnet::SessionKeys pub fn pop_testnet_session_keys(keys: AuraId) -> pop_runtime_testnet::SessionKeys { pop_runtime_testnet::SessionKeys { aura: keys } } +/// Generate the session keys from individual elements. +/// +/// The input must be a tuple of individual keys (a single arg for now since we have just one key). +pub fn pop_mainnet_session_keys(keys: AuraId) -> pop_runtime_mainnet::SessionKeys { + pop_runtime_mainnet::SessionKeys { aura: keys } +} fn configure_for_relay( relay: Relay, properties: &mut sc_chain_spec::Properties, ) -> (Extensions, u32) { - properties.insert("ss58Format".into(), 42.into()); let para_id; match relay { @@ -89,10 +98,22 @@ fn configure_for_relay( properties.insert("tokenSymbol".into(), "PAS".into()); properties.insert("tokenDecimals".into(), 10.into()); - let relay_chain = - if let Relay::Paseo = relay { "paseo".into() } else { "paseo-local".into() }; + let relay_chain = if let Relay::Paseo = relay { + properties.insert("ss58Format".into(), 0.into()); + "paseo".into() + } else { + properties.insert("ss58Format".into(), 42.into()); + "paseo-local".into() + }; (Extensions { relay_chain, para_id }, para_id) }, + Relay::Polkadot => { + para_id = 3395; + properties.insert("ss58Format".into(), 0.into()); + properties.insert("tokenSymbol".into(), "DOT".into()); + properties.insert("tokenDecimals".into(), 10.into()); + (Extensions { relay_chain: "polkadot".into(), para_id }, para_id) + }, } } @@ -174,6 +195,83 @@ pub fn testnet_config(relay: Relay) -> TestnetChainSpec { .build() } +pub fn mainnet_config(relay: Relay) -> MainnetChainSpec { + let mut properties = sc_chain_spec::Properties::new(); + let (extensions, para_id) = configure_for_relay(relay, &mut properties); + + let collator_0_account_id: AccountId = + AccountId::from_ss58check("15B6eUkXgoLA3dWruCRYWeBGNC8SCwuqiMtMTM1Zh2auSg3w").unwrap(); + let collator_0_aura_id: AuraId = + AuraId::from_ss58check("15B6eUkXgoLA3dWruCRYWeBGNC8SCwuqiMtMTM1Zh2auSg3w").unwrap(); + + // Multisig account for sudo, generated from the following signatories: + // - 15VPagCVayS6XvT5RogPYop3BJTJzwqR2mCGR1kVn3w58ygg + // - 142zako1kfvrpQ7pJKYR8iGUD58i4wjb78FUsmJ9WcXmkM5z + // - 15k9niqckMg338cFBoz9vWFGwnCtwPBquKvqJEfHApijZkDz + // - 14G3CUFnZUBnHZUhahexSZ6AgemaW9zMHBnGccy3df7actf4 + // - Threshold 2 + let sudo_account_id: AccountId = SudoAddress::get(); + + #[allow(deprecated)] + MainnetChainSpec::builder( + pop_runtime_mainnet::WASM_BINARY.expect("WASM binary was not built, please build it!"), + extensions, + ) + .with_name("Pop Network") + .with_id("pop") + .with_chain_type(ChainType::Live) + .with_genesis_config_patch(mainnet_genesis( + // initial collators. + vec![ + // POP COLLATOR 0 + (collator_0_account_id, collator_0_aura_id), + ], + sudo_account_id, + para_id.into(), + )) + .with_protocol_id("pop") + .with_properties(properties) + .build() +} + +fn mainnet_genesis( + invulnerables: Vec<(AccountId, AuraId)>, + root: AccountId, + id: ParaId, +) -> serde_json::Value { + use pop_runtime_mainnet::EXISTENTIAL_DEPOSIT; + + serde_json::json!({ + "balances": { + "balances": [], + }, + "parachainInfo": { + "parachainId": id, + }, + "collatorSelection": { + "invulnerables": invulnerables.iter().cloned().map(|(acc, _)| acc).collect::>(), + "candidacyBond": EXISTENTIAL_DEPOSIT * 16, + "desiredCandidates": 0, + }, + "session": { + "keys": invulnerables + .into_iter() + .map(|(acc, aura)| { + ( + acc.clone(), // account id + acc, // validator id + pop_mainnet_session_keys(aura), // session keys + ) + }) + .collect::>(), + }, + "polkadotXcm": { + "safeXcmVersion": Some(SAFE_XCM_VERSION), + }, + "sudo": { "key": Some(root) } + }) +} + fn testnet_genesis( invulnerables: Vec<(AccountId, AuraId)>, root: AccountId, @@ -247,3 +345,43 @@ fn devnet_genesis( "sudo": { "key": Some(root) } }) } + +#[test] +fn sudo_key_valid() { + // Source: https://github.com/paritytech/extended-parachain-template/blob/d08cec37117731953119ecaed79522a0812b46f5/node/src/chain_spec.rs#L79 + fn get_multisig_sudo_key(mut authority_set: Vec, threshold: u16) -> AccountId { + assert!(threshold > 0, "Threshold for sudo multisig cannot be 0"); + assert!(!authority_set.is_empty(), "Sudo authority set cannot be empty"); + assert!( + authority_set.len() >= threshold.into(), + "Threshold must be less than or equal to authority set members" + ); + // Sorting is done to deterministically order the multisig set + // So that a single authority set (A, B, C) may generate only a single unique multisig key + // Otherwise, (B, A, C) or (C, A, B) could produce different keys and cause chaos + authority_set.sort(); + + // Define a multisig threshold for `threshold / authority_set.len()` members + pallet_multisig::Pallet::::multi_account_id( + &authority_set[..], + threshold, + ) + } + + assert_eq!( + get_multisig_sudo_key( + vec![ + AccountId::from_ss58check("15VPagCVayS6XvT5RogPYop3BJTJzwqR2mCGR1kVn3w58ygg") + .unwrap(), + AccountId::from_ss58check("142zako1kfvrpQ7pJKYR8iGUD58i4wjb78FUsmJ9WcXmkM5z") + .unwrap(), + AccountId::from_ss58check("15k9niqckMg338cFBoz9vWFGwnCtwPBquKvqJEfHApijZkDz") + .unwrap(), + AccountId::from_ss58check("14G3CUFnZUBnHZUhahexSZ6AgemaW9zMHBnGccy3df7actf4") + .unwrap(), + ], + 2 + ), + SudoAddress::get() + ) +} diff --git a/node/src/cli.rs b/node/src/cli.rs index 665b1129..19532033 100644 --- a/node/src/cli.rs +++ b/node/src/cli.rs @@ -38,11 +38,6 @@ pub enum Subcommand { #[command(subcommand)] Benchmark(frame_benchmarking_cli::BenchmarkCmd), - /// Try-runtime has migrated to a standalone - /// [CLI](). The subcommand exists as a stub and - /// deprecation notice. It will be removed entirely some time after Janurary 2024. - TryRuntime, - /// Key management CLI utilities #[command(subcommand)] Key(sc_cli::KeySubcommand), diff --git a/node/src/command.rs b/node/src/command.rs index a83253fc..9da4052d 100644 --- a/node/src/command.rs +++ b/node/src/command.rs @@ -1,5 +1,6 @@ use std::{net::SocketAddr, path::PathBuf}; +use cumulus_client_service::storage_proof_size::HostFunctions as ReclaimHostFunctions; use cumulus_primitives_core::ParaId; use frame_benchmarking_cli::{BenchmarkCmd, SUBSTRATE_REFERENCE_HARDWARE}; use log::info; @@ -9,19 +10,20 @@ use sc_cli::{ NetworkParams, Result, SharedParams, SubstrateCli, }; use sc_service::config::{BasePath, PrometheusConfig}; -use sp_runtime::traits::AccountIdConversion; +use sp_runtime::traits::HashingFor; use crate::{ chain_spec, chain_spec::Relay, cli::{Cli, RelayChainCli, Subcommand}, - service::{new_partial, DevnetRuntimeExecutor, TestnetRuntimeExecutor}, + service::new_partial, }; #[derive(Debug, PartialEq)] enum Runtime { Devnet, Testnet, + Mainnet, } trait RuntimeResolver { @@ -34,8 +36,14 @@ fn runtime(id: &str) -> Runtime { Runtime::Devnet } else if id.starts_with("test") || id.ends_with("testnet") { Runtime::Testnet + } else if id.eq("pop") || id.ends_with("mainnet") { + Runtime::Mainnet } else { - log::warn!("No specific runtime was recognized for ChainSpec's Id: '{}', so Runtime::Devnet will be used", id); + log::warn!( + "No specific runtime was recognized for ChainSpec's Id: '{}', so Runtime::Devnet will \ + be used", + id + ); Runtime::Devnet } } @@ -67,12 +75,15 @@ fn load_spec(id: &str) -> std::result::Result, String> { "dev" | "devnet" | "dev-paseo" => Box::new(chain_spec::development_config(Relay::PaseoLocal)), "test" | "testnet" | "pop-paseo" => Box::new(chain_spec::testnet_config(Relay::Paseo)), + "pop" | "mainnet" | "pop-polkadot" | "pop-network" => + Box::new(chain_spec::mainnet_config(Relay::Polkadot)), "" | "local" => Box::new(chain_spec::development_config(Relay::PaseoLocal)), path => { let path: PathBuf = path.into(); match path.runtime() { Runtime::Devnet => Box::new(chain_spec::DevnetChainSpec::from_json_file(path)?), Runtime::Testnet => Box::new(chain_spec::TestnetChainSpec::from_json_file(path)?), + Runtime::Mainnet => Box::new(chain_spec::MainnetChainSpec::from_json_file(path)?), } }, }) @@ -89,10 +100,9 @@ impl SubstrateCli for Cli { fn description() -> String { format!( - "Pop Collator\n\nThe command-line arguments provided first will be \ - passed to the parachain node, while the arguments provided after -- will be passed \ - to the relay chain node.\n\n\ - {} -- ", + "Pop Collator\n\nThe command-line arguments provided first will be passed to the \ + parachain node, while the arguments provided after -- will be passed to the relay \ + chain node.\n\n{} -- ", Self::executable_name() ) } @@ -125,10 +135,9 @@ impl SubstrateCli for RelayChainCli { fn description() -> String { format!( - "Pop Collator\n\nThe command-line arguments provided first will be \ - passed to the parachain node, while the arguments provided after -- will be passed \ - to the relay chain node.\n\n\ - {} -- ", + "Pop Collator\n\nThe command-line arguments provided first will be passed to the \ + parachain node, while the arguments provided after -- will be passed to the relay \ + chain node.\n\n{} -- ", Self::executable_name() ) } @@ -156,7 +165,7 @@ macro_rules! construct_async_run { match runner.config().chain_spec.runtime() { Runtime::Devnet => { runner.async_run(|$config| { - let $components = new_partial::( + let $components = new_partial::( &$config )?; let task_manager = $components.task_manager; @@ -165,7 +174,16 @@ macro_rules! construct_async_run { } Runtime::Testnet => { runner.async_run(|$config| { - let $components = new_partial::( + let $components = new_partial::( + &$config + )?; + let task_manager = $components.task_manager; + { $( $code )* }.map(|v| (v, task_manager)) + }) + } + Runtime::Mainnet => { + runner.async_run(|$config| { + let $components = new_partial::( &$config )?; let task_manager = $components.task_manager; @@ -180,15 +198,15 @@ macro_rules! construct_benchmark_partials { ($config:expr, |$partials:ident| $code:expr) => { match $config.chain_spec.runtime() { Runtime::Devnet => { - let $partials = - new_partial::(&$config)?; + let $partials = new_partial::(&$config)?; $code }, Runtime::Testnet => { - let $partials = new_partial::< - pop_runtime_testnet::RuntimeApi, - TestnetRuntimeExecutor, - >(&$config)?; + let $partials = new_partial::(&$config)?; + $code + }, + Runtime::Mainnet => { + let $partials = new_partial::(&$config)?; $code }, } @@ -251,9 +269,7 @@ pub fn run() -> Result<()> { Some(Subcommand::ExportGenesisHead(cmd)) => { let runner = cli.create_runner(cmd)?; runner.sync_run(|config| { - construct_benchmark_partials!(config, |partials| { - cmd.run(partials.client) - }) + construct_benchmark_partials!(config, |partials| cmd.run(partials.client)) }) }, Some(Subcommand::ExportGenesisWasm(cmd)) => { @@ -269,23 +285,24 @@ pub fn run() -> Result<()> { match cmd { BenchmarkCmd::Pallet(cmd) => if cfg!(feature = "runtime-benchmarks") { - runner.sync_run(|config| cmd.run::(config)) + runner.sync_run(|config| { + cmd.run_with_spec::, ReclaimHostFunctions>(Some( + config.chain_spec, + )) + }) } else { - Err("Benchmarking wasn't enabled when building the node. \ - You can enable it with `--features runtime-benchmarks`." + Err("Benchmarking wasn't enabled when building the node. You can enable \ + it with `--features runtime-benchmarks`." .into()) }, BenchmarkCmd::Block(cmd) => runner.sync_run(|config| { construct_benchmark_partials!(config, |partials| cmd.run(partials.client)) }), #[cfg(not(feature = "runtime-benchmarks"))] - BenchmarkCmd::Storage(_) => - return Err(sc_cli::Error::Input( - "Compile with --features=runtime-benchmarks \ - to enable storage benchmarks." - .into(), - ) - .into()), + BenchmarkCmd::Storage(_) => Err(sc_cli::Error::Input( + "Compile with --features=runtime-benchmarks to enable storage benchmarks." + .into(), + )), #[cfg(feature = "runtime-benchmarks")] BenchmarkCmd::Storage(cmd) => runner.sync_run(|config| { construct_benchmark_partials!(config, |partials| { @@ -302,7 +319,6 @@ pub fn run() -> Result<()> { _ => Err("Benchmarking sub-command unsupported".into()), } }, - Some(Subcommand::TryRuntime) => Err("The `try-runtime` subcommand has been migrated to a standalone CLI (https://github.com/paritytech/try-runtime-cli). It is no longer being maintained here and will be removed entirely some time after January 2024. Please remove this subcommand from your runtime and use the standalone CLI.".into()), Some(Subcommand::Key(cmd)) => cmd.run(&cli), None => { let runner = cli.create_runner(&cli.run.normalize())?; @@ -327,17 +343,11 @@ pub fn run() -> Result<()> { let id = ParaId::from(para_id); - let parachain_account = - AccountIdConversion::::into_account_truncating( - &id, - ); - let tokio_handle = config.tokio_handle.clone(); let polkadot_config = SubstrateCli::create_configuration(&polkadot_cli, &polkadot_cli, tokio_handle) .map_err(|err| format!("Relay chain argument error: {}", err))?; - info!("Parachain Account: {parachain_account}"); info!("Is collating: {}", if config.role.is_authority() { "yes" } else { "no" }); match config.chain_spec.runtime() { @@ -345,10 +355,7 @@ pub fn run() -> Result<()> { sp_core::crypto::set_default_ss58_version( pop_runtime_devnet::SS58Prefix::get().into(), ); - crate::service::start_parachain_node::< - pop_runtime_devnet::RuntimeApi, - DevnetRuntimeExecutor, - >( + crate::service::start_parachain_node::( config, polkadot_config, collator_options, @@ -363,10 +370,22 @@ pub fn run() -> Result<()> { sp_core::crypto::set_default_ss58_version( pop_runtime_testnet::SS58Prefix::get().into(), ); - crate::service::start_parachain_node::< - pop_runtime_testnet::RuntimeApi, - TestnetRuntimeExecutor, - >( + crate::service::start_parachain_node::( + config, + polkadot_config, + collator_options, + id, + hwbench, + ) + .await + .map(|r| r.0) + .map_err(Into::into) + }, + Runtime::Mainnet => { + sp_core::crypto::set_default_ss58_version( + pop_runtime_mainnet::SS58Prefix::get().into(), + ); + crate::service::start_parachain_node::( config, polkadot_config, collator_options, diff --git a/node/src/rpc.rs b/node/src/rpc.rs index 39d74019..6265dfd3 100644 --- a/node/src/rpc.rs +++ b/node/src/rpc.rs @@ -8,7 +8,6 @@ use std::sync::Arc; use pop_runtime_common::{AccountId, Balance, Block, Nonce}; - pub use sc_rpc::DenyUnsafe; use sc_transaction_pool_api::TransactionPool; use sp_api::ProvideRuntimeApi; diff --git a/node/src/service.rs b/node/src/service.rs index cd3a5a52..95eba022 100644 --- a/node/src/service.rs +++ b/node/src/service.rs @@ -4,11 +4,9 @@ use std::{sync::Arc, time::Duration}; use cumulus_client_cli::CollatorOptions; -// Local Runtime Types -use pop_runtime_common::{AccountId, AuraId, Balance, Block, Hash, Nonce}; - // Cumulus Imports use cumulus_client_collator::service::CollatorService; +use cumulus_client_consensus_aura::collators::lookahead::{self as aura, Params as AuraParams}; use cumulus_client_consensus_common::ParachainBlockImport as TParachainBlockImport; use cumulus_client_consensus_proposer::Proposer; use cumulus_client_service::{ @@ -20,15 +18,14 @@ use cumulus_primitives_core::{ ParaId, }; use cumulus_relay_chain_interface::{OverseerHandle, RelayChainInterface}; - // Substrate Imports use frame_benchmarking_cli::SUBSTRATE_REFERENCE_HARDWARE; +// Local Runtime Types +use pop_runtime_common::{AccountId, AuraId, Balance, Block, Hash, Nonce}; +use prometheus_endpoint::Registry; use sc_client_api::Backend; use sc_consensus::ImportQueue; -use sc_executor::{ - HeapAllocStrategy, NativeElseWasmExecutor, NativeExecutionDispatch, WasmExecutor, - DEFAULT_HEAP_ALLOC_STRATEGY, -}; +use sc_executor::{HeapAllocStrategy, WasmExecutor, DEFAULT_HEAP_ALLOC_STRATEGY}; use sc_network::NetworkBlock; use sc_network_sync::SyncingService; use sc_service::{Configuration, PartialComponents, TFullBackend, TFullClient, TaskManager}; @@ -38,72 +35,47 @@ use sp_api::ConstructRuntimeApi; use sp_core::Pair; use sp_keystore::KeystorePtr; use sp_runtime::{app_crypto::AppCrypto, traits::BlakeTwo256}; -use substrate_prometheus_endpoint::Registry; - -/// Devnet Native executor type. -pub struct DevnetRuntimeExecutor; - -impl NativeExecutionDispatch for DevnetRuntimeExecutor { - type ExtendHostFunctions = frame_benchmarking::benchmarking::HostFunctions; - - fn dispatch(method: &str, data: &[u8]) -> Option> { - pop_runtime_devnet::api::dispatch(method, data) - } - - fn native_version() -> sc_executor::NativeVersion { - pop_runtime_devnet::native_version() - } -} -/// Testnet Native executor type. -pub struct TestnetRuntimeExecutor; +#[cfg(not(feature = "runtime-benchmarks"))] +type HostFunctions = cumulus_client_service::ParachainHostFunctions; -impl NativeExecutionDispatch for TestnetRuntimeExecutor { - type ExtendHostFunctions = frame_benchmarking::benchmarking::HostFunctions; +#[cfg(feature = "runtime-benchmarks")] +type HostFunctions = ( + cumulus_client_service::ParachainHostFunctions, + frame_benchmarking::benchmarking::HostFunctions, +); - fn dispatch(method: &str, data: &[u8]) -> Option> { - pop_runtime_testnet::api::dispatch(method, data) - } - - fn native_version() -> sc_executor::NativeVersion { - pop_runtime_testnet::native_version() - } -} +type ParachainExecutor = WasmExecutor; -type ParachainExecutor = NativeElseWasmExecutor; - -type ParachainClient = - TFullClient>; +type ParachainClient = TFullClient; type ParachainBackend = TFullBackend; -type ParachainBlockImport = - TParachainBlockImport>, ParachainBackend>; +type ParachainBlockImport = + TParachainBlockImport>, ParachainBackend>; /// Assembly of PartialComponents (enough to run chain ops subcommands) -type Service = PartialComponents< - ParachainClient, +type Service = PartialComponents< + ParachainClient, ParachainBackend, (), sc_consensus::DefaultImportQueue, - sc_transaction_pool::FullPool>, - (ParachainBlockImport, Option, Option), + sc_transaction_pool::FullPool>, + (ParachainBlockImport, Option, Option), >; /// Starts a `ServiceBuilder` for a full service. /// /// Use this macro if you don't actually need the full service, but just the builder in order to /// be able to perform chain operations. -pub fn new_partial( +pub fn new_partial( config: &Configuration, -) -> Result, sc_service::Error> +) -> Result, sc_service::Error> where - RuntimeApi: - ConstructRuntimeApi> + Send + Sync + 'static, - RuntimeApi::RuntimeApi: RuntimeApiExt, + RuntimeApi: ConstructRuntimeApi> + Send + Sync + 'static, + RuntimeApi::RuntimeApi: RuntimeApiExt, sc_client_api::StateBackendFor, Block>: sc_client_api::StateBackend, - Executor: NativeExecutionDispatch + 'static, { let telemetry = config .telemetry_endpoints @@ -120,7 +92,7 @@ where .default_heap_pages .map_or(DEFAULT_HEAP_ALLOC_STRATEGY, |h| HeapAllocStrategy::Static { extra_pages: h as _ }); - let wasm = WasmExecutor::builder() + let executor = ParachainExecutor::builder() .with_execution_method(config.wasm_method) .with_onchain_heap_alloc_strategy(heap_pages) .with_offchain_heap_alloc_strategy(heap_pages) @@ -128,13 +100,12 @@ where .with_runtime_cache_size(config.runtime_cache_size) .build(); - let executor = NativeElseWasmExecutor::::new_with_wasm_executor(wasm); - let (client, backend, keystore_container, task_manager) = - sc_service::new_full_parts::( + sc_service::new_full_parts_record_import::( config, telemetry.as_ref().map(|(_, telemetry)| telemetry.handle()), executor, + true, )?; let client = Arc::new(client); @@ -153,8 +124,7 @@ where client.clone(), ); - let block_import = - ParachainBlockImport::::new(client.clone(), backend.clone()); + let block_import = ParachainBlockImport::::new(client.clone(), backend.clone()); let import_queue = build_import_queue( client.clone(), @@ -162,7 +132,7 @@ where config, telemetry.as_ref().map(|telemetry| telemetry.handle()), &task_manager, - )?; + ); Ok(PartialComponents { backend, @@ -180,28 +150,26 @@ where /// /// This is the actual implementation that is abstract over the executor and the runtime api. #[sc_tracing::logging::prefix_logs_with("Parachain")] -async fn start_node_impl( +async fn start_node_impl( parachain_config: Configuration, polkadot_config: Configuration, collator_options: CollatorOptions, para_id: ParaId, start_consensus: SC, hwbench: Option, -) -> sc_service::error::Result<(TaskManager, Arc>)> +) -> sc_service::error::Result<(TaskManager, Arc>)> where - RuntimeApi: - ConstructRuntimeApi> + Send + Sync + 'static, - RuntimeApi::RuntimeApi: RuntimeApiExt, - Executor: NativeExecutionDispatch + 'static, + RuntimeApi: ConstructRuntimeApi> + Send + Sync + 'static, + RuntimeApi::RuntimeApi: RuntimeApiExt, SC: FnOnce( - Arc>, + Arc>, Arc, - ParachainBlockImport, + ParachainBlockImport, Option<&Registry>, Option, &TaskManager, Arc, - Arc>>, + Arc>>, Arc>, KeystorePtr, Duration, @@ -213,9 +181,13 @@ where { let parachain_config = prepare_node_config(parachain_config); - let params = new_partial::(¶chain_config)?; + let params = new_partial::(¶chain_config)?; let (block_import, mut telemetry, telemetry_worker_handle) = params.other; - let net_config = sc_network::config::FullNetworkConfiguration::new(¶chain_config.network); + let net_config = sc_network::config::FullNetworkConfiguration::< + _, + _, + sc_network::NetworkWorker, + >::new(¶chain_config.network); let client = params.client.clone(); let backend = params.backend.clone(); @@ -264,7 +236,7 @@ where transaction_pool: Some(OffchainTransactionPoolFactory::new( transaction_pool.clone(), )), - network_provider: network.clone(), + network_provider: Arc::new(network.clone()), is_validator: parachain_config.role.is_authority(), enable_http_requests: false, custom_extensions: move |_| vec![], @@ -297,7 +269,7 @@ where config: parachain_config, keystore: params.keystore_container.keystore(), backend: backend.clone(), - network: network.clone(), + network, sync_service: sync_service.clone(), system_rpc_tx, tx_handler_controller, @@ -361,9 +333,9 @@ where prometheus_registry.as_ref(), telemetry.as_ref().map(|t| t.handle()), &task_manager, - relay_chain_interface.clone(), + relay_chain_interface, transaction_pool, - sync_service.clone(), + sync_service, params.keystore_container.keystore(), relay_chain_slot_duration, para_id, @@ -380,21 +352,18 @@ where /// Build the import queue for the parachain runtime. #[allow(clippy::type_complexity)] -pub(crate) fn build_import_queue( - client: Arc>, - block_import: ParachainBlockImport, +pub(crate) fn build_import_queue( + client: Arc>, + block_import: ParachainBlockImport, config: &Configuration, telemetry: Option, task_manager: &TaskManager, -) -> Result, sc_service::Error> +) -> sc_consensus::DefaultImportQueue where - RuntimeApi: - ConstructRuntimeApi> + Send + Sync + 'static, - RuntimeApi::RuntimeApi: RuntimeApiExt, + RuntimeApi: ConstructRuntimeApi> + Send + Sync + 'static, + RuntimeApi::RuntimeApi: RuntimeApiExt, { - let slot_duration = cumulus_client_consensus_aura::slot_duration(&*client)?; - - Ok(cumulus_client_consensus_aura::equivocation_import_queue::fully_verifying_import_queue::< + cumulus_client_consensus_aura::equivocation_import_queue::fully_verifying_import_queue::< sp_consensus_aura::sr25519::AuthorityPair, _, _, @@ -407,25 +376,22 @@ where let timestamp = sp_timestamp::InherentDataProvider::from_system_time(); Ok(timestamp) }, - slot_duration, &task_manager.spawn_essential_handle(), config.prometheus_registry(), telemetry, - )) + ) } #[allow(clippy::too_many_arguments)] -fn start_consensus( - client: Arc>, +fn start_consensus( + client: Arc>, backend: Arc, - block_import: ParachainBlockImport, + block_import: ParachainBlockImport, prometheus_registry: Option<&Registry>, telemetry: Option, task_manager: &TaskManager, relay_chain_interface: Arc, - transaction_pool: Arc< - sc_transaction_pool::FullPool>, - >, + transaction_pool: Arc>>, sync_oracle: Arc>, keystore: KeystorePtr, relay_chain_slot_duration: Duration, @@ -435,18 +401,9 @@ fn start_consensus( announce_block: Arc>) + Send + Sync>, ) -> Result<(), sc_service::Error> where - RuntimeApi: - ConstructRuntimeApi> + Send + Sync + 'static, - RuntimeApi::RuntimeApi: RuntimeApiExt, - Executor: NativeExecutionDispatch + 'static, + RuntimeApi: ConstructRuntimeApi> + Send + Sync + 'static, + RuntimeApi::RuntimeApi: RuntimeApiExt, { - use cumulus_client_consensus_aura::collators::lookahead::{self as aura, Params as AuraParams}; - - // NOTE: because we use Aura here explicitly, we can use `CollatorSybilResistance::Resistant` - // when starting the network. - - let slot_duration = cumulus_client_consensus_aura::slot_duration(&*client)?; - let proposer_factory = sc_basic_authorship::ProposerFactory::with_proof_recording( task_manager.spawn_handle(), client.clone(), @@ -478,11 +435,10 @@ where collator_key, para_id, overseer_handle, - slot_duration, relay_chain_slot_duration, proposer, collator_service, - authoring_duration: Duration::from_millis(1500), + authoring_duration: Duration::from_millis(2000), reinitialize: false, }; @@ -496,32 +452,30 @@ where } /// Start a parachain node. -pub async fn start_parachain_node( +pub async fn start_parachain_node( parachain_config: Configuration, polkadot_config: Configuration, collator_options: CollatorOptions, para_id: ParaId, hwbench: Option, -) -> sc_service::error::Result<(TaskManager, Arc>)> +) -> sc_service::error::Result<(TaskManager, Arc>)> where - Executor: NativeExecutionDispatch + 'static, - RuntimeApi: - ConstructRuntimeApi> + Send + Sync + 'static, - RuntimeApi::RuntimeApi: RuntimeApiExt, + RuntimeApi: ConstructRuntimeApi> + Send + Sync + 'static, + RuntimeApi::RuntimeApi: RuntimeApiExt, { - start_node_impl::( + start_node_impl::( parachain_config, polkadot_config, collator_options, para_id, - start_consensus::, + start_consensus::, hwbench, ) .await } // Trait alias refactored out from above to simplify repeated trait bounds -pub(crate) trait RuntimeApiExt: +pub(crate) trait RuntimeApiExt: sp_transaction_pool::runtime_api::TaggedTransactionQueue + sp_api::Metadata + sp_session::SessionKeys @@ -548,7 +502,6 @@ impl< + substrate_frame_rpc_system::AccountNonceApi + cumulus_primitives_aura::AuraUnincludedSegmentApi, RuntimeApi, - Executor, - > RuntimeApiExt for T + > RuntimeApiExt for T { } diff --git a/pallets/api/Cargo.toml b/pallets/api/Cargo.toml index d2d444bf..55a00789 100644 --- a/pallets/api/Cargo.toml +++ b/pallets/api/Cargo.toml @@ -1,13 +1,13 @@ [package] -name = "pallet-api" authors.workspace = true description = "API pallet, enabling smart(er) contracts with the power of Polkadot" edition.workspace = true license.workspace = true +name = "pallet-api" version = "0.1.0" [package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] +targets = [ "x86_64-unknown-linux-gnu" ] [dependencies] codec.workspace = true @@ -31,30 +31,31 @@ sp-core.workspace = true sp-io.workspace = true [features] -default = ["std"] +default = [ "std" ] runtime-benchmarks = [ - "frame-benchmarking/runtime-benchmarks", - "frame-support/runtime-benchmarks", - "frame-system/runtime-benchmarks", - "pallet-assets/runtime-benchmarks", - "sp-runtime/runtime-benchmarks", + "frame-benchmarking/runtime-benchmarks", + "frame-support/runtime-benchmarks", + "frame-system/runtime-benchmarks", + "pallet-assets/runtime-benchmarks", + "pop-chain-extension/runtime-benchmarks", + "sp-runtime/runtime-benchmarks", ] std = [ - "codec/std", - "frame-benchmarking/std", - "frame-support/std", - "frame-system/std", - "pallet-assets/std", - "pallet-balances/std", - "pop-chain-extension/std", - "scale-info/std", - "sp-core/std", - "sp-io/std", - "sp-runtime/std", - "sp-std/std", + "codec/std", + "frame-benchmarking/std", + "frame-support/std", + "frame-system/std", + "pallet-assets/std", + "pallet-balances/std", + "pop-chain-extension/std", + "scale-info/std", + "sp-core/std", + "sp-io/std", + "sp-runtime/std", + "sp-std/std", ] try-runtime = [ - "frame-support/try-runtime", - "frame-system/try-runtime", - "sp-runtime/try-runtime", + "frame-support/try-runtime", + "frame-system/try-runtime", + "sp-runtime/try-runtime", ] diff --git a/pallets/api/src/extension.rs b/pallets/api/src/extension.rs index 8469ae40..138cdee6 100644 --- a/pallets/api/src/extension.rs +++ b/pallets/api/src/extension.rs @@ -1,4 +1,5 @@ use core::{fmt::Debug, marker::PhantomData}; + use frame_support::traits::Get; pub use pop_chain_extension::{ Config, ContractWeightsOf, DecodingFailed, DispatchCall, ReadState, Readable, @@ -99,6 +100,7 @@ impl + Debug> Converter type Source = Source; /// The target type. type Target = Target; + /// The log target. const LOG_TARGET: &'static str = "pop-api::extension::converters::versioned-result"; @@ -138,11 +140,12 @@ fn version(env: &impl Environment) -> u8 { #[cfg(test)] mod tests { - use super::*; - use crate::extension::Prepender; use frame_support::pallet_prelude::Weight; use pop_chain_extension::Ext; + use super::*; + use crate::extension::Prepender; + #[test] fn prepender_works() { let env = MockEnvironment { func_id: 1, ext_id: u16::from_le_bytes([2, 3]) }; diff --git a/pallets/api/src/fungibles/benchmarking.rs b/pallets/api/src/fungibles/benchmarking.rs index d3d65b97..f346df1a 100644 --- a/pallets/api/src/fungibles/benchmarking.rs +++ b/pallets/api/src/fungibles/benchmarking.rs @@ -1,6 +1,5 @@ //! Benchmarking setup for pallet-api::fungibles -use super::{AccountIdOf, AssetIdOf, AssetsInstanceOf, AssetsOf, BalanceOf, Call, Config, Pallet}; use frame_benchmarking::{account, v2::*}; use frame_support::{ assert_ok, @@ -15,6 +14,8 @@ use frame_support::{ use frame_system::RawOrigin; use sp_runtime::traits::Zero; +use super::{AccountIdOf, AssetIdOf, AssetsInstanceOf, AssetsOf, BalanceOf, Call, Config, Pallet}; + const SEED: u32 = 1; // See if `generic_event` has been emitted. diff --git a/pallets/api/src/fungibles/mod.rs b/pallets/api/src/fungibles/mod.rs index dac002e9..76f3b28a 100644 --- a/pallets/api/src/fungibles/mod.rs +++ b/pallets/api/src/fungibles/mod.rs @@ -27,8 +27,8 @@ type BalanceOf = > as Inspect< #[frame_support::pallet] pub mod pallet { - use super::*; use core::cmp::Ordering::*; + use frame_support::{ dispatch::{DispatchResult, DispatchResultWithPostInfo, WithPostDispatchInfo}, pallet_prelude::*, @@ -41,6 +41,8 @@ pub mod pallet { }; use sp_std::vec::Vec; + use super::*; + /// State reads for the fungibles API with required input. #[derive(Encode, Decode, Debug, MaxEncodedLen)] #[repr(u8)] diff --git a/pallets/api/src/fungibles/tests.rs b/pallets/api/src/fungibles/tests.rs index d6d4ef2f..d850474b 100644 --- a/pallets/api/src/fungibles/tests.rs +++ b/pallets/api/src/fungibles/tests.rs @@ -1,4 +1,3 @@ -use crate::{fungibles::Read::*, mock::*, Read}; use codec::Encode; use frame_support::{ assert_ok, @@ -8,6 +7,8 @@ use frame_support::{ }, }; +use crate::{fungibles::Read::*, mock::*, Read}; + const ASSET: u32 = 42; type Event = crate::fungibles::Event; diff --git a/pallets/api/src/mock.rs b/pallets/api/src/mock.rs index 77e17394..fe2b2c9a 100644 --- a/pallets/api/src/mock.rs +++ b/pallets/api/src/mock.rs @@ -32,73 +32,73 @@ parameter_types! { #[derive_impl(frame_system::config_preludes::TestDefaultConfig as frame_system::DefaultConfig)] impl frame_system::Config for Test { + type AccountData = pallet_balances::AccountData; + type AccountId = AccountId; type BaseCallFilter = Everything; - type BlockWeights = (); + type Block = Block; + type BlockHashCount = BlockHashCount; type BlockLength = (); - type RuntimeOrigin = RuntimeOrigin; - type RuntimeCall = RuntimeCall; - type Nonce = u64; + type BlockWeights = (); + type DbWeight = (); type Hash = H256; type Hashing = BlakeTwo256; - type AccountId = AccountId; type Lookup = IdentityLookup; - type Block = Block; - type RuntimeEvent = RuntimeEvent; - type BlockHashCount = BlockHashCount; - type DbWeight = (); - type Version = (); - type PalletInfo = PalletInfo; - type AccountData = pallet_balances::AccountData; - type OnNewAccount = (); + type MaxConsumers = ConstU32<16>; + type Nonce = u64; type OnKilledAccount = (); - type SystemWeightInfo = (); - type SS58Prefix = SS58Prefix; + type OnNewAccount = (); type OnSetCode = (); - type MaxConsumers = ConstU32<16>; + type PalletInfo = PalletInfo; + type RuntimeCall = RuntimeCall; + type RuntimeEvent = RuntimeEvent; + type RuntimeOrigin = RuntimeOrigin; + type SS58Prefix = SS58Prefix; + type SystemWeightInfo = (); + type Version = (); } impl pallet_balances::Config for Test { + type AccountStore = System; type Balance = Balance; type DustRemoval = (); - type RuntimeEvent = RuntimeEvent; type ExistentialDeposit = ConstU128<1>; - type AccountStore = System; type FreezeIdentifier = (); type MaxFreezes = ConstU32<0>; - type WeightInfo = (); type MaxLocks = (); type MaxReserves = (); type ReserveIdentifier = [u8; 8]; - type RuntimeHoldReason = RuntimeHoldReason; + type RuntimeEvent = RuntimeEvent; type RuntimeFreezeReason = RuntimeFreezeReason; + type RuntimeHoldReason = RuntimeHoldReason; + type WeightInfo = (); } type AssetsInstance = pallet_assets::Instance1; impl pallet_assets::Config for Test { - type RuntimeEvent = RuntimeEvent; - type Balance = Balance; - type RemoveItemsLimit = ConstU32<5>; + type ApprovalDeposit = ConstU128<1>; + type AssetAccountDeposit = ConstU128<10>; + type AssetDeposit = ConstU128<1>; type AssetId = AssetId; type AssetIdParameter = u32; - type Currency = Balances; + type Balance = Balance; + #[cfg(feature = "runtime-benchmarks")] + type BenchmarkHelper = (); + type CallbackHandle = (); type CreateOrigin = AsEnsureOriginWithArg>; + type Currency = Balances; + type Extra = (); type ForceOrigin = EnsureRoot; - type AssetDeposit = ConstU128<1>; - type AssetAccountDeposit = ConstU128<10>; + type Freezer = (); type MetadataDepositBase = ConstU128<1>; type MetadataDepositPerByte = ConstU128<1>; - type ApprovalDeposit = ConstU128<1>; + type RemoveItemsLimit = ConstU32<5>; + type RuntimeEvent = RuntimeEvent; type StringLimit = ConstU32<50>; - type Freezer = (); - type Extra = (); - type CallbackHandle = (); type WeightInfo = (); - #[cfg(feature = "runtime-benchmarks")] - type BenchmarkHelper = (); } impl crate::fungibles::Config for Test { - type RuntimeEvent = RuntimeEvent; type AssetsInstance = AssetsInstance; + type RuntimeEvent = RuntimeEvent; type WeightInfo = (); } diff --git a/pop-api/Cargo.toml b/pop-api/Cargo.toml index 05dd9715..8296569a 100644 --- a/pop-api/Cargo.toml +++ b/pop-api/Cargo.toml @@ -1,27 +1,26 @@ [package] -name = "pop-api" description = "Enabling smart(er) contracts with the power of Polkadot" +edition = "2021" license = "GPL-3.0-only" +name = "pop-api" version = "0.0.0" -edition = "2021" [dependencies] ink = { version = "5.0.0", default-features = false } +pop-primitives = { path = "../primitives", default-features = false } sp-io = { version = "31.0.0", default-features = false, features = [ - "disable_panic_handler", - "disable_oom", - "disable_allocator", + "disable_allocator", + "disable_oom", + "disable_panic_handler", ] } -pop-primitives = { path = "../primitives", default-features = false } - [lib] +crate-type = [ "rlib" ] name = "pop_api" path = "src/lib.rs" -crate-type = ["rlib"] [features] -default = ["std"] -std = ["ink/std", "pop-primitives/std", "sp-io/std"] -assets = [] -fungibles = ["assets"] +assets = [ ] +default = [ "std" ] +fungibles = [ "assets" ] +std = [ "ink/std", "pop-primitives/std", "sp-io/std" ] diff --git a/pop-api/examples/balance-transfer/Cargo.toml b/pop-api/examples/balance-transfer/Cargo.toml index 29cd0ea5..2a12e532 100755 --- a/pop-api/examples/balance-transfer/Cargo.toml +++ b/pop-api/examples/balance-transfer/Cargo.toml @@ -1,14 +1,14 @@ [package] +authors = [ "[your_name] <[your_email]>" ] +edition = "2021" name = "balance_transfer" version = "0.1.0" -authors = ["[your_name] <[your_email]>"] -edition = "2021" [dependencies] ink = { version = "5.0.0", default-features = false } pop-api = { path = "../../../pop-api", default-features = false } -scale = { package = "parity-scale-codec", version = "3", default-features = false, features = ["derive"] } -scale-info = { version = "2.6", default-features = false, features = ["derive"], optional = true } +scale = { package = "parity-scale-codec", version = "3", default-features = false, features = [ "derive" ] } +scale-info = { version = "2.6", default-features = false, features = [ "derive" ], optional = true } [dev-dependencies] ink_e2e = "5.0.0" @@ -17,12 +17,12 @@ ink_e2e = "5.0.0" path = "lib.rs" [features] -default = ["std"] +default = [ "std" ] +e2e-tests = [ ] +ink-as-dependency = [ ] std = [ - "ink/std", - "pop-api/std", - "scale/std", - "scale-info/std", + "ink/std", + "pop-api/std", + "scale-info/std", + "scale/std", ] -ink-as-dependency = [] -e2e-tests = [] diff --git a/pop-api/examples/fungibles/Cargo.toml b/pop-api/examples/fungibles/Cargo.toml index 19d9ce12..0b79e1b2 100755 --- a/pop-api/examples/fungibles/Cargo.toml +++ b/pop-api/examples/fungibles/Cargo.toml @@ -1,21 +1,21 @@ [package] +authors = [ "[your_name] <[your_email]>" ] +edition = "2021" name = "fungibles" version = "0.1.0" -authors = ["[your_name] <[your_email]>"] -edition = "2021" [dependencies] ink = { version = "5.0.0", default-features = false } -pop-api = { path = "../../../pop-api", default-features = false, features = ["fungibles"] } +pop-api = { path = "../../../pop-api", default-features = false, features = [ "fungibles" ] } [lib] path = "lib.rs" [features] -default = ["std"] +default = [ "std" ] +e2e-tests = [ ] +ink-as-dependency = [ ] std = [ - "ink/std", - "pop-api/std", + "ink/std", + "pop-api/std", ] -ink-as-dependency = [] -e2e-tests = [] diff --git a/pop-api/examples/fungibles/lib.rs b/pop-api/examples/fungibles/lib.rs index a6328c37..1ad36de0 100755 --- a/pop-api/examples/fungibles/lib.rs +++ b/pop-api/examples/fungibles/lib.rs @@ -182,4 +182,4 @@ mod fungibles { PopApiFungiblesExample::new(); } } -} +} \ No newline at end of file diff --git a/pop-api/examples/nfts/Cargo.toml b/pop-api/examples/nfts/Cargo.toml index e931cf9f..ef50b7ec 100755 --- a/pop-api/examples/nfts/Cargo.toml +++ b/pop-api/examples/nfts/Cargo.toml @@ -1,25 +1,25 @@ [package] +authors = [ "[your_name] <[your_email]>" ] +edition = "2021" name = "nfts" version = "0.1.0" -authors = ["[your_name] <[your_email]>"] -edition = "2021" [dependencies] ink = { version = "5.0.0", default-features = false } pop-api = { path = "../../../pop-api", default-features = false } -scale = { package = "parity-scale-codec", version = "3", default-features = false, features = ["derive"] } -scale-info = { version = "2.6", default-features = false, features = ["derive"], optional = true } +scale = { package = "parity-scale-codec", version = "3", default-features = false, features = [ "derive" ] } +scale-info = { version = "2.6", default-features = false, features = [ "derive" ], optional = true } [lib] path = "lib.rs" [features] -default = ["std"] +default = [ "std" ] +e2e-tests = [ ] +ink-as-dependency = [ ] std = [ - "ink/std", - "pop-api/std", - "scale/std", - "scale-info/std", + "ink/std", + "pop-api/std", + "scale-info/std", + "scale/std", ] -ink-as-dependency = [] -e2e-tests = [] diff --git a/pop-api/examples/place-spot-order/Cargo.toml b/pop-api/examples/place-spot-order/Cargo.toml index 2c67313d..f523bea7 100755 --- a/pop-api/examples/place-spot-order/Cargo.toml +++ b/pop-api/examples/place-spot-order/Cargo.toml @@ -1,25 +1,25 @@ [package] +authors = [ "[your_name] <[your_email]>" ] +edition = "2021" name = "spot_order" version = "0.1.0" -authors = ["[your_name] <[your_email]>"] -edition = "2021" [dependencies] ink = { version = "5.0.0", default-features = false } pop-api = { path = "../../../pop-api", default-features = false } -scale = { package = "parity-scale-codec", version = "3", default-features = false, features = ["derive"] } -scale-info = { version = "2.6", default-features = false, features = ["derive"], optional = true } +scale = { package = "parity-scale-codec", version = "3", default-features = false, features = [ "derive" ] } +scale-info = { version = "2.6", default-features = false, features = [ "derive" ], optional = true } [lib] path = "lib.rs" [features] -default = ["std"] +default = [ "std" ] +e2e-tests = [ ] +ink-as-dependency = [ ] std = [ - "ink/std", - "pop-api/std", - "scale/std", - "scale-info/std", + "ink/std", + "pop-api/std", + "scale-info/std", + "scale/std", ] -ink-as-dependency = [] -e2e-tests = [] diff --git a/pop-api/examples/read-runtime-state/Cargo.toml b/pop-api/examples/read-runtime-state/Cargo.toml index 379152dd..f5464730 100755 --- a/pop-api/examples/read-runtime-state/Cargo.toml +++ b/pop-api/examples/read-runtime-state/Cargo.toml @@ -1,25 +1,25 @@ [package] +authors = [ "[your_name] <[your_email]>" ] +edition = "2021" name = "read_relay_blocknumber" version = "0.1.0" -authors = ["[your_name] <[your_email]>"] -edition = "2021" [dependencies] ink = { version = "5.0.0", default-features = false } pop-api = { path = "../../../pop-api", default-features = false } -scale = { package = "parity-scale-codec", version = "3", default-features = false, features = ["derive"] } -scale-info = { version = "2.6", default-features = false, features = ["derive"], optional = true } +scale = { package = "parity-scale-codec", version = "3", default-features = false, features = [ "derive" ] } +scale-info = { version = "2.6", default-features = false, features = [ "derive" ], optional = true } [lib] path = "lib.rs" [features] -default = ["std"] +default = [ "std" ] +e2e-tests = [ ] +ink-as-dependency = [ ] std = [ - "ink/std", - "pop-api/std", - "scale/std", - "scale-info/std", + "ink/std", + "pop-api/std", + "scale-info/std", + "scale/std", ] -ink-as-dependency = [] -e2e-tests = [] diff --git a/pop-api/integration-tests/Cargo.toml b/pop-api/integration-tests/Cargo.toml index 499ad991..5e0e4f9c 100644 --- a/pop-api/integration-tests/Cargo.toml +++ b/pop-api/integration-tests/Cargo.toml @@ -1,40 +1,41 @@ [package] +build = "build.rs" +edition = "2021" name = "integration-tests" version = "0.1.0" -edition = "2021" -build = "build.rs" [build-dependencies] contract-build = "4.1.1" [dev-dependencies] env_logger = "0.11.2" -scale = { package = "parity-scale-codec", version = "3.0.0", default-features = false, features = [ - "derive", -] } -frame-support = { version = "29.0.0", default-features = false } -frame-system = { version = "29.0.0", default-features = false } +frame-support = { version = "36.0.0", default-features = false } +frame-support-procedural = { version = "=30.0.1", default-features = false } +frame-system = { version = "36.1.0", default-features = false } log = "0.4.22" -pallet-balances = { version = "29.0.2", default-features = false } -pallet-assets = { version = "30.0.0", default-features = false } -pallet-contracts = { version = "28.0.0", default-features = false } +pallet-assets = { version = "37.0.0", default-features = false } +pallet-balances = { version = "37.0.0", default-features = false } +pallet-contracts = { version = "35.0.0", default-features = false } pop-primitives = { path = "../../primitives", default-features = false } pop-runtime-devnet = { path = "../../runtime/devnet", default-features = false } -sp-io = { version = "31.0.0", default-features = false } -sp-runtime = { version = "32.0.0", default-features = false } +scale = { package = "parity-scale-codec", version = "3.6.12", default-features = false, features = [ + "derive", +] } +sp-io = { version = "37.0.0", default-features = false } +sp-runtime = { version = "=38.0.0", default-features = false } [features] -default = ["std"] +default = [ "std" ] std = [ - "frame-support/std", - "frame-system/std", - "pallet-balances/std", - "pallet-assets/std", - "pallet-contracts/std", - "pop-primitives/std", - "pop-runtime-devnet/std", - "scale/std", - "sp-io/std", - "sp-runtime/std", -] \ No newline at end of file + "frame-support/std", + "frame-system/std", + "pallet-assets/std", + "pallet-balances/std", + "pallet-contracts/std", + "pop-primitives/std", + "pop-runtime-devnet/std", + "scale/std", + "sp-io/std", + "sp-runtime/std", +] diff --git a/pop-api/integration-tests/contracts/.gitignore b/pop-api/integration-tests/contracts/.gitignore deleted file mode 100755 index d60800c8..00000000 --- a/pop-api/integration-tests/contracts/.gitignore +++ /dev/null @@ -1,9 +0,0 @@ -# Ignore build artifacts from the local tests sub-crate. -**/target/ - -# Ignore backup files creates by cargo fmt. -**/*.rs.bk - -# Remove Cargo.lock when creating an executable, leave it for libraries -# More information here http://doc.crates.io/guide.html#cargotoml-vs-cargolock -**/Cargo.lock diff --git a/pop-api/integration-tests/contracts/create_token_in_constructor/Cargo.toml b/pop-api/integration-tests/contracts/create_token_in_constructor/Cargo.toml index 2c202715..c3d2c2fc 100755 --- a/pop-api/integration-tests/contracts/create_token_in_constructor/Cargo.toml +++ b/pop-api/integration-tests/contracts/create_token_in_constructor/Cargo.toml @@ -1,21 +1,21 @@ [package] +authors = [ "[your_name] <[your_email]>" ] +edition = "2021" name = "create_token_in_constructor" version = "0.1.0" -authors = ["[your_name] <[your_email]>"] -edition = "2021" [dependencies] ink = { version = "5.0.0", default-features = false } -pop-api = { path = "../../..", default-features = false, features = ["fungibles"] } +pop-api = { path = "../../..", default-features = false, features = [ "fungibles" ] } [lib] path = "lib.rs" [features] -default = ["std"] +default = [ "std" ] +e2e-tests = [ ] +ink-as-dependency = [ ] std = [ - "ink/std", - "pop-api/std", + "ink/std", + "pop-api/std", ] -ink-as-dependency = [] -e2e-tests = [] diff --git a/pop-api/integration-tests/contracts/fungibles/Cargo.toml b/pop-api/integration-tests/contracts/fungibles/Cargo.toml index 7c322004..0d0e80d5 100755 --- a/pop-api/integration-tests/contracts/fungibles/Cargo.toml +++ b/pop-api/integration-tests/contracts/fungibles/Cargo.toml @@ -1,21 +1,21 @@ [package] +authors = [ "[your_name] <[your_email]>" ] +edition = "2021" name = "fungibles" version = "0.1.0" -authors = ["[your_name] <[your_email]>"] -edition = "2021" [dependencies] ink = { version = "5.0.0", default-features = false } -pop-api = { path = "../../../../pop-api", default-features = false, features = ["fungibles"] } +pop-api = { path = "../../../../pop-api", default-features = false, features = [ "fungibles" ] } [lib] path = "lib.rs" [features] -default = ["std"] +default = [ "std" ] +e2e-tests = [ ] +ink-as-dependency = [ ] std = [ - "ink/std", - "pop-api/std", + "ink/std", + "pop-api/std", ] -ink-as-dependency = [] -e2e-tests = [] diff --git a/pop-api/integration-tests/src/fungibles/mod.rs b/pop-api/integration-tests/src/fungibles/mod.rs index d1c0e2ae..0d895aa3 100644 --- a/pop-api/integration-tests/src/fungibles/mod.rs +++ b/pop-api/integration-tests/src/fungibles/mod.rs @@ -569,7 +569,7 @@ fn burn_works() { start_destroy_asset(addr.clone(), asset); assert_eq!( burn(addr.clone(), asset, BOB, amount), - Err(Module { index: 52, error: [16, 0] }) + Err(Module { index: 52, error: [17, 0] }) ); }); } diff --git a/pop-api/integration-tests/src/lib.rs b/pop-api/integration-tests/src/lib.rs index 1dab5b85..6499df59 100644 --- a/pop-api/integration-tests/src/lib.rs +++ b/pop-api/integration-tests/src/lib.rs @@ -99,4 +99,4 @@ fn instantiate(contract: &str, init_value: u128, salt: Vec) -> AccountId32 { .unwrap(); assert!(!result.result.did_revert(), "deploying contract reverted {:?}", result); result.account_id -} +} \ No newline at end of file diff --git a/primitives/Cargo.toml b/primitives/Cargo.toml index e7d55ffe..0cb46198 100644 --- a/primitives/Cargo.toml +++ b/primitives/Cargo.toml @@ -1,17 +1,14 @@ [package] -name = "pop-primitives" description = "Primitives crate for Pop" +edition = "2021" license = "GPL-3.0-only" +name = "pop-primitives" version = "0.0.0" -edition = "2021" [dependencies] codec.workspace = true scale-info.workspace = true [features] -default = ["std"] -std = [ - "codec/std", - "scale-info/std", -] \ No newline at end of file +default = [ "std" ] +std = [ "codec/std", "scale-info/std" ] diff --git a/primitives/src/lib.rs b/primitives/src/lib.rs index e15b142c..ef6ae3a9 100644 --- a/primitives/src/lib.rs +++ b/primitives/src/lib.rs @@ -9,9 +9,10 @@ pub use v0::*; pub type AssetId = u32; pub mod v0 { - use super::*; pub use error::*; + use super::*; + mod error { use super::*; diff --git a/runtime/common/Cargo.toml b/runtime/common/Cargo.toml index 0cd9aecb..395abd24 100644 --- a/runtime/common/Cargo.toml +++ b/runtime/common/Cargo.toml @@ -4,16 +4,16 @@ description = "Pop Runtime Common" edition.workspace = true license.workspace = true name = "pop-runtime-common" +publish = false repository.workspace = true version = "0.0.0" -publish = false [package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] +targets = [ "x86_64-unknown-linux-gnu" ] [dependencies] -codec = { workspace = true, default-features = false, features = ["derive"] } -scale-info = { workspace = true, default-features = false, features = ["derive"] } +codec = { workspace = true, default-features = false, features = [ "derive" ] } +scale-info = { workspace = true, default-features = false, features = [ "derive" ] } # Substrate frame-support = { workspace = true, default-features = false } @@ -24,9 +24,9 @@ parachains-common = { workspace = true, default-features = false } polkadot-primitives = { workspace = true, default-features = false } [features] -default = ["std"] -std = ["frame-support/std", "sp-runtime/std"] +default = [ "std" ] runtime-benchmarks = [ - "frame-support/runtime-benchmarks", - "sp-runtime/runtime-benchmarks", -] \ No newline at end of file + "frame-support/runtime-benchmarks", + "sp-runtime/runtime-benchmarks", +] +std = [ "frame-support/std", "sp-runtime/std" ] diff --git a/runtime/common/src/lib.rs b/runtime/common/src/lib.rs index 2160ec81..f20ea377 100644 --- a/runtime/common/src/lib.rs +++ b/runtime/common/src/lib.rs @@ -1,12 +1,10 @@ #![cfg_attr(not(feature = "std"), no_std)] -use sp_runtime::Perbill; - use frame_support::weights::{constants::WEIGHT_REF_TIME_PER_SECOND, Weight}; - // Cumulus types re-export // These types are shared between the devnet and testnet runtimes pub use parachains_common::{AccountId, AuraId, Balance, Block, BlockNumber, Hash, Signature}; pub use polkadot_primitives::MAX_POV_SIZE; +use sp_runtime::Perbill; /// Nonce for an account pub type Nonce = u32; @@ -47,8 +45,8 @@ pub const MAXIMUM_BLOCK_WEIGHT: Weight = // Unit = the base number of indivisible units for balances pub const UNIT: Balance = 10_000_000_000; // 10 decimals -pub const MILLIUNIT: Balance = UNIT / 1_000; -pub const MICROUNIT: Balance = UNIT / 1_000_000; +pub const MILLIUNIT: Balance = UNIT / 1_000; // 10_000_000 +pub const MICROUNIT: Balance = UNIT / 1_000_000; // 10_000 // Deposits pub const fn deposit(items: u32, bytes: u32) -> Balance { @@ -69,11 +67,12 @@ pub const BLOCK_PROCESSING_VELOCITY: u32 = 1; /// Proxy commons for Pop runtimes pub mod proxy { - use super::{deposit, Balance}; use codec::{Decode, Encode, MaxEncodedLen}; use frame_support::parameter_types; use sp_runtime::RuntimeDebug; + use super::{deposit, Balance}; + parameter_types! { // One storage item; key size 32, value size 8; . pub const ProxyDepositBase: Balance = deposit(1, 40); diff --git a/runtime/devnet/Cargo.toml b/runtime/devnet/Cargo.toml index 3d2f20d0..b0eec2c2 100644 --- a/runtime/devnet/Cargo.toml +++ b/runtime/devnet/Cargo.toml @@ -1,15 +1,15 @@ [package] -name = "pop-runtime-devnet" -version = "0.1.0" authors.workspace = true description.workspace = true -license = "Unlicense" +edition.workspace = true homepage.workspace = true +license = "Unlicense" +name = "pop-runtime-devnet" repository.workspace = true -edition.workspace = true +version = "0.1.0" [package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] +targets = [ "x86_64-unknown-linux-gnu" ] [build-dependencies] substrate-wasm-builder.workspace = true @@ -22,22 +22,23 @@ scale-info.workspace = true smallvec.workspace = true # Local +pallet-api.workspace = true pop-chain-extension.workspace = true pop-primitives.workspace = true pop-runtime-common.workspace = true -pallet-api.workspace = true # Substrate frame-benchmarking.workspace = true frame-executive.workspace = true +frame-metadata-hash-extension.workspace = true frame-support.workspace = true frame-system.workspace = true frame-system-benchmarking.workspace = true frame-system-rpc-runtime-api.workspace = true frame-try-runtime.workspace = true +pallet-assets.workspace = true pallet-aura.workspace = true pallet-authorship.workspace = true -pallet-assets.workspace = true pallet-balances.workspace = true pallet-contracts.workspace = true pallet-message-queue.workspace = true @@ -45,22 +46,22 @@ pallet-multisig.workspace = true pallet-nft-fractionalization.workspace = true pallet-nfts.workspace = true pallet-nfts-runtime-api.workspace = true +pallet-preimage.workspace = true +pallet-proxy.workspace = true pallet-scheduler.workspace = true pallet-session.workspace = true pallet-sudo.workspace = true -pallet-preimage.workspace = true -pallet-proxy.workspace = true pallet-timestamp.workspace = true pallet-transaction-payment.workspace = true pallet-transaction-payment-rpc-runtime-api.workspace = true pallet-utility.workspace = true sp-api.workspace = true -sp-io.workspace = true sp-block-builder.workspace = true sp-consensus-aura.workspace = true sp-core.workspace = true sp-genesis-builder.workspace = true sp-inherents.workspace = true +sp-io.workspace = true sp-offchain.workspace = true sp-runtime.workspace = true sp-session.workspace = true @@ -84,146 +85,166 @@ cumulus-pallet-xcm.workspace = true cumulus-pallet-xcmp-queue.workspace = true cumulus-primitives-aura.workspace = true cumulus-primitives-core.workspace = true +cumulus-primitives-storage-weight-reclaim.workspace = true cumulus-primitives-utility.workspace = true pallet-collator-selection.workspace = true -parachains-common.workspace = true parachain-info.workspace = true +parachains-common.workspace = true [dev-dependencies] +enumflags2 = "0.7.9" env_logger = "0.11.2" hex = "0.4.3" [features] -default = ["std"] +default = [ "std" ] std = [ - "codec/std", - "cumulus-pallet-aura-ext/std", - "cumulus-pallet-parachain-system/std", - "cumulus-pallet-session-benchmarking/std", - "cumulus-pallet-xcm/std", - "cumulus-pallet-xcmp-queue/std", - "cumulus-primitives-aura/std", - "cumulus-primitives-core/std", - "cumulus-primitives-utility/std", - "frame-benchmarking/std", - "frame-executive/std", - "frame-support/std", - "frame-system-benchmarking/std", - "frame-system-rpc-runtime-api/std", - "frame-system/std", - "frame-try-runtime/std", - "log/std", - "pallet-aura/std", - "pallet-authorship/std", - "pallet-assets/std", - "pallet-balances/std", - "pallet-collator-selection/std", - "pallet-contracts/std", - "pallet-api/std", - "pallet-message-queue/std", - "pallet-multisig/std", - "pallet-nft-fractionalization/std", - "pallet-nfts/std", - "pallet-nfts-runtime-api/std", - "pallet-scheduler/std", - "pallet-session/std", - "pallet-sudo/std", - "pallet-preimage/std", - "pallet-proxy/std", - "pallet-timestamp/std", - "pallet-transaction-payment-rpc-runtime-api/std", - "pallet-transaction-payment/std", - "pallet-utility/std", - "pallet-xcm/std", - "parachain-info/std", - "parachains-common/std", - "polkadot-parachain-primitives/std", - "polkadot-runtime-common/std", - "pop-chain-extension/std", - "pop-primitives/std", - "scale-info/std", - "sp-api/std", - "sp-io/std", - "sp-block-builder/std", - "sp-consensus-aura/std", - "sp-core/std", - "sp-genesis-builder/std", - "sp-inherents/std", - "sp-offchain/std", - "sp-runtime/std", - "sp-session/std", - "sp-std/std", - "sp-transaction-pool/std", - "sp-version/std", - "xcm-builder/std", - "xcm-executor/std", - "xcm/std", + "codec/std", + "cumulus-pallet-aura-ext/std", + "cumulus-pallet-parachain-system/std", + "cumulus-pallet-session-benchmarking/std", + "cumulus-pallet-xcm/std", + "cumulus-pallet-xcmp-queue/std", + "cumulus-primitives-aura/std", + "cumulus-primitives-core/std", + "cumulus-primitives-storage-weight-reclaim/std", + "cumulus-primitives-utility/std", + "frame-benchmarking/std", + "frame-executive/std", + "frame-metadata-hash-extension/std", + "frame-support/std", + "frame-system-benchmarking/std", + "frame-system-rpc-runtime-api/std", + "frame-system/std", + "frame-try-runtime/std", + "log/std", + "pallet-api/std", + "pallet-assets/std", + "pallet-aura/std", + "pallet-authorship/std", + "pallet-balances/std", + "pallet-collator-selection/std", + "pallet-contracts/std", + "pallet-message-queue/std", + "pallet-multisig/std", + "pallet-nft-fractionalization/std", + "pallet-nfts-runtime-api/std", + "pallet-nfts/std", + "pallet-preimage/std", + "pallet-proxy/std", + "pallet-scheduler/std", + "pallet-session/std", + "pallet-sudo/std", + "pallet-timestamp/std", + "pallet-transaction-payment-rpc-runtime-api/std", + "pallet-transaction-payment/std", + "pallet-utility/std", + "pallet-xcm/std", + "parachain-info/std", + "parachains-common/std", + "polkadot-parachain-primitives/std", + "polkadot-runtime-common/std", + "pop-chain-extension/std", + "pop-primitives/std", + "pop-runtime-common/std", + "scale-info/std", + "sp-api/std", + "sp-block-builder/std", + "sp-consensus-aura/std", + "sp-core/std", + "sp-genesis-builder/std", + "sp-inherents/std", + "sp-io/std", + "sp-offchain/std", + "sp-runtime/std", + "sp-session/std", + "sp-std/std", + "sp-transaction-pool/std", + "sp-version/std", + "xcm-builder/std", + "xcm-executor/std", + "xcm/std", ] runtime-benchmarks = [ - "cumulus-pallet-parachain-system/runtime-benchmarks", - "cumulus-pallet-session-benchmarking/runtime-benchmarks", - "cumulus-pallet-xcmp-queue/runtime-benchmarks", - "cumulus-primitives-core/runtime-benchmarks", - "cumulus-primitives-utility/runtime-benchmarks", - "frame-benchmarking/runtime-benchmarks", - "frame-support/runtime-benchmarks", - "frame-system-benchmarking/runtime-benchmarks", - "frame-system/runtime-benchmarks", - "pallet-assets/runtime-benchmarks", - "pallet-api/runtime-benchmarks", - "pallet-balances/runtime-benchmarks", - "pallet-collator-selection/runtime-benchmarks", - "pallet-contracts/runtime-benchmarks", - "pallet-message-queue/runtime-benchmarks", - "pallet-multisig/runtime-benchmarks", - "pallet-nft-fractionalization/runtime-benchmarks", - "pallet-nfts/runtime-benchmarks", - "pallet-scheduler/runtime-benchmarks", - "pallet-sudo/runtime-benchmarks", - "pallet-preimage/runtime-benchmarks", - "pallet-proxy/runtime-benchmarks", - "pallet-timestamp/runtime-benchmarks", - "pallet-utility/runtime-benchmarks", - "pallet-xcm/runtime-benchmarks", - "parachains-common/runtime-benchmarks", - "polkadot-parachain-primitives/runtime-benchmarks", - "polkadot-runtime-common/runtime-benchmarks", - "sp-runtime/runtime-benchmarks", - "xcm-builder/runtime-benchmarks", - "xcm-executor/runtime-benchmarks", + "cumulus-pallet-parachain-system/runtime-benchmarks", + "cumulus-pallet-session-benchmarking/runtime-benchmarks", + "cumulus-pallet-xcmp-queue/runtime-benchmarks", + "cumulus-primitives-core/runtime-benchmarks", + "cumulus-primitives-utility/runtime-benchmarks", + "frame-benchmarking/runtime-benchmarks", + "frame-support/runtime-benchmarks", + "frame-system-benchmarking/runtime-benchmarks", + "frame-system/runtime-benchmarks", + "pallet-api/runtime-benchmarks", + "pallet-assets/runtime-benchmarks", + "pallet-balances/runtime-benchmarks", + "pallet-collator-selection/runtime-benchmarks", + "pallet-contracts/runtime-benchmarks", + "pallet-message-queue/runtime-benchmarks", + "pallet-multisig/runtime-benchmarks", + "pallet-nft-fractionalization/runtime-benchmarks", + "pallet-nfts/runtime-benchmarks", + "pallet-preimage/runtime-benchmarks", + "pallet-proxy/runtime-benchmarks", + "pallet-scheduler/runtime-benchmarks", + "pallet-sudo/runtime-benchmarks", + "pallet-timestamp/runtime-benchmarks", + "pallet-utility/runtime-benchmarks", + "pallet-xcm/runtime-benchmarks", + "parachains-common/runtime-benchmarks", + "polkadot-parachain-primitives/runtime-benchmarks", + "polkadot-runtime-common/runtime-benchmarks", + "pop-chain-extension/runtime-benchmarks", + "pop-runtime-common/runtime-benchmarks", + "sp-runtime/runtime-benchmarks", + "xcm-builder/runtime-benchmarks", + "xcm-executor/runtime-benchmarks", ] try-runtime = [ - "cumulus-pallet-aura-ext/try-runtime", - "cumulus-pallet-parachain-system/try-runtime", - "cumulus-pallet-xcm/try-runtime", - "cumulus-pallet-xcmp-queue/try-runtime", - "frame-executive/try-runtime", - "frame-support/try-runtime", - "frame-system/try-runtime", - "frame-try-runtime/try-runtime", - "pallet-api/try-runtime", - "pallet-aura/try-runtime", - "pallet-authorship/try-runtime", - "pallet-assets/try-runtime", - "pallet-balances/try-runtime", - "pallet-collator-selection/try-runtime", - "pallet-contracts/try-runtime", - "pallet-message-queue/try-runtime", - "pallet-multisig/try-runtime", - "pallet-nft-fractionalization/try-runtime", - "pallet-nfts/try-runtime", - "pallet-scheduler/try-runtime", - "pallet-session/try-runtime", - "pallet-sudo/try-runtime", - "pallet-preimage/try-runtime", - "pallet-proxy/try-runtime", - "pallet-timestamp/try-runtime", - "pallet-transaction-payment/try-runtime", - "pallet-utility/try-runtime", - "pallet-xcm/try-runtime", - "parachain-info/try-runtime", - "polkadot-runtime-common/try-runtime", - "sp-runtime/try-runtime", + "cumulus-pallet-aura-ext/try-runtime", + "cumulus-pallet-parachain-system/try-runtime", + "cumulus-pallet-xcm/try-runtime", + "cumulus-pallet-xcmp-queue/try-runtime", + "frame-executive/try-runtime", + "frame-support/try-runtime", + "frame-system/try-runtime", + "frame-try-runtime/try-runtime", + "pallet-api/try-runtime", + "pallet-assets/try-runtime", + "pallet-aura/try-runtime", + "pallet-authorship/try-runtime", + "pallet-balances/try-runtime", + "pallet-collator-selection/try-runtime", + "pallet-contracts/try-runtime", + "pallet-message-queue/try-runtime", + "pallet-multisig/try-runtime", + "pallet-nft-fractionalization/try-runtime", + "pallet-nfts/try-runtime", + "pallet-preimage/try-runtime", + "pallet-proxy/try-runtime", + "pallet-scheduler/try-runtime", + "pallet-session/try-runtime", + "pallet-sudo/try-runtime", + "pallet-timestamp/try-runtime", + "pallet-transaction-payment/try-runtime", + "pallet-utility/try-runtime", + "pallet-xcm/try-runtime", + "parachain-info/try-runtime", + "polkadot-runtime-common/try-runtime", + "sp-runtime/try-runtime", ] + +# Enable the metadata hash generation. +# +# This is hidden behind a feature because it increases the compile time. +# The wasm binary needs to be compiled twice, once to fetch the metadata, +# generate the metadata hash and then a second time with the +# `RUNTIME_METADATA_HASH` environment variable set for the `CheckMetadataHash` +# extension. +metadata-hash = [ "substrate-wasm-builder/metadata-hash" ] + +# A convenience feature for enabling things when doing a build +# for an on-chain release. +on-chain-release-build = [ "metadata-hash" ] diff --git a/runtime/devnet/build.rs b/runtime/devnet/build.rs index 02d6973f..6293cebb 100644 --- a/runtime/devnet/build.rs +++ b/runtime/devnet/build.rs @@ -1,12 +1,15 @@ -#[cfg(feature = "std")] +#[cfg(all(feature = "std", feature = "metadata-hash"))] fn main() { - substrate_wasm_builder::WasmBuilder::new() - .with_current_project() - .export_heap_base() - .import_memory() + substrate_wasm_builder::WasmBuilder::init_with_defaults() + .enable_metadata_hash("PAS", 10) .build() } +#[cfg(all(feature = "std", not(feature = "metadata-hash")))] +fn main() { + substrate_wasm_builder::WasmBuilder::build_using_defaults() +} + /// The wasm builder is deactivated when compiling /// this crate for wasm to speed up the compilation. #[cfg(not(feature = "std"))] diff --git a/runtime/devnet/src/config/api/mod.rs b/runtime/devnet/src/config/api/mod.rs index ac956eb2..16ea92fb 100644 --- a/runtime/devnet/src/config/api/mod.rs +++ b/runtime/devnet/src/config/api/mod.rs @@ -1,8 +1,6 @@ -use crate::{ - config::assets::TrustBackedAssetsInstance, fungibles, Runtime, RuntimeCall, RuntimeEvent, -}; -use codec::Decode; use core::marker::PhantomData; + +use codec::Decode; use cumulus_primitives_core::Weight; use frame_support::traits::Contains; pub(crate) use pallet_api::Extension; @@ -12,6 +10,10 @@ use sp_runtime::DispatchError; use sp_std::vec::Vec; use versioning::*; +use crate::{ + config::assets::TrustBackedAssetsInstance, fungibles, Runtime, RuntimeCall, RuntimeEvent, +}; + mod versioning; type DecodingFailedError = DecodingFailed; @@ -68,8 +70,8 @@ impl RuntimeResult { } impl fungibles::Config for Runtime { - type RuntimeEvent = RuntimeEvent; type AssetsInstance = TrustBackedAssetsInstance; + type RuntimeEvent = RuntimeEvent; type WeightInfo = fungibles::weights::SubstrateWeight; } diff --git a/runtime/devnet/src/config/api/versioning.rs b/runtime/devnet/src/config/api/versioning.rs index 50041340..317496df 100644 --- a/runtime/devnet/src/config/api/versioning.rs +++ b/runtime/devnet/src/config/api/versioning.rs @@ -1,6 +1,7 @@ -use super::*; use sp_runtime::ModuleError; +use super::*; + type Version = u8; /// Versioned runtime calls. @@ -156,11 +157,12 @@ impl From for V0Error { #[cfg(test)] mod tests { - use super::*; use pop_primitives::{ArithmeticError::*, Error, TokenError::*, TransactionalError::*}; use sp_runtime::ModuleError; use DispatchError::*; + use super::*; + // Compare all the different `DispatchError` variants with the expected `Error`. #[test] fn dispatch_error_to_error() { diff --git a/runtime/devnet/src/config/assets.rs b/runtime/devnet/src/config/assets.rs index 78aed8b5..91322ecf 100644 --- a/runtime/devnet/src/config/assets.rs +++ b/runtime/devnet/src/config/assets.rs @@ -38,36 +38,36 @@ parameter_types! { } impl pallet_nfts::Config for Runtime { - type RuntimeEvent = RuntimeEvent; // TODO: source from primitives - type CollectionId = CollectionId; + type ApprovalsLimit = ConstU32<20>; + type AttributeDepositBase = NftsAttributeDepositBase; + type CollectionDeposit = NftsCollectionDeposit; // TODO: source from primitives - type ItemId = ItemId; - type Currency = Balances; + type CollectionId = CollectionId; type CreateOrigin = AsEnsureOriginWithArg>; + type Currency = Balances; + type DepositPerByte = NftsDepositPerByte; + type Features = NftsPalletFeatures; type ForceOrigin = AssetsForceOrigin; - type Locker = (); - type CollectionDeposit = NftsCollectionDeposit; + #[cfg(feature = "runtime-benchmarks")] + type Helper = (); + type ItemAttributesApprovalsLimit = ConstU32<30>; type ItemDeposit = NftsItemDeposit; - type MetadataDepositBase = NftsMetadataDepositBase; - type AttributeDepositBase = NftsAttributeDepositBase; - type DepositPerByte = NftsDepositPerByte; - type StringLimit = ConstU32<256>; // TODO: source from primitives - type KeyLimit = ConstU32<64>; - type ValueLimit = ConstU32<256>; + type ItemId = ItemId; // TODO: source from primitives - type ApprovalsLimit = ConstU32<20>; - type ItemAttributesApprovalsLimit = ConstU32<30>; - type MaxTips = ConstU32<10>; - type MaxDeadlineDuration = NftsMaxDeadlineDuration; + type KeyLimit = ConstU32<64>; + type Locker = (); type MaxAttributesPerCall = ConstU32<10>; - type Features = NftsPalletFeatures; - type OffchainSignature = Signature; + type MaxDeadlineDuration = NftsMaxDeadlineDuration; + type MaxTips = ConstU32<10>; + type MetadataDepositBase = NftsMetadataDepositBase; type OffchainPublic = ::Signer; + type OffchainSignature = Signature; + type RuntimeEvent = RuntimeEvent; + type StringLimit = ConstU32<256>; + type ValueLimit = ConstU32<256>; type WeightInfo = pallet_nfts::weights::SubstrateWeight; - #[cfg(feature = "runtime-benchmarks")] - type Helper = (); } parameter_types! { @@ -77,46 +77,46 @@ parameter_types! { } impl pallet_nft_fractionalization::Config for Runtime { - type RuntimeEvent = RuntimeEvent; - type Deposit = AssetDeposit; + type AssetBalance = >::Balance; + type AssetId = >::AssetId; + type Assets = Assets; + #[cfg(feature = "runtime-benchmarks")] + type BenchmarkHelper = (); type Currency = Balances; - type NewAssetSymbol = NewAssetSymbol; + type Deposit = AssetDeposit; type NewAssetName = NewAssetName; - type StringLimit = AssetsStringLimit; + type NewAssetSymbol = NewAssetSymbol; type NftCollectionId = ::CollectionId; type NftId = ::ItemId; - type AssetBalance = >::Balance; - type AssetId = >::AssetId; - type Assets = Assets; type Nfts = Nfts; type PalletId = NftFractionalizationPalletId; - type WeightInfo = pallet_nft_fractionalization::weights::SubstrateWeight; + type RuntimeEvent = RuntimeEvent; type RuntimeHoldReason = RuntimeHoldReason; - #[cfg(feature = "runtime-benchmarks")] - type BenchmarkHelper = (); + type StringLimit = AssetsStringLimit; + type WeightInfo = pallet_nft_fractionalization::weights::SubstrateWeight; } pub type TrustBackedAssetsInstance = pallet_assets::Instance1; -pub(crate) type AssetsCall = pallet_assets::Call; +pub type TrustBackedAssetsCall = pallet_assets::Call; impl pallet_assets::Config for Runtime { - type RuntimeEvent = RuntimeEvent; - type Balance = Balance; + type ApprovalDeposit = ApprovalDeposit; + type AssetAccountDeposit = AssetAccountDeposit; + type AssetDeposit = AssetDeposit; type AssetId = AssetIdForTrustBackedAssets; type AssetIdParameter = codec::Compact; - type Currency = Balances; + type Balance = Balance; + #[cfg(feature = "runtime-benchmarks")] + type BenchmarkHelper = (); + type CallbackHandle = (); type CreateOrigin = AsEnsureOriginWithArg>; + type Currency = Balances; + type Extra = (); type ForceOrigin = AssetsForceOrigin; - type AssetDeposit = AssetDeposit; + type Freezer = (); type MetadataDepositBase = MetadataDepositBase; type MetadataDepositPerByte = MetadataDepositPerByte; - type ApprovalDeposit = ApprovalDeposit; + type RemoveItemsLimit = ConstU32<1000>; + type RuntimeEvent = RuntimeEvent; type StringLimit = AssetsStringLimit; - type Freezer = (); - type Extra = (); type WeightInfo = pallet_assets::weights::SubstrateWeight; - type CallbackHandle = (); - type AssetAccountDeposit = AssetAccountDeposit; - type RemoveItemsLimit = ConstU32<1000>; - #[cfg(feature = "runtime-benchmarks")] - type BenchmarkHelper = (); } diff --git a/runtime/devnet/src/config/contracts.rs b/runtime/devnet/src/config/contracts.rs index 67a2f33c..6cf923b9 100644 --- a/runtime/devnet/src/config/contracts.rs +++ b/runtime/devnet/src/config/contracts.rs @@ -1,13 +1,14 @@ +use frame_support::{ + parameter_types, + traits::{ConstBool, ConstU32, Randomness}, +}; +use frame_system::{pallet_prelude::BlockNumberFor, EnsureSigned}; + use super::api::{self, Config}; use crate::{ deposit, Balance, Balances, BalancesCall, Perbill, Runtime, RuntimeCall, RuntimeEvent, RuntimeHoldReason, Timestamp, }; -use frame_support::{ - parameter_types, - traits::{ConstBool, ConstU32, Randomness}, -}; -use frame_system::pallet_prelude::BlockNumberFor; pub enum AllowBalancesCall {} @@ -46,12 +47,8 @@ parameter_types! { } impl pallet_contracts::Config for Runtime { - type Time = Timestamp; - type Randomness = DummyRandomness; - type Currency = Balances; - type RuntimeEvent = RuntimeEvent; - type RuntimeCall = RuntimeCall; - + type AddressGenerator = pallet_contracts::DefaultAddressGenerator; + type ApiVersion = (); /// The safest default is to allow no calls at all. /// /// Runtimes should whitelist dispatchables that are allowed to be called from contracts @@ -59,14 +56,16 @@ impl pallet_contracts::Config for Runtime { /// change because that would break already deployed contracts. The `RuntimeCall` structure /// itself is not allowed to change the indices of existing pallets, too. type CallFilter = AllowBalancesCall; - type DepositPerItem = DepositPerItem; - type DepositPerByte = DepositPerByte; type CallStack = [pallet_contracts::Frame; 23]; - type WeightPrice = pallet_transaction_payment::Pallet; - type WeightInfo = pallet_contracts::weights::SubstrateWeight; type ChainExtension = api::Extension; - type Schedule = Schedule; - type AddressGenerator = pallet_contracts::DefaultAddressGenerator; + type CodeHashLockupDepositPercent = CodeHashLockupDepositPercent; + type Currency = Balances; + type Debug = (); + type DefaultDepositLimit = DefaultDepositLimit; + type DepositPerByte = DepositPerByte; + type DepositPerItem = DepositPerItem; + type Environment = (); + type InstantiateOrigin = EnsureSigned; // This node is geared towards development and testing of contracts. // We decided to increase the default allowed contract size for this // reason (the default is `128 * 1024`). @@ -76,16 +75,19 @@ impl pallet_contracts::Config for Runtime { // less friction during development when the requirement here is // just more lax. type MaxCodeLen = ConstU32<{ 256 * 1024 }>; - type DefaultDepositLimit = DefaultDepositLimit; - type MaxStorageKeyLen = ConstU32<128>; type MaxDebugBufferLen = ConstU32<{ 2 * 1024 * 1024 }>; - type UnsafeUnstableInterface = ConstBool; - type CodeHashLockupDepositPercent = CodeHashLockupDepositPercent; type MaxDelegateDependencies = ConstU32<32>; - type RuntimeHoldReason = RuntimeHoldReason; - - type Environment = (); - type Debug = (); + type MaxStorageKeyLen = ConstU32<128>; type Migrations = (); + type Randomness = DummyRandomness; + type RuntimeCall = RuntimeCall; + type RuntimeEvent = RuntimeEvent; + type RuntimeHoldReason = RuntimeHoldReason; + type Schedule = Schedule; + type Time = Timestamp; + type UnsafeUnstableInterface = ConstBool; + type UploadOrigin = EnsureSigned; + type WeightInfo = pallet_contracts::weights::SubstrateWeight; + type WeightPrice = pallet_transaction_payment::Pallet; type Xcm = pallet_xcm::Pallet; } diff --git a/runtime/devnet/src/config/proxy.rs b/runtime/devnet/src/config/proxy.rs index c1142126..ff70240e 100644 --- a/runtime/devnet/src/config/proxy.rs +++ b/runtime/devnet/src/config/proxy.rs @@ -1,5 +1,3 @@ -use super::assets::AssetsCall; -use crate::{Balances, Runtime, RuntimeCall, RuntimeEvent}; use frame_support::traits::InstanceFilter; use pop_runtime_common::proxy::{ AnnouncementDepositBase, AnnouncementDepositFactor, MaxPending, MaxProxies, ProxyDepositBase, @@ -7,6 +5,9 @@ use pop_runtime_common::proxy::{ }; use sp_runtime::traits::BlakeTwo256; +use super::assets::TrustBackedAssetsCall; +use crate::{Balances, Runtime, RuntimeCall, RuntimeEvent}; + impl InstanceFilter for ProxyType { fn filter(&self, c: &RuntimeCall) -> bool { match self { @@ -34,16 +35,16 @@ impl InstanceFilter for ProxyType { }, ProxyType::AssetOwner => matches!( c, - RuntimeCall::Assets(AssetsCall::create { .. }) | - RuntimeCall::Assets(AssetsCall::start_destroy { .. }) | - RuntimeCall::Assets(AssetsCall::destroy_accounts { .. }) | - RuntimeCall::Assets(AssetsCall::destroy_approvals { .. }) | - RuntimeCall::Assets(AssetsCall::finish_destroy { .. }) | - RuntimeCall::Assets(AssetsCall::transfer_ownership { .. }) | - RuntimeCall::Assets(AssetsCall::set_team { .. }) | - RuntimeCall::Assets(AssetsCall::set_metadata { .. }) | - RuntimeCall::Assets(AssetsCall::clear_metadata { .. }) | - RuntimeCall::Assets(AssetsCall::set_min_balance { .. }) | + RuntimeCall::Assets(TrustBackedAssetsCall::create { .. }) | + RuntimeCall::Assets(TrustBackedAssetsCall::start_destroy { .. }) | + RuntimeCall::Assets(TrustBackedAssetsCall::destroy_accounts { .. }) | + RuntimeCall::Assets(TrustBackedAssetsCall::destroy_approvals { .. }) | + RuntimeCall::Assets(TrustBackedAssetsCall::finish_destroy { .. }) | + RuntimeCall::Assets(TrustBackedAssetsCall::transfer_ownership { .. }) | + RuntimeCall::Assets(TrustBackedAssetsCall::set_team { .. }) | + RuntimeCall::Assets(TrustBackedAssetsCall::set_metadata { .. }) | + RuntimeCall::Assets(TrustBackedAssetsCall::clear_metadata { .. }) | + RuntimeCall::Assets(TrustBackedAssetsCall::set_min_balance { .. }) | RuntimeCall::Nfts(pallet_nfts::Call::create { .. }) | RuntimeCall::Nfts(pallet_nfts::Call::destroy { .. }) | RuntimeCall::Nfts(pallet_nfts::Call::redeposit { .. }) | @@ -56,15 +57,15 @@ impl InstanceFilter for ProxyType { ), ProxyType::AssetManager => matches!( c, - RuntimeCall::Assets(AssetsCall::mint { .. }) | - RuntimeCall::Assets(AssetsCall::burn { .. }) | - RuntimeCall::Assets(AssetsCall::freeze { .. }) | - RuntimeCall::Assets(AssetsCall::block { .. }) | - RuntimeCall::Assets(AssetsCall::thaw { .. }) | - RuntimeCall::Assets(AssetsCall::freeze_asset { .. }) | - RuntimeCall::Assets(AssetsCall::thaw_asset { .. }) | - RuntimeCall::Assets(AssetsCall::touch_other { .. }) | - RuntimeCall::Assets(AssetsCall::refund_other { .. }) | + RuntimeCall::Assets(TrustBackedAssetsCall::mint { .. }) | + RuntimeCall::Assets(TrustBackedAssetsCall::burn { .. }) | + RuntimeCall::Assets(TrustBackedAssetsCall::freeze { .. }) | + RuntimeCall::Assets(TrustBackedAssetsCall::block { .. }) | + RuntimeCall::Assets(TrustBackedAssetsCall::thaw { .. }) | + RuntimeCall::Assets(TrustBackedAssetsCall::freeze_asset { .. }) | + RuntimeCall::Assets(TrustBackedAssetsCall::thaw_asset { .. }) | + RuntimeCall::Assets(TrustBackedAssetsCall::touch_other { .. }) | + RuntimeCall::Assets(TrustBackedAssetsCall::refund_other { .. }) | RuntimeCall::Nfts(pallet_nfts::Call::force_mint { .. }) | RuntimeCall::Nfts(pallet_nfts::Call::update_mint_settings { .. }) | RuntimeCall::Nfts(pallet_nfts::Call::mint_pre_signed { .. }) | @@ -94,16 +95,16 @@ impl InstanceFilter for ProxyType { } impl pallet_proxy::Config for Runtime { - type RuntimeEvent = RuntimeEvent; - type RuntimeCall = RuntimeCall; + type AnnouncementDepositBase = AnnouncementDepositBase; + type AnnouncementDepositFactor = AnnouncementDepositFactor; + type CallHasher = BlakeTwo256; type Currency = Balances; - type ProxyType = ProxyType; + type MaxPending = MaxPending; + type MaxProxies = MaxProxies; type ProxyDepositBase = ProxyDepositBase; type ProxyDepositFactor = ProxyDepositFactor; - type MaxProxies = MaxProxies; + type ProxyType = ProxyType; + type RuntimeCall = RuntimeCall; + type RuntimeEvent = RuntimeEvent; type WeightInfo = pallet_proxy::weights::SubstrateWeight; - type MaxPending = MaxPending; - type CallHasher = BlakeTwo256; - type AnnouncementDepositBase = AnnouncementDepositBase; - type AnnouncementDepositFactor = AnnouncementDepositFactor; } diff --git a/runtime/devnet/src/config/xcm.rs b/runtime/devnet/src/config/xcm.rs index a5b7a04d..40f18c7c 100644 --- a/runtime/devnet/src/config/xcm.rs +++ b/runtime/devnet/src/config/xcm.rs @@ -1,8 +1,5 @@ -use crate::{ - AccountId, AllPalletsWithSystem, Balances, ParachainInfo, ParachainSystem, PolkadotXcm, - Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin, WeightToFee, XcmpQueue, -}; use core::marker::PhantomData; + use frame_support::{ parameter_types, traits::{ConstU32, Contains, ContainsPair, Everything, Get, Nothing}, @@ -13,24 +10,29 @@ use pallet_xcm::XcmPassthrough; use polkadot_parachain_primitives::primitives::Sibling; use polkadot_runtime_common::impls::ToAuthor; use xcm::latest::prelude::*; -#[allow(deprecated)] -use xcm_builder::CurrencyAdapter; use xcm_builder::{ AccountId32Aliases, AllowExplicitUnpaidExecutionFrom, AllowKnownQueryResponses, AllowTopLevelPaidExecutionFrom, EnsureXcmOrigin, FixedWeightBounds, - FrameTransactionalProcessor, IsConcrete, NativeAsset, ParentIsPreset, RelayChainAsNative, - SiblingParachainAsNative, SiblingParachainConvertsVia, SignedAccountId32AsNative, - SignedToAccountId32, SovereignSignedViaLocation, TakeWeightCredit, TrailingSetTopicAsId, - UsingComponents, WithComputedOrigin, WithUniqueTopic, + FrameTransactionalProcessor, FungibleAdapter, IsConcrete, NativeAsset, ParentIsPreset, + RelayChainAsNative, SiblingParachainAsNative, SiblingParachainConvertsVia, + SignedAccountId32AsNative, SignedToAccountId32, SovereignSignedViaLocation, TakeWeightCredit, + TrailingSetTopicAsId, UsingComponents, WithComputedOrigin, WithUniqueTopic, }; use xcm_executor::XcmExecutor; +use crate::{ + AccountId, AllPalletsWithSystem, Balances, ParachainInfo, ParachainSystem, PolkadotXcm, + Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin, WeightToFee, XcmpQueue, +}; + parameter_types! { pub const RelayLocation: Location = Location::parent(); pub AssetHub: Location = Location::new(1, [Parachain(1000)]); // Note: Paseo currently uses Polkadot https://github.com/paseo-network/runtimes/blob/abc4ae9c5ae8f0166aab7ef2b427b3c2c6d5ce5c/relay/paseo/src/xcm_config.rs#L56 pub const RelayNetwork: Option = Some(Polkadot); pub RelayChainOrigin: RuntimeOrigin = cumulus_pallet_xcm::Origin::Relay.into(); + // For the real deployment, it is recommended to set `RelayNetwork` according to the relay chain + // and prepend `UniversalLocation` with `GlobalConsensus(RelayNetwork::get())`. pub UniversalLocation: InteriorLocation = Parachain(ParachainInfo::parachain_id().into()).into(); } @@ -48,7 +50,7 @@ pub type LocationToAccountId = ( /// Means for transacting assets on this chain. #[allow(deprecated)] -pub type LocalAssetTransactor = CurrencyAdapter< +pub type LocalAssetTransactor = FungibleAdapter< // Use this currency: Balances, // Use this currency when it is a fungible asset matching the given location or name: @@ -125,33 +127,38 @@ pub type TrustedReserves = (NativeAsset, NativeAssetFrom); pub struct XcmConfig; impl xcm_executor::Config for XcmConfig { - type RuntimeCall = RuntimeCall; - type XcmSender = XcmRouter; + type Aliasers = Nothing; + type AssetClaims = PolkadotXcm; + type AssetExchanger = (); + type AssetLocker = (); // How to withdraw and deposit an asset. type AssetTransactor = LocalAssetTransactor; - type OriginConverter = XcmOriginToTransactDispatchOrigin; - type IsReserve = TrustedReserves; - type IsTeleporter = (); // Teleporting is disabled. - type UniversalLocation = UniversalLocation; - type Barrier = Barrier; - type Weigher = FixedWeightBounds; - type Trader = - UsingComponents>; - type ResponseHandler = PolkadotXcm; type AssetTrap = PolkadotXcm; - type AssetClaims = PolkadotXcm; - type SubscriptionService = PolkadotXcm; - type PalletInstancesInfo = AllPalletsWithSystem; - type MaxAssetsIntoHolding = MaxAssetsIntoHolding; - type AssetLocker = (); - type AssetExchanger = (); + type Barrier = Barrier; + type CallDispatcher = RuntimeCall; type FeeManager = (); + type HrmpChannelAcceptedHandler = (); + type HrmpChannelClosingHandler = (); + type HrmpNewChannelOpenRequestHandler = (); + type IsReserve = TrustedReserves; + type IsTeleporter = (); + type MaxAssetsIntoHolding = MaxAssetsIntoHolding; type MessageExporter = (); - type UniversalAliases = Nothing; - type CallDispatcher = RuntimeCall; + type OriginConverter = XcmOriginToTransactDispatchOrigin; + type PalletInstancesInfo = AllPalletsWithSystem; + type ResponseHandler = PolkadotXcm; + type RuntimeCall = RuntimeCall; type SafeCallFilter = Everything; - type Aliasers = Nothing; + type SubscriptionService = PolkadotXcm; + type Trader = + UsingComponents>; type TransactionalProcessor = FrameTransactionalProcessor; + type UniversalAliases = Nothing; + // Teleporting is disabled. + type UniversalLocation = UniversalLocation; + type Weigher = FixedWeightBounds; + type XcmRecorder = PolkadotXcm; + type XcmSender = XcmRouter; } /// No local origins on this chain are allowed to dispatch XCM sends/executions. @@ -167,34 +174,32 @@ pub type XcmRouter = WithUniqueTopic<( )>; impl pallet_xcm::Config for Runtime { - type RuntimeEvent = RuntimeEvent; - type SendXcmOrigin = EnsureXcmOrigin; - type XcmRouter = XcmRouter; - type ExecuteXcmOrigin = EnsureXcmOrigin; - type XcmExecuteFilter = Nothing; - // ^ Disable dispatchable execute on the XCM pallet. - // Needs to be `Everything` for local testing. - type XcmExecutor = XcmExecutor; - type XcmTeleportFilter = Nothing; - // TODO: add filter to only allow reserve transfers of native to relay/asset hub - type XcmReserveTransferFilter = Everything; - type Weigher = FixedWeightBounds; - type UniversalLocation = UniversalLocation; - type RuntimeOrigin = RuntimeOrigin; - type RuntimeCall = RuntimeCall; - - const VERSION_DISCOVERY_QUEUE_SIZE: u32 = 100; + type AdminOrigin = EnsureRoot; // ^ Override for AdvertisedXcmVersion default type AdvertisedXcmVersion = pallet_xcm::CurrentXcmVersion; type Currency = Balances; type CurrencyMatcher = (); - type TrustedLockers = (); - type SovereignAccountOf = LocationToAccountId; + type ExecuteXcmOrigin = EnsureXcmOrigin; type MaxLockers = ConstU32<8>; - type WeightInfo = pallet_xcm::TestWeightInfo; - type AdminOrigin = EnsureRoot; type MaxRemoteLockConsumers = ConstU32<0>; type RemoteLockConsumerIdentifier = (); + type RuntimeCall = RuntimeCall; + type RuntimeEvent = RuntimeEvent; + type RuntimeOrigin = RuntimeOrigin; + type SendXcmOrigin = EnsureXcmOrigin; + type SovereignAccountOf = LocationToAccountId; + type TrustedLockers = (); + type UniversalLocation = UniversalLocation; + type Weigher = FixedWeightBounds; + type WeightInfo = pallet_xcm::TestWeightInfo; + type XcmExecuteFilter = Everything; + type XcmExecutor = XcmExecutor; + // TODO: add filter to only allow reserve transfers of native to relay/asset hub + type XcmReserveTransferFilter = Everything; + type XcmRouter = XcmRouter; + type XcmTeleportFilter = Everything; + + const VERSION_DISCOVERY_QUEUE_SIZE: u32 = 100; } impl cumulus_pallet_xcm::Config for Runtime { diff --git a/runtime/devnet/src/lib.rs b/runtime/devnet/src/lib.rs index 4f4b2e22..ba6ceae6 100644 --- a/runtime/devnet/src/lib.rs +++ b/runtime/devnet/src/lib.rs @@ -10,34 +10,18 @@ include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs")); pub mod config; mod weights; -use cumulus_pallet_parachain_system::RelayNumberMonotonicallyIncreases; -use polkadot_runtime_common::xcm_sender::NoPriceForMessageDelivery; -use smallvec::smallvec; -use sp_api::impl_runtime_apis; -use sp_core::{crypto::KeyTypeId, OpaqueMetadata}; -use sp_runtime::{ - create_runtime_str, generic, impl_opaque_keys, - traits::{BlakeTwo256, Block as BlockT, IdentifyAccount, Verify}, - transaction_validity::{TransactionSource, TransactionValidity}, - ApplyExtrinsicResult, -}; - -use sp_std::prelude::*; -#[cfg(feature = "std")] -use sp_version::NativeVersion; -use sp_version::RuntimeVersion; - use config::xcm::{RelayLocation, XcmOriginToTransactDispatchOrigin}; +use cumulus_pallet_parachain_system::RelayNumberMonotonicallyIncreases; use cumulus_primitives_core::{AggregateMessageOrigin, ParaId}; use frame_support::{ - construct_runtime, derive_impl, + derive_impl, dispatch::DispatchClass, - genesis_builder_helper::{build_config, create_default_config}, + genesis_builder_helper::{build_state, get_preset}, parameter_types, traits::{ fungible::HoldConsideration, tokens::nonfungibles_v2::Inspect, ConstBool, ConstU32, ConstU64, ConstU8, Contains, EitherOfDiverse, EqualPrivilegeOnly, EverythingBut, - LinearStoragePrice, TransformOrigin, + LinearStoragePrice, TransformOrigin, VariantCountOf, }, weights::{ ConstantMultiplier, Weight, WeightToFeeCoefficient, WeightToFeeCoefficients, @@ -49,31 +33,39 @@ use frame_system::{ limits::{BlockLength, BlockWeights}, EnsureRoot, }; +use pallet_api::fungibles; +use pallet_balances::Call as BalancesCall; use pallet_xcm::{EnsureXcm, IsVoiceOfBody}; use parachains_common::message_queue::{NarrowOriginToSibling, ParaIdToSibling}; +use polkadot_runtime_common::xcm_sender::NoPriceForMessageDelivery; +// Polkadot imports +use polkadot_runtime_common::{BlockHashCount, SlowAdjustingFeeUpdate}; pub use pop_runtime_common::{ deposit, AuraId, Balance, BlockNumber, Hash, Nonce, Signature, AVERAGE_ON_INITIALIZE_RATIO, BLOCK_PROCESSING_VELOCITY, DAYS, EXISTENTIAL_DEPOSIT, HOURS, MAXIMUM_BLOCK_WEIGHT, MICROUNIT, MILLIUNIT, MINUTES, NORMAL_DISPATCH_RATIO, RELAY_CHAIN_SLOT_DURATION_MILLIS, SLOT_DURATION, UNINCLUDED_SEGMENT_CAPACITY, UNIT, }; -pub use sp_runtime::{MultiAddress, Perbill, Permill}; - +use smallvec::smallvec; +use sp_api::impl_runtime_apis; +use sp_core::{crypto::KeyTypeId, OpaqueMetadata}; #[cfg(any(feature = "std", test))] pub use sp_runtime::BuildStorage; - -use pallet_balances::Call as BalancesCall; - -// Polkadot imports -use polkadot_runtime_common::{BlockHashCount, SlowAdjustingFeeUpdate}; - +use sp_runtime::{ + create_runtime_str, generic, impl_opaque_keys, + traits::{BlakeTwo256, Block as BlockT, IdentifyAccount, Verify}, + transaction_validity::{TransactionSource, TransactionValidity}, + ApplyExtrinsicResult, +}; +pub use sp_runtime::{ExtrinsicInclusionMode, MultiAddress, Perbill, Permill}; +use sp_std::prelude::*; +#[cfg(feature = "std")] +use sp_version::NativeVersion; +use sp_version::RuntimeVersion; use weights::{BlockExecutionWeight, ExtrinsicBaseWeight, RocksDbWeight}; - // XCM Imports use xcm::latest::prelude::BodyId; -use pallet_api::fungibles; - /// Some way of identifying an account on the chain. We intentionally make it equivalent /// to the public key of our transaction signing scheme. pub type AccountId = <::Signer as IdentifyAccount>::AccountId; @@ -103,6 +95,8 @@ pub type SignedExtra = ( frame_system::CheckNonce, frame_system::CheckWeight, pallet_transaction_payment::ChargeTransactionPayment, + cumulus_primitives_storage_weight_reclaim::StorageWeightReclaim, + frame_metadata_hash_extension::CheckMetadataHash, ); /// Unchecked extrinsic type as expected by this runtime. @@ -131,6 +125,7 @@ pub type Executive = frame_executive::Executive< pub struct WeightToFee; impl WeightToFeePolynomial for WeightToFee { type Balance = Balance; + fn polynomial() -> WeightToFeeCoefficients { // in Rococo, extrinsic base weight (smallest non-zero weight) is mapped to 1 MILLIUNIT: // we map to 1/10 of that, or 1/10 MILLIUNIT @@ -150,13 +145,13 @@ impl WeightToFeePolynomial for WeightToFee { /// of data like extrinsics, allowing for them to continue syncing the network through upgrades /// to even the core data structures. pub mod opaque { - use super::*; + pub use sp_runtime::OpaqueExtrinsic as UncheckedExtrinsic; use sp_runtime::{ generic, traits::{BlakeTwo256, Hash as HashT}, }; - pub use sp_runtime::OpaqueExtrinsic as UncheckedExtrinsic; + use super::*; /// Opaque block header type. pub type Header = generic::Header; /// Opaque block type. @@ -254,48 +249,48 @@ impl Contains for FilteredCalls { /// The default types are being injected by [`derive_impl`](`frame_support::derive_impl`) from /// [`ParaChainDefaultConfig`](`struct@frame_system::config_preludes::ParaChainDefaultConfig`), /// but overridden as needed. -#[derive_impl(frame_system::config_preludes::ParaChainDefaultConfig as frame_system::DefaultConfig)] +#[derive_impl(frame_system::config_preludes::ParaChainDefaultConfig)] impl frame_system::Config for Runtime { + /// The data to be stored in an account. + type AccountData = pallet_balances::AccountData; /// The identifier used to distinguish between accounts. type AccountId = AccountId; - /// The index type for storing how many extrinsics an account has signed. - type Nonce = Nonce; - /// The type for hashing blocks and tries. - type Hash = Hash; + /// The basic call filter to use in dispatchable. Supports everything as the default. + type BaseCallFilter = EverythingBut; /// The block type. type Block = Block; /// Maximum number of block number to block hash mappings to keep (oldest pruned first). type BlockHashCount = BlockHashCount; - /// Runtime version. - type Version = Version; - /// The data to be stored in an account. - type AccountData = pallet_balances::AccountData; - /// The weight of database operations that the runtime can invoke. - type DbWeight = RocksDbWeight; - /// Block & extrinsics weights: base values and limits. - type BlockWeights = RuntimeBlockWeights; /// The maximum length of a block (in bytes). type BlockLength = RuntimeBlockLength; - /// This is used as an identifier of the chain. 42 is the generic substrate prefix. - type SS58Prefix = SS58Prefix; - /// The basic call filter to use in dispatchable. Supports everything as the default. - type BaseCallFilter = EverythingBut; + /// Block & extrinsics weights: base values and limits. + type BlockWeights = RuntimeBlockWeights; + /// The weight of database operations that the runtime can invoke. + type DbWeight = RocksDbWeight; + /// The type for hashing blocks and tries. + type Hash = Hash; + type MaxConsumers = frame_support::traits::ConstU32<16>; + /// The index type for storing how many extrinsics an account has signed. + type Nonce = Nonce; /// The action to take on a Runtime Upgrade type OnSetCode = cumulus_pallet_parachain_system::ParachainSetCode; - type MaxConsumers = frame_support::traits::ConstU32<16>; + /// This is used as an identifier of the chain. 42 is the generic substrate prefix. + type SS58Prefix = SS58Prefix; + /// Runtime version. + type Version = Version; } impl pallet_timestamp::Config for Runtime { + type MinimumPeriod = ConstU64<0>; /// A timestamp: milliseconds since the unix epoch. type Moment = u64; type OnTimestampSet = Aura; - type MinimumPeriod = ConstU64<0>; type WeightInfo = (); } impl pallet_authorship::Config for Runtime { - type FindAuthor = pallet_session::FindAccountFromAuthorIndex; type EventHandler = (CollatorSelection,); + type FindAuthor = pallet_session::FindAccountFromAuthorIndex; } parameter_types! { @@ -303,21 +298,21 @@ parameter_types! { } impl pallet_balances::Config for Runtime { - type MaxLocks = ConstU32<50>; + type AccountStore = System; /// The type for recording an account's balance. type Balance = Balance; - /// The ubiquitous event type. - type RuntimeEvent = RuntimeEvent; type DustRemoval = (); type ExistentialDeposit = ExistentialDeposit; - type AccountStore = System; - type WeightInfo = pallet_balances::weights::SubstrateWeight; + type FreezeIdentifier = RuntimeFreezeReason; + type MaxFreezes = VariantCountOf; + type MaxLocks = ConstU32<50>; type MaxReserves = ConstU32<50>; type ReserveIdentifier = [u8; 8]; - type RuntimeHoldReason = RuntimeHoldReason; + /// The ubiquitous event type. + type RuntimeEvent = RuntimeEvent; type RuntimeFreezeReason = RuntimeFreezeReason; - type FreezeIdentifier = (); - type MaxFreezes = ConstU32<0>; + type RuntimeHoldReason = RuntimeHoldReason; + type WeightInfo = pallet_balances::weights::SubstrateWeight; } parameter_types! { @@ -326,17 +321,17 @@ parameter_types! { } impl pallet_transaction_payment::Config for Runtime { - type RuntimeEvent = RuntimeEvent; - type OnChargeTransaction = pallet_transaction_payment::CurrencyAdapter; - type WeightToFee = WeightToFee; - type LengthToFee = ConstantMultiplier; type FeeMultiplierUpdate = SlowAdjustingFeeUpdate; + type LengthToFee = ConstantMultiplier; + type OnChargeTransaction = pallet_transaction_payment::FungibleAdapter; type OperationalFeeMultiplier = ConstU8<5>; + type RuntimeEvent = RuntimeEvent; + type WeightToFee = WeightToFee; } impl pallet_sudo::Config for Runtime { - type RuntimeEvent = RuntimeEvent; type RuntimeCall = RuntimeCall; + type RuntimeEvent = RuntimeEvent; type WeightInfo = (); } @@ -354,17 +349,17 @@ type ConsensusHook = cumulus_pallet_aura_ext::FixedVelocityConsensusHook< >; impl cumulus_pallet_parachain_system::Config for Runtime { - type WeightInfo = (); - type RuntimeEvent = RuntimeEvent; + type CheckAssociatedRelayNumber = RelayNumberMonotonicallyIncreases; + type ConsensusHook = ConsensusHook; + type DmpQueue = frame_support::traits::EnqueueWithOrigin; type OnSystemEvent = (); - type SelfParaId = parachain_info::Pallet; type OutboundXcmpMessageSource = XcmpQueue; - type DmpQueue = frame_support::traits::EnqueueWithOrigin; type ReservedDmpWeight = ReservedDmpWeight; - type XcmpMessageHandler = XcmpQueue; type ReservedXcmpWeight = ReservedXcmpWeight; - type CheckAssociatedRelayNumber = RelayNumberMonotonicallyIncreases; - type ConsensusHook = ConsensusHook; + type RuntimeEvent = RuntimeEvent; + type SelfParaId = parachain_info::Pallet; + type WeightInfo = (); + type XcmpMessageHandler = XcmpQueue; } impl parachain_info::Config for Runtime {} @@ -374,8 +369,9 @@ parameter_types! { } impl pallet_message_queue::Config for Runtime { - type RuntimeEvent = RuntimeEvent; - type WeightInfo = (); + type HeapSize = sp_core::ConstU32<{ 103 * 1024 }>; + type IdleMaxServiceWeight = (); + type MaxStale = sp_core::ConstU32<8>; #[cfg(feature = "runtime-benchmarks")] type MessageProcessor = pallet_message_queue::mock_helpers::NoopMessageProcessor< cumulus_primitives_core::AggregateMessageOrigin, @@ -386,28 +382,32 @@ impl pallet_message_queue::Config for Runtime { xcm_executor::XcmExecutor, RuntimeCall, >; - type Size = u32; // The XCMP queue pallet is only ever able to handle the `Sibling(ParaId)` origin: type QueueChangeHandler = NarrowOriginToSibling; type QueuePausedQuery = NarrowOriginToSibling; - type HeapSize = sp_core::ConstU32<{ 64 * 1024 }>; - type MaxStale = sp_core::ConstU32<8>; + type RuntimeEvent = RuntimeEvent; type ServiceWeight = MessageQueueServiceWeight; + type Size = u32; + type WeightInfo = (); } impl cumulus_pallet_aura_ext::Config for Runtime {} impl cumulus_pallet_xcmp_queue::Config for Runtime { - type RuntimeEvent = RuntimeEvent; type ChannelInfo = ParachainSystem; - type VersionWrapper = (); - // Enqueue XCMP messages from siblings for later processing. - type XcmpQueue = TransformOrigin; - type MaxInboundSuspended = sp_core::ConstU32<1_000>; type ControllerOrigin = EnsureRoot; type ControllerOriginConverter = XcmOriginToTransactDispatchOrigin; - type WeightInfo = (); + // Limit the number of messages and signals a HRML channel can have at most + type MaxActiveOutboundChannels = ConstU32<128>; + type MaxInboundSuspended = sp_core::ConstU32<1_000>; + // Limit the number of HRML channels + type MaxPageSize = ConstU32<{ 103 * 1024 }>; type PriceForSiblingDelivery = NoPriceForMessageDelivery; + type RuntimeEvent = RuntimeEvent; + type VersionWrapper = (); + type WeightInfo = (); + // Enqueue XCMP messages from siblings for later processing. + type XcmpQueue = TransformOrigin; } parameter_types! { @@ -416,24 +416,24 @@ parameter_types! { } impl pallet_session::Config for Runtime { + type Keys = SessionKeys; + type NextSessionRotation = pallet_session::PeriodicSessions; type RuntimeEvent = RuntimeEvent; + // Essentially just Aura, but let's be pedantic. + type SessionHandler = ::KeyTypeIdProviders; + type SessionManager = CollatorSelection; + type ShouldEndSession = pallet_session::PeriodicSessions; type ValidatorId = ::AccountId; // we don't have stash and controller, thus we don't need the convert as well. type ValidatorIdOf = pallet_collator_selection::IdentityCollator; - type ShouldEndSession = pallet_session::PeriodicSessions; - type NextSessionRotation = pallet_session::PeriodicSessions; - type SessionManager = CollatorSelection; - // Essentially just Aura, but let's be pedantic. - type SessionHandler = ::KeyTypeIdProviders; - type Keys = SessionKeys; type WeightInfo = (); } impl pallet_aura::Config for Runtime { + type AllowMultipleBlocksPerSlot = ConstBool; type AuthorityId = AuraId; type DisabledValidators = (); type MaxAuthorities = ConstU32<100_000>; - type AllowMultipleBlocksPerSlot = ConstBool; type SlotDuration = ConstU64; } @@ -451,15 +451,15 @@ pub type CollatorSelectionUpdateOrigin = EitherOfDiverse< >; impl pallet_collator_selection::Config for Runtime { - type RuntimeEvent = RuntimeEvent; type Currency = Balances; - type UpdateOrigin = CollatorSelectionUpdateOrigin; - type PotId = PotId; - type MaxCandidates = ConstU32<100>; - type MinEligibleCollators = ConstU32<4>; - type MaxInvulnerables = ConstU32<20>; // should be a multiple of session or things will get inconsistent type KickThreshold = Period; + type MaxCandidates = ConstU32<100>; + type MaxInvulnerables = ConstU32<20>; + type MinEligibleCollators = ConstU32<4>; + type PotId = PotId; + type RuntimeEvent = RuntimeEvent; + type UpdateOrigin = CollatorSelectionUpdateOrigin; type ValidatorId = ::AccountId; type ValidatorIdOf = pallet_collator_selection::IdentityCollator; type ValidatorRegistration = Session; @@ -472,19 +472,19 @@ parameter_types! { } impl pallet_scheduler::Config for Runtime { - type RuntimeEvent = RuntimeEvent; - type RuntimeOrigin = RuntimeOrigin; - type PalletsOrigin = OriginCaller; - type RuntimeCall = RuntimeCall; - type MaximumWeight = MaximumSchedulerWeight; - type ScheduleOrigin = EnsureRoot; #[cfg(feature = "runtime-benchmarks")] type MaxScheduledPerBlock = ConstU32<512>; #[cfg(not(feature = "runtime-benchmarks"))] type MaxScheduledPerBlock = ConstU32<50>; - type WeightInfo = pallet_scheduler::weights::SubstrateWeight; + type MaximumWeight = MaximumSchedulerWeight; type OriginPrivilegeCmp = EqualPrivilegeOnly; + type PalletsOrigin = OriginCaller; type Preimages = Preimage; + type RuntimeCall = RuntimeCall; + type RuntimeEvent = RuntimeEvent; + type RuntimeOrigin = RuntimeOrigin; + type ScheduleOrigin = EnsureRoot; + type WeightInfo = pallet_scheduler::weights::SubstrateWeight; } parameter_types! { @@ -494,16 +494,16 @@ parameter_types! { } impl pallet_preimage::Config for Runtime { - type WeightInfo = pallet_preimage::weights::SubstrateWeight; - type RuntimeEvent = RuntimeEvent; - type Currency = Balances; - type ManagerOrigin = EnsureRoot; type Consideration = HoldConsideration< AccountId, Balances, PreimageHoldReason, LinearStoragePrice, >; + type Currency = Balances; + type ManagerOrigin = EnsureRoot; + type RuntimeEvent = RuntimeEvent; + type WeightInfo = pallet_preimage::weights::SubstrateWeight; } parameter_types! { @@ -515,76 +515,115 @@ parameter_types! { } impl pallet_multisig::Config for Runtime { - type RuntimeEvent = RuntimeEvent; - type RuntimeCall = RuntimeCall; type Currency = Balances; type DepositBase = DepositBase; type DepositFactor = DepositFactor; type MaxSignatories = MaxSignatories; + type RuntimeCall = RuntimeCall; + type RuntimeEvent = RuntimeEvent; type WeightInfo = pallet_multisig::weights::SubstrateWeight; } impl pallet_utility::Config for Runtime { - type RuntimeEvent = RuntimeEvent; - type RuntimeCall = RuntimeCall; type PalletsOrigin = OriginCaller; + type RuntimeCall = RuntimeCall; + type RuntimeEvent = RuntimeEvent; type WeightInfo = pallet_utility::weights::SubstrateWeight; } -// Create the runtime by composing the FRAME pallets that were previously configured. -construct_runtime!( - pub enum Runtime { - // System support stuff. - System: frame_system = 0, - ParachainSystem: cumulus_pallet_parachain_system = 1, - Timestamp: pallet_timestamp = 2, - ParachainInfo: parachain_info = 3, - - // Monetary stuff. - Balances: pallet_balances = 10, - TransactionPayment: pallet_transaction_payment = 11, - - // Governance - Sudo: pallet_sudo = 15, - - // Collator support. The order of these 4 are important and shall not change. - Authorship: pallet_authorship = 20, - CollatorSelection: pallet_collator_selection = 21, - Session: pallet_session = 22, - Aura: pallet_aura = 23, - AuraExt: cumulus_pallet_aura_ext = 24, - - // Scheduler - Scheduler: pallet_scheduler = 28, - - // Preimage - Preimage: pallet_preimage = 29, - - // XCM helpers. - XcmpQueue: cumulus_pallet_xcmp_queue = 30, - PolkadotXcm: pallet_xcm = 31, - CumulusXcm: cumulus_pallet_xcm = 32, - MessageQueue: pallet_message_queue = 33, - - // Contracts - Contracts: pallet_contracts = 40, - - // Proxy - Proxy: pallet_proxy = 41, - // Multisig - Multisig: pallet_multisig = 42, - // Utility - Utility: pallet_utility = 43, - - // Assets - Nfts: pallet_nfts = 50, - NftFractionalization: pallet_nft_fractionalization = 51, - Assets: pallet_assets:: = 52, - - // Pop API - Fungibles: fungibles = 150, - } -); +#[frame_support::runtime] +mod runtime { + // Create the runtime by composing the FRAME pallets that were previously configured. + #[runtime::runtime] + #[runtime::derive( + RuntimeCall, + RuntimeEvent, + RuntimeError, + RuntimeOrigin, + RuntimeFreezeReason, + RuntimeHoldReason, + RuntimeSlashReason, + RuntimeLockId, + RuntimeTask + )] + pub struct Runtime; + + // System support stuff. + #[runtime::pallet_index(0)] + pub type System = frame_system::Pallet; + #[runtime::pallet_index(1)] + pub type ParachainSystem = cumulus_pallet_parachain_system::Pallet; + #[runtime::pallet_index(2)] + pub type Timestamp = pallet_timestamp::Pallet; + #[runtime::pallet_index(3)] + pub type ParachainInfo = parachain_info::Pallet; + + // Monetary stuff. + #[runtime::pallet_index(10)] + pub type Balances = pallet_balances::Pallet; + #[runtime::pallet_index(11)] + pub type TransactionPayment = pallet_transaction_payment::Pallet; + + // Governance + #[runtime::pallet_index(15)] + pub type Sudo = pallet_sudo; + + // Collator support. The order of these 4 are important and shall not change. + #[runtime::pallet_index(20)] + pub type Authorship = pallet_authorship::Pallet; + #[runtime::pallet_index(21)] + pub type CollatorSelection = pallet_collator_selection::Pallet; + #[runtime::pallet_index(22)] + pub type Session = pallet_session::Pallet; + #[runtime::pallet_index(23)] + pub type Aura = pallet_aura::Pallet; + #[runtime::pallet_index(24)] + pub type AuraExt = cumulus_pallet_aura_ext; + + // Scheduler + #[runtime::pallet_index(28)] + pub type Scheduler = pallet_scheduler; + + // Preimage + #[runtime::pallet_index(29)] + pub type Preimage = pallet_preimage; + + // XCM helpers. + #[runtime::pallet_index(30)] + pub type XcmpQueue = cumulus_pallet_xcmp_queue::Pallet; + #[runtime::pallet_index(31)] + pub type PolkadotXcm = pallet_xcm::Pallet; + #[runtime::pallet_index(32)] + pub type CumulusXcm = cumulus_pallet_xcm::Pallet; + #[runtime::pallet_index(33)] + pub type MessageQueue = pallet_message_queue::Pallet; + + // Contracts + #[runtime::pallet_index(40)] + pub type Contracts = pallet_contracts::Pallet; + + // Proxy + #[runtime::pallet_index(41)] + pub type Proxy = pallet_proxy::Pallet; + // Multisig + #[runtime::pallet_index(42)] + pub type Multisig = pallet_multisig::Pallet; + // Utility + #[runtime::pallet_index(43)] + pub type Utility = pallet_utility::Pallet; + + // Assets + #[runtime::pallet_index(50)] + pub type Nfts = pallet_nfts::Pallet; + #[runtime::pallet_index(51)] + pub type NftFractionalization = pallet_nft_fractionalization::Pallet; + #[runtime::pallet_index(52)] + pub type Assets = pallet_assets::Pallet; + + // Pop API + #[runtime::pallet_index(150)] + pub type Fungibles = fungibles::Pallet; +} #[cfg(feature = "runtime-benchmarks")] mod benches { @@ -610,7 +649,7 @@ impl_runtime_apis! { } fn authorities() -> Vec { - Aura::authorities().into_inner() + pallet_aura::Authorities::::get().into_inner() } } @@ -623,7 +662,7 @@ impl_runtime_apis! { Executive::execute_block(block) } - fn initialize_block(header: &::Header) { + fn initialize_block(header: &::Header) -> ExtrinsicInclusionMode { Executive::initialize_block(header) } } @@ -637,7 +676,7 @@ impl_runtime_apis! { Runtime::metadata_at_version(version) } - fn metadata_versions() -> sp_std::vec::Vec { + fn metadata_versions() -> Vec { Runtime::metadata_versions() } } @@ -911,7 +950,7 @@ impl_runtime_apis! { use frame_system_benchmarking::Pallet as SystemBench; impl frame_system_benchmarking::Config for Runtime { - fn setup_set_code_requirements(code: &sp_std::vec::Vec) -> Result<(), BenchmarkError> { + fn setup_set_code_requirements(code: &Vec) -> Result<(), BenchmarkError> { ParachainSystem::initialize_for_set_code_benchmark(code.len() as u32); Ok(()) } @@ -937,12 +976,16 @@ impl_runtime_apis! { } impl sp_genesis_builder::GenesisBuilder for Runtime { - fn create_default_config() -> Vec { - create_default_config::() + fn build_state(config: Vec) -> sp_genesis_builder::Result { + build_state::(config) + } + + fn get_preset(id: &Option) -> Option> { + get_preset::(id, |_| None) } - fn build_config(config: Vec) -> sp_genesis_builder::Result { - build_config::(config) + fn preset_names() -> Vec { + Default::default() } } } @@ -954,9 +997,10 @@ cumulus_pallet_parachain_system::register_validate_block! { #[cfg(test)] mod tests { - use crate::Runtime; use std::any::TypeId; + use crate::Runtime; + // Ensures that the account id lookup does not perform any state reads. When this changes, // `pallet_api::fungibles` dispatchables need to be re-evaluated. #[test] diff --git a/runtime/devnet/src/weights/paritydb_weights.rs b/runtime/devnet/src/weights/paritydb_weights.rs index 25679703..27f7f1b0 100644 --- a/runtime/devnet/src/weights/paritydb_weights.rs +++ b/runtime/devnet/src/weights/paritydb_weights.rs @@ -32,9 +32,10 @@ pub mod constants { #[cfg(test)] mod test_db_weights { - use super::constants::ParityDbWeight as W; use frame_support::weights::constants; + use super::constants::ParityDbWeight as W; + /// Checks that all weights exist and have sane values. // NOTE: If this test fails but you are sure that the generated values are fine, // you can delete it. diff --git a/runtime/devnet/src/weights/rocksdb_weights.rs b/runtime/devnet/src/weights/rocksdb_weights.rs index 3dd817aa..bacad98c 100644 --- a/runtime/devnet/src/weights/rocksdb_weights.rs +++ b/runtime/devnet/src/weights/rocksdb_weights.rs @@ -32,9 +32,10 @@ pub mod constants { #[cfg(test)] mod test_db_weights { - use super::constants::RocksDbWeight as W; use frame_support::weights::constants; + use super::constants::RocksDbWeight as W; + /// Checks that all weights exist and have sane values. // NOTE: If this test fails but you are sure that the generated values are fine, // you can delete it. diff --git a/runtime/mainnet/Cargo.toml b/runtime/mainnet/Cargo.toml new file mode 100644 index 00000000..a3ddf745 --- /dev/null +++ b/runtime/mainnet/Cargo.toml @@ -0,0 +1,220 @@ +[package] +authors.workspace = true +description.workspace = true +edition.workspace = true +homepage.workspace = true +license.workspace = true +name = "pop-runtime-mainnet" +repository.workspace = true +version = "0.1.0" + +[package.metadata.docs.rs] +targets = [ "x86_64-unknown-linux-gnu" ] + +[build-dependencies] +substrate-wasm-builder.workspace = true + +[dependencies] +codec.workspace = true +scale-info.workspace = true +smallvec.workspace = true + +# Local +pop-runtime-common = { workspace = true, default-features = false } + +# Substrate +frame-benchmarking.workspace = true +frame-executive.workspace = true +frame-metadata-hash-extension.workspace = true +frame-support.workspace = true +frame-system.workspace = true +frame-system-benchmarking.workspace = true +frame-system-rpc-runtime-api.workspace = true +frame-try-runtime.workspace = true +pallet-aura.workspace = true +pallet-authorship.workspace = true +pallet-balances.workspace = true +pallet-message-queue.workspace = true +pallet-multisig.workspace = true +pallet-preimage.workspace = true +pallet-proxy.workspace = true +pallet-scheduler.workspace = true +pallet-session.workspace = true +pallet-sudo.workspace = true +pallet-timestamp.workspace = true +pallet-transaction-payment.workspace = true +pallet-transaction-payment-rpc-runtime-api.workspace = true +pallet-utility.workspace = true +sp-api.workspace = true +sp-block-builder.workspace = true +sp-consensus-aura.workspace = true +sp-core.workspace = true +sp-genesis-builder.workspace = true +sp-inherents.workspace = true +sp-io.workspace = true +sp-offchain.workspace = true +sp-runtime.workspace = true +sp-session.workspace = true +sp-std.workspace = true +sp-transaction-pool.workspace = true +sp-version.workspace = true + +# Polkadot +pallet-xcm.workspace = true +polkadot-parachain-primitives.workspace = true +polkadot-runtime-common.workspace = true +xcm.workspace = true +xcm-builder.workspace = true +xcm-executor.workspace = true + +# Cumulus +cumulus-pallet-aura-ext.workspace = true +cumulus-pallet-parachain-system.workspace = true +cumulus-pallet-session-benchmarking.workspace = true +cumulus-pallet-xcm.workspace = true +cumulus-pallet-xcmp-queue.workspace = true +cumulus-primitives-aura.workspace = true +cumulus-primitives-core.workspace = true +cumulus-primitives-storage-weight-reclaim.workspace = true +cumulus-primitives-utility.workspace = true +pallet-collator-selection.workspace = true +parachain-info.workspace = true +parachains-common.workspace = true + +[dev-dependencies] +enumflags2 = "0.7.9" +env_logger = "0.11.2" +hex = "0.4.3" + +[features] +default = [ "std" ] +std = [ + "codec/std", + "cumulus-pallet-aura-ext/std", + "cumulus-pallet-parachain-system/std", + "cumulus-pallet-session-benchmarking/std", + "cumulus-pallet-xcm/std", + "cumulus-pallet-xcmp-queue/std", + "cumulus-primitives-aura/std", + "cumulus-primitives-core/std", + "cumulus-primitives-storage-weight-reclaim/std", + "cumulus-primitives-utility/std", + "frame-benchmarking/std", + "frame-executive/std", + "frame-metadata-hash-extension/std", + "frame-support/std", + "frame-system-benchmarking/std", + "frame-system-rpc-runtime-api/std", + "frame-system/std", + "frame-try-runtime/std", + "pallet-aura/std", + "pallet-authorship/std", + "pallet-balances/std", + "pallet-collator-selection/std", + "pallet-message-queue/std", + "pallet-multisig/std", + "pallet-preimage/std", + "pallet-proxy/std", + "pallet-scheduler/std", + "pallet-session/std", + "pallet-sudo/std", + "pallet-timestamp/std", + "pallet-transaction-payment-rpc-runtime-api/std", + "pallet-transaction-payment/std", + "pallet-utility/std", + "pallet-xcm/std", + "parachain-info/std", + "parachains-common/std", + "polkadot-parachain-primitives/std", + "polkadot-runtime-common/std", + "pop-runtime-common/std", + "scale-info/std", + "sp-api/std", + "sp-block-builder/std", + "sp-consensus-aura/std", + "sp-core/std", + "sp-genesis-builder/std", + "sp-inherents/std", + "sp-io/std", + "sp-offchain/std", + "sp-runtime/std", + "sp-session/std", + "sp-std/std", + "sp-transaction-pool/std", + "sp-version/std", + "xcm-builder/std", + "xcm-executor/std", + "xcm/std", +] + +runtime-benchmarks = [ + "cumulus-pallet-parachain-system/runtime-benchmarks", + "cumulus-pallet-session-benchmarking/runtime-benchmarks", + "cumulus-pallet-xcmp-queue/runtime-benchmarks", + "cumulus-primitives-core/runtime-benchmarks", + "cumulus-primitives-utility/runtime-benchmarks", + "frame-benchmarking/runtime-benchmarks", + "frame-support/runtime-benchmarks", + "frame-system-benchmarking/runtime-benchmarks", + "frame-system/runtime-benchmarks", + "pallet-balances/runtime-benchmarks", + "pallet-collator-selection/runtime-benchmarks", + "pallet-message-queue/runtime-benchmarks", + "pallet-multisig/runtime-benchmarks", + "pallet-preimage/runtime-benchmarks", + "pallet-proxy/runtime-benchmarks", + "pallet-scheduler/runtime-benchmarks", + "pallet-sudo/runtime-benchmarks", + "pallet-timestamp/runtime-benchmarks", + "pallet-utility/runtime-benchmarks", + "pallet-xcm/runtime-benchmarks", + "parachains-common/runtime-benchmarks", + "polkadot-parachain-primitives/runtime-benchmarks", + "polkadot-runtime-common/runtime-benchmarks", + "pop-runtime-common/runtime-benchmarks", + "sp-runtime/runtime-benchmarks", + "xcm-builder/runtime-benchmarks", + "xcm-executor/runtime-benchmarks", +] + +try-runtime = [ + "cumulus-pallet-aura-ext/try-runtime", + "cumulus-pallet-parachain-system/try-runtime", + "cumulus-pallet-xcm/try-runtime", + "cumulus-pallet-xcmp-queue/try-runtime", + "frame-executive/try-runtime", + "frame-support/try-runtime", + "frame-system/try-runtime", + "frame-try-runtime/try-runtime", + "pallet-aura/try-runtime", + "pallet-authorship/try-runtime", + "pallet-balances/try-runtime", + "pallet-collator-selection/try-runtime", + "pallet-message-queue/try-runtime", + "pallet-multisig/try-runtime", + "pallet-preimage/try-runtime", + "pallet-proxy/try-runtime", + "pallet-scheduler/try-runtime", + "pallet-session/try-runtime", + "pallet-sudo/try-runtime", + "pallet-timestamp/try-runtime", + "pallet-transaction-payment/try-runtime", + "pallet-utility/try-runtime", + "pallet-xcm/try-runtime", + "parachain-info/try-runtime", + "polkadot-runtime-common/try-runtime", + "sp-runtime/try-runtime", +] + +# Enable the metadata hash generation. +# +# This is hidden behind a feature because it increases the compile time. +# The wasm binary needs to be compiled twice, once to fetch the metadata, +# generate the metadata hash and then a second time with the +# `RUNTIME_METADATA_HASH` environment variable set for the `CheckMetadataHash` +# extension. +metadata-hash = [ "substrate-wasm-builder/metadata-hash" ] + +# A convenience feature for enabling things when doing a build +# for an on-chain release. +on-chain-release-build = [ "metadata-hash" ] diff --git a/runtime/mainnet/build.rs b/runtime/mainnet/build.rs new file mode 100644 index 00000000..ecc5fb01 --- /dev/null +++ b/runtime/mainnet/build.rs @@ -0,0 +1,16 @@ +#[cfg(all(feature = "std", feature = "metadata-hash"))] +fn main() { + substrate_wasm_builder::WasmBuilder::init_with_defaults() + .enable_metadata_hash("DOT", 10) + .build() +} + +#[cfg(all(feature = "std", not(feature = "metadata-hash")))] +fn main() { + substrate_wasm_builder::WasmBuilder::build_using_defaults() +} + +/// The wasm builder is deactivated when compiling +/// this crate for wasm to speed up the compilation. +#[cfg(not(feature = "std"))] +fn main() {} diff --git a/runtime/mainnet/src/config/mod.rs b/runtime/mainnet/src/config/mod.rs new file mode 100644 index 00000000..913d0352 --- /dev/null +++ b/runtime/mainnet/src/config/mod.rs @@ -0,0 +1,2 @@ +mod proxy; +pub mod xcm; diff --git a/runtime/mainnet/src/config/proxy.rs b/runtime/mainnet/src/config/proxy.rs new file mode 100644 index 00000000..0b8ab9b9 --- /dev/null +++ b/runtime/mainnet/src/config/proxy.rs @@ -0,0 +1,57 @@ +use frame_support::traits::InstanceFilter; +use pop_runtime_common::proxy::{ + AnnouncementDepositBase, AnnouncementDepositFactor, MaxPending, MaxProxies, ProxyDepositBase, + ProxyDepositFactor, ProxyType, +}; +use sp_runtime::traits::BlakeTwo256; + +use crate::{Balances, Runtime, RuntimeCall, RuntimeEvent}; + +impl InstanceFilter for ProxyType { + fn filter(&self, c: &RuntimeCall) -> bool { + match self { + ProxyType::Any => true, + ProxyType::NonTransfer => !matches!(c, RuntimeCall::Balances { .. }), + ProxyType::CancelProxy => matches!( + c, + RuntimeCall::Proxy(pallet_proxy::Call::reject_announcement { .. }) | + RuntimeCall::Utility { .. } | + RuntimeCall::Multisig { .. } + ), + ProxyType::Assets => { + matches!(c, RuntimeCall::Utility { .. } | RuntimeCall::Multisig { .. }) + }, + ProxyType::AssetOwner => { + matches!(c, RuntimeCall::Utility { .. } | RuntimeCall::Multisig { .. }) + }, + ProxyType::AssetManager => { + matches!(c, RuntimeCall::Utility { .. } | RuntimeCall::Multisig { .. }) + }, + ProxyType::Collator => matches!( + c, + RuntimeCall::CollatorSelection { .. } | + RuntimeCall::Utility { .. } | + RuntimeCall::Multisig { .. } + ), + } + } + + fn is_superset(&self, o: &Self) -> bool { + ProxyType::is_superset(self, o) + } +} + +impl pallet_proxy::Config for Runtime { + type AnnouncementDepositBase = AnnouncementDepositBase; + type AnnouncementDepositFactor = AnnouncementDepositFactor; + type CallHasher = BlakeTwo256; + type Currency = Balances; + type MaxPending = MaxPending; + type MaxProxies = MaxProxies; + type ProxyDepositBase = ProxyDepositBase; + type ProxyDepositFactor = ProxyDepositFactor; + type ProxyType = ProxyType; + type RuntimeCall = RuntimeCall; + type RuntimeEvent = RuntimeEvent; + type WeightInfo = pallet_proxy::weights::SubstrateWeight; +} diff --git a/runtime/mainnet/src/config/xcm.rs b/runtime/mainnet/src/config/xcm.rs new file mode 100644 index 00000000..0b5863a7 --- /dev/null +++ b/runtime/mainnet/src/config/xcm.rs @@ -0,0 +1,213 @@ +use core::marker::PhantomData; + +use frame_support::{ + parameter_types, + traits::{tokens::imbalance::ResolveTo, ConstU32, ContainsPair, Everything, Get, Nothing}, + weights::Weight, +}; +use frame_system::EnsureRoot; +use pallet_xcm::XcmPassthrough; +use parachains_common::xcm_config::{ + AllSiblingSystemParachains, ParentRelayOrSiblingParachains, RelayOrOtherSystemParachains, +}; +use polkadot_parachain_primitives::primitives::Sibling; +use xcm::latest::prelude::*; +use xcm_builder::{ + AccountId32Aliases, AllowKnownQueryResponses, AllowSubscriptionsFrom, + AllowTopLevelPaidExecutionFrom, EnsureXcmOrigin, FixedWeightBounds, + FrameTransactionalProcessor, FungibleAdapter, IsConcrete, NativeAsset, ParentIsPreset, + RelayChainAsNative, SiblingParachainAsNative, SiblingParachainConvertsVia, + SignedAccountId32AsNative, SignedToAccountId32, SovereignSignedViaLocation, TakeWeightCredit, + TrailingSetTopicAsId, UsingComponents, WithComputedOrigin, WithUniqueTopic, + XcmFeeManagerFromComponents, XcmFeeToAccount, +}; +use xcm_executor::XcmExecutor; + +use crate::{ + fee::WeightToFee, AccountId, AllPalletsWithSystem, Balances, ParachainInfo, ParachainSystem, + PolkadotXcm, Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin, SudoAddress, XcmpQueue, +}; + +parameter_types! { + pub const RelayLocation: Location = Location::parent(); + pub AssetHub: Location = Location::new(1, [Parachain(1000)]); + pub const RelayNetwork: Option = Some(Polkadot); + pub RelayChainOrigin: RuntimeOrigin = cumulus_pallet_xcm::Origin::Relay.into(); + pub UniversalLocation: InteriorLocation = [GlobalConsensus(RelayNetwork::get().unwrap()), Parachain(ParachainInfo::parachain_id().into())].into(); +} + +/// Type for specifying how a `Location` can be converted into an `AccountId`. This is used +/// when determining ownership of accounts for asset transacting and when attempting to use XCM +/// `Transact` in order to determine the dispatch Origin. +pub type LocationToAccountId = ( + // The parent (Relay-chain) origin converts to the parent `AccountId`. + ParentIsPreset, + // Sibling parachain origins convert to AccountId via the `ParaId::into`. + SiblingParachainConvertsVia, + // Straight up local `AccountId32` origins just alias directly to `AccountId`. + AccountId32Aliases, +); + +/// Means for transacting assets on this chain. +pub type LocalAssetTransactor = FungibleAdapter< + // Use this currency: + Balances, + // Use this currency when it is a fungible asset matching the given location or name: + IsConcrete, + // Do a simple punn to convert an AccountId32 Location into a native chain account ID: + LocationToAccountId, + // Our chain's account ID type (we can't get away without mentioning it explicitly): + AccountId, + // We don't track any teleports. + (), +>; + +/// This is the type we use to convert an (incoming) XCM origin into a local `Origin` instance, +/// ready for dispatching a transaction with Xcm's `Transact`. There is an `OriginKind` which can +/// biases the kind of local `Origin` it will become. +pub type XcmOriginToTransactDispatchOrigin = ( + // Sovereign account converter; this attempts to derive an `AccountId` from the origin location + // using `LocationToAccountId` and then turn that into the usual `Signed` origin. Useful for + // foreign chains who want to have a local sovereign account on this chain which they control. + SovereignSignedViaLocation, + // Native converter for Relay-chain (Parent) location; will convert to a `Relay` origin when + // recognized. + RelayChainAsNative, + // Native converter for sibling Parachains; will convert to a `SiblingPara` origin when + // recognized. + SiblingParachainAsNative, + // Native signed account converter; this just converts an `AccountId32` origin into a normal + // `RuntimeOrigin::Signed` origin of the same 32-byte value. + SignedAccountId32AsNative, + // Xcm origins can be represented natively under the Xcm pallet's Xcm origin. + XcmPassthrough, +); + +parameter_types! { + // One XCM operation is 1_000_000_000 weight - almost certainly a conservative estimate. + pub UnitWeightCost: Weight = Weight::from_parts(1_000_000_000, 64 * 1024); + pub const MaxInstructions: u32 = 100; + pub const MaxAssetsIntoHolding: u32 = 64; +} + +pub type Barrier = TrailingSetTopicAsId<( + TakeWeightCredit, + AllowKnownQueryResponses, + WithComputedOrigin< + ( + AllowTopLevelPaidExecutionFrom, + AllowSubscriptionsFrom, + ), + UniversalLocation, + ConstU32<8>, + >, +)>; + +/// Asset filter that allows native/relay asset if coming from a certain location. +// Borrowed from https://github.com/paritytech/polkadot-sdk/blob/ea458d0b95d819d31683a8a09ca7973ae10b49be/cumulus/parachains/runtimes/testing/penpal/src/xcm_config.rs#L239 for now +pub struct NativeAssetFrom(PhantomData); +impl> ContainsPair for NativeAssetFrom { + fn contains(asset: &Asset, origin: &Location) -> bool { + let loc = T::get(); + &loc == origin && + matches!(asset, Asset { id: AssetId(asset_loc), fun: Fungible(_a) } + if *asset_loc == Location::from(Parent)) + } +} +pub type TrustedReserves = (NativeAsset, NativeAssetFrom); + +/// Locations that will not be charged fees in the executor, +/// either execution or delivery. +/// We only waive fees for system functions, which these locations represent. +pub type WaivedLocations = (RelayOrOtherSystemParachains,); + +pub struct XcmConfig; +impl xcm_executor::Config for XcmConfig { + type Aliasers = Nothing; + type AssetClaims = PolkadotXcm; + type AssetExchanger = (); + type AssetLocker = (); + // How to withdraw and deposit an asset. + type AssetTransactor = LocalAssetTransactor; + type AssetTrap = PolkadotXcm; + type Barrier = Barrier; + type CallDispatcher = RuntimeCall; + type FeeManager = XcmFeeManagerFromComponents< + WaivedLocations, + XcmFeeToAccount, + >; + type HrmpChannelAcceptedHandler = (); + type HrmpChannelClosingHandler = (); + type HrmpNewChannelOpenRequestHandler = (); + type IsReserve = TrustedReserves; + type IsTeleporter = (); + type MaxAssetsIntoHolding = MaxAssetsIntoHolding; + type MessageExporter = (); + type OriginConverter = XcmOriginToTransactDispatchOrigin; + type PalletInstancesInfo = AllPalletsWithSystem; + type ResponseHandler = PolkadotXcm; + type RuntimeCall = RuntimeCall; + type SafeCallFilter = Everything; + type SubscriptionService = PolkadotXcm; + type Trader = UsingComponents< + WeightToFee, + RelayLocation, + AccountId, + Balances, + ResolveTo, + >; + type TransactionalProcessor = FrameTransactionalProcessor; + type UniversalAliases = Nothing; + type UniversalLocation = UniversalLocation; + type Weigher = FixedWeightBounds; + type XcmRecorder = PolkadotXcm; + type XcmSender = XcmRouter; +} + +/// No local origins on this chain are allowed to dispatch XCM sends/executions. +pub type LocalOriginToLocation = SignedToAccountId32; + +/// The means for routing XCM messages which are not for local execution into the right message +/// queues. +pub type XcmRouter = WithUniqueTopic<( + // Two routers - use UMP to communicate with the relay chain: + cumulus_primitives_utility::ParentAsUmp, + // ..and XCMP to communicate with the sibling chains. + XcmpQueue, +)>; + +impl pallet_xcm::Config for Runtime { + type AdminOrigin = EnsureRoot; + // ^ Override for AdvertisedXcmVersion default. + type AdvertisedXcmVersion = pallet_xcm::CurrentXcmVersion; + type Currency = Balances; + type CurrencyMatcher = (); + type ExecuteXcmOrigin = EnsureXcmOrigin; + type MaxLockers = ConstU32<8>; + type MaxRemoteLockConsumers = ConstU32<0>; + type RemoteLockConsumerIdentifier = (); + type RuntimeCall = RuntimeCall; + type RuntimeEvent = RuntimeEvent; + type RuntimeOrigin = RuntimeOrigin; + type SendXcmOrigin = EnsureXcmOrigin; + type SovereignAccountOf = LocationToAccountId; + type TrustedLockers = (); + type UniversalLocation = UniversalLocation; + type Weigher = FixedWeightBounds; + type WeightInfo = pallet_xcm::TestWeightInfo; + type XcmExecuteFilter = Nothing; + // ^ Disable dispatchable execute on the XCM pallet. + // Needs to be `Everything` for local testing. + type XcmExecutor = XcmExecutor; + // TODO: add filter to only allow reserve transfers of native to relay/asset hub + type XcmReserveTransferFilter = Everything; + type XcmRouter = XcmRouter; + type XcmTeleportFilter = Nothing; + + const VERSION_DISCOVERY_QUEUE_SIZE: u32 = 100; +} + +impl cumulus_pallet_xcm::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type XcmExecutor = XcmExecutor; +} diff --git a/runtime/mainnet/src/lib.rs b/runtime/mainnet/src/lib.rs new file mode 100644 index 00000000..536396af --- /dev/null +++ b/runtime/mainnet/src/lib.rs @@ -0,0 +1,1015 @@ +#![cfg_attr(not(feature = "std"), no_std)] +// `construct_runtime!` does a lot of recursion and requires us to increase the limit to 256. +#![recursion_limit = "256"] + +// Make the WASM binary available. +#[cfg(feature = "std")] +include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs")); + +pub mod config; +mod weights; + +use config::xcm::{RelayLocation, XcmOriginToTransactDispatchOrigin}; +use cumulus_pallet_parachain_system::RelayNumberMonotonicallyIncreases; +use cumulus_primitives_core::{AggregateMessageOrigin, ParaId}; +use frame_support::{ + derive_impl, + dispatch::DispatchClass, + genesis_builder_helper::{build_state, get_preset}, + parameter_types, + traits::{ + fungible::HoldConsideration, tokens::imbalance::ResolveTo, ConstBool, ConstU32, ConstU64, + ConstU8, Contains, EitherOfDiverse, EqualPrivilegeOnly, EverythingBut, LinearStoragePrice, + TransformOrigin, VariantCountOf, + }, + weights::{ConstantMultiplier, Weight}, + PalletId, +}; +use frame_system::{ + limits::{BlockLength, BlockWeights}, + EnsureRoot, +}; +use pallet_balances::Call as BalancesCall; +use pallet_xcm::{EnsureXcm, IsVoiceOfBody}; +use parachains_common::message_queue::{NarrowOriginToSibling, ParaIdToSibling}; +use polkadot_runtime_common::xcm_sender::NoPriceForMessageDelivery; +// Polkadot imports +use polkadot_runtime_common::{BlockHashCount, SlowAdjustingFeeUpdate}; +pub use pop_runtime_common::{ + AuraId, Balance, BlockNumber, Hash, Nonce, Signature, AVERAGE_ON_INITIALIZE_RATIO, + BLOCK_PROCESSING_VELOCITY, DAYS, EXISTENTIAL_DEPOSIT, HOURS, MAXIMUM_BLOCK_WEIGHT, MICROUNIT, + MILLIUNIT, MINUTES, NORMAL_DISPATCH_RATIO, RELAY_CHAIN_SLOT_DURATION_MILLIS, SLOT_DURATION, + UNINCLUDED_SEGMENT_CAPACITY, UNIT, +}; +use sp_api::impl_runtime_apis; +use sp_core::{ + crypto::{KeyTypeId, Ss58Codec}, + OpaqueMetadata, +}; +#[cfg(any(feature = "std", test))] +pub use sp_runtime::BuildStorage; +use sp_runtime::{ + create_runtime_str, generic, impl_opaque_keys, + traits::{BlakeTwo256, Block as BlockT, IdentifyAccount, Verify}, + transaction_validity::{TransactionSource, TransactionValidity}, + ApplyExtrinsicResult, +}; +pub use sp_runtime::{ExtrinsicInclusionMode, MultiAddress, Perbill, Permill}; +use sp_std::prelude::*; +#[cfg(feature = "std")] +use sp_version::NativeVersion; +use sp_version::RuntimeVersion; +use weights::{BlockExecutionWeight, ExtrinsicBaseWeight, RocksDbWeight}; +// XCM Imports +use xcm::latest::prelude::BodyId; + +/// Some way of identifying an account on the chain. We intentionally make it equivalent +/// to the public key of our transaction signing scheme. +pub type AccountId = <::Signer as IdentifyAccount>::AccountId; + +/// The address format for describing accounts. +pub type Address = MultiAddress; + +/// Block header type as expected by this runtime. +pub type Header = generic::Header; + +/// Block type as expected by this runtime. +pub type Block = generic::Block; + +/// A Block signed with a Justification +pub type SignedBlock = generic::SignedBlock; + +/// BlockId type as expected by this runtime. +pub type BlockId = generic::BlockId; + +/// The SignedExtension to the basic transaction logic. +pub type SignedExtra = ( + frame_system::CheckNonZeroSender, + frame_system::CheckSpecVersion, + frame_system::CheckTxVersion, + frame_system::CheckGenesis, + frame_system::CheckEra, + frame_system::CheckNonce, + frame_system::CheckWeight, + pallet_transaction_payment::ChargeTransactionPayment, + cumulus_primitives_storage_weight_reclaim::StorageWeightReclaim, + frame_metadata_hash_extension::CheckMetadataHash, +); + +/// Unchecked extrinsic type as expected by this runtime. +pub type UncheckedExtrinsic = + generic::UncheckedExtrinsic; + +/// Migrations to apply on runtime upgrade. +pub type Migrations = (); + +/// Executive: handles dispatch to the various modules. +pub type Executive = frame_executive::Executive< + Runtime, + Block, + frame_system::ChainContext, + Runtime, + AllPalletsWithSystem, + Migrations, +>; + +pub const fn deposit(items: u32, bytes: u32) -> Balance { + // src: https://github.com/polkadot-fellows/runtimes/blob/main/system-parachains/constants/src/polkadot.rs#L70 + (items as Balance * 20 * UNIT + (bytes as Balance) * 100 * fee::MILLICENTS) / 100 +} + +/// Constants related to Polkadot fee payment. +/// Source: https://github.com/polkadot-fellows/runtimes/blob/main/system-parachains/constants/src/polkadot.rs#L65C47-L65C58 +pub mod fee { + use frame_support::{ + pallet_prelude::Weight, + weights::{ + constants::ExtrinsicBaseWeight, FeePolynomial, WeightToFeeCoefficient, + WeightToFeeCoefficients, WeightToFeePolynomial, + }, + }; + use pop_runtime_common::{Balance, MILLIUNIT}; + use smallvec::smallvec; + pub use sp_runtime::Perbill; + + pub const CENTS: Balance = MILLIUNIT * 10; // 100_000_000 + pub const MILLICENTS: Balance = CENTS / 1_000; // 100_000 + + /// Cost of every transaction byte at Polkadot system parachains. + /// + /// It is the Relay Chain (Polkadot) `TransactionByteFee` / 20. + pub const TRANSACTION_BYTE_FEE: Balance = MILLICENTS / 2; + + /// Handles converting a weight scalar to a fee value, based on the scale and granularity of the + /// node's balance type. + /// + /// This should typically create a mapping between the following ranges: + /// - [0, MAXIMUM_BLOCK_WEIGHT] + /// - [Balance::min, Balance::max] + /// + /// Yet, it can be used for any other sort of change to weight-fee. Some examples being: + /// - Setting it to `0` will essentially disable the weight fee. + /// - Setting it to `1` will cause the literal `#[weight = x]` values to be charged. + pub struct WeightToFee; + impl frame_support::weights::WeightToFee for WeightToFee { + type Balance = Balance; + + fn weight_to_fee(weight: &Weight) -> Self::Balance { + let time_poly: FeePolynomial = RefTimeToFee::polynomial().into(); + let proof_poly: FeePolynomial = ProofSizeToFee::polynomial().into(); + + // Take the maximum instead of the sum to charge by the more scarce resource. + time_poly.eval(weight.ref_time()).max(proof_poly.eval(weight.proof_size())) + } + } + + /// Maps the reference time component of `Weight` to a fee. + pub struct RefTimeToFee; + impl WeightToFeePolynomial for RefTimeToFee { + type Balance = Balance; + + fn polynomial() -> WeightToFeeCoefficients { + // In Polkadot, extrinsic base weight (smallest non-zero weight) is mapped to 1/10 CENT: + // The standard system parachain configuration is 1/20 of that, as in 1/200 CENT. + let p = CENTS; + let q = 200 * Balance::from(ExtrinsicBaseWeight::get().ref_time()); + + smallvec![WeightToFeeCoefficient { + degree: 1, + negative: false, + coeff_frac: Perbill::from_rational(p % q, q), + coeff_integer: p / q, + }] + } + } + + /// Maps the proof size component of `Weight` to a fee. + pub struct ProofSizeToFee; + impl WeightToFeePolynomial for ProofSizeToFee { + type Balance = Balance; + + fn polynomial() -> WeightToFeeCoefficients { + // Map 20kb proof to 1 CENT. + let p = CENTS; + let q = 20_000; + + smallvec![WeightToFeeCoefficient { + degree: 1, + negative: false, + coeff_frac: Perbill::from_rational(p % q, q), + coeff_integer: p / q, + }] + } + } +} + +/// Opaque types. These are used by the CLI to instantiate machinery that don't need to know +/// the specifics of the runtime. They can then be made to be agnostic over specific formats +/// of data like extrinsics, allowing for them to continue syncing the network through upgrades +/// to even the core data structures. +pub mod opaque { + pub use sp_runtime::OpaqueExtrinsic as UncheckedExtrinsic; + use sp_runtime::{ + generic, + traits::{BlakeTwo256, Hash as HashT}, + }; + + use super::*; + /// Opaque block header type. + pub type Header = generic::Header; + /// Opaque block type. + pub type Block = generic::Block; + /// Opaque block identifier type. + pub type BlockId = generic::BlockId; + /// Opaque block hash type. + pub type Hash = ::Output; +} + +impl_opaque_keys! { + pub struct SessionKeys { + pub aura: Aura, + } +} + +#[sp_version::runtime_version] +pub const VERSION: RuntimeVersion = RuntimeVersion { + spec_name: create_runtime_str!("pop"), + impl_name: create_runtime_str!("pop"), + authoring_version: 1, + #[allow(clippy::zero_prefixed_literal)] + spec_version: 00_01_00, + impl_version: 0, + apis: RUNTIME_API_VERSIONS, + transaction_version: 1, + state_version: 1, +}; + +/// The version information used to identify this runtime when compiled natively. +#[cfg(feature = "std")] +pub fn native_version() -> NativeVersion { + NativeVersion { runtime_version: VERSION, can_author_with: Default::default() } +} + +parameter_types! { + pub const Version: RuntimeVersion = VERSION; + + // This part is copied from Substrate's `bin/node/runtime/src/lib.rs`. + // The `RuntimeBlockLength` and `RuntimeBlockWeights` exist here because the + // `DeletionWeightLimit` and `DeletionQueueDepth` depend on those to parameterize + // the lazy contract deletion. + pub RuntimeBlockLength: BlockLength = + BlockLength::max_with_normal_ratio(5 * 1024 * 1024, NORMAL_DISPATCH_RATIO); + pub RuntimeBlockWeights: BlockWeights = BlockWeights::builder() + .base_block(BlockExecutionWeight::get()) + .for_class(DispatchClass::all(), |weights| { + weights.base_extrinsic = ExtrinsicBaseWeight::get(); + }) + .for_class(DispatchClass::Normal, |weights| { + weights.max_total = Some(NORMAL_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT); + }) + .for_class(DispatchClass::Operational, |weights| { + weights.max_total = Some(MAXIMUM_BLOCK_WEIGHT); + // Operational transactions have some extra reserved space, so that they + // are included even if block reached `MAXIMUM_BLOCK_WEIGHT`. + weights.reserved = Some( + MAXIMUM_BLOCK_WEIGHT - NORMAL_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT + ); + }) + .avg_block_initialization(AVERAGE_ON_INITIALIZE_RATIO) + .build_or_panic(); + pub const SS58Prefix: u16 = 0; +} + +/// A type to identify filtered calls. +pub struct FilteredCalls; +impl Contains for FilteredCalls { + fn contains(c: &RuntimeCall) -> bool { + use BalancesCall::*; + matches!( + c, + RuntimeCall::Balances( + force_adjust_total_issuance { .. } | + force_set_balance { .. } | + force_transfer { .. } | + force_unreserve { .. } + ) + ) + } +} + +/// The default types are being injected by [`derive_impl`](`frame_support::derive_impl`) from +/// [`ParaChainDefaultConfig`](`struct@frame_system::config_preludes::ParaChainDefaultConfig`), +/// but overridden as needed. +#[derive_impl(frame_system::config_preludes::ParaChainDefaultConfig)] +impl frame_system::Config for Runtime { + /// The data to be stored in an account. + type AccountData = pallet_balances::AccountData; + /// The identifier used to distinguish between accounts. + type AccountId = AccountId; + /// The basic call filter to use in dispatchable. Supports everything as the default. + type BaseCallFilter = EverythingBut; + /// The block type. + type Block = Block; + /// Maximum number of block number to block hash mappings to keep (oldest pruned first). + type BlockHashCount = BlockHashCount; + /// The maximum length of a block (in bytes). + type BlockLength = RuntimeBlockLength; + /// Block & extrinsics weights: base values and limits. + type BlockWeights = RuntimeBlockWeights; + /// The weight of database operations that the runtime can invoke. + type DbWeight = RocksDbWeight; + /// The type for hashing blocks and tries. + type Hash = Hash; + type MaxConsumers = frame_support::traits::ConstU32<16>; + /// The index type for storing how many extrinsics an account has signed. + type Nonce = Nonce; + /// The action to take on a Runtime Upgrade + type OnSetCode = cumulus_pallet_parachain_system::ParachainSetCode; + /// This is used as an identifier of the chain. 42 is the generic substrate prefix. + type SS58Prefix = SS58Prefix; + /// Runtime version. + type Version = Version; +} + +impl pallet_timestamp::Config for Runtime { + type MinimumPeriod = ConstU64<0>; + /// A timestamp: milliseconds since the unix epoch. + type Moment = u64; + type OnTimestampSet = Aura; + type WeightInfo = (); +} + +impl pallet_authorship::Config for Runtime { + type EventHandler = (CollatorSelection,); + type FindAuthor = pallet_session::FindAccountFromAuthorIndex; +} + +parameter_types! { + // increase ED 100 times to match system chains: 1_000_000_000 + pub const ExistentialDeposit: Balance = EXISTENTIAL_DEPOSIT * 100; +} + +impl pallet_balances::Config for Runtime { + type AccountStore = System; + /// The type for recording an account's balance. + type Balance = Balance; + type DustRemoval = (); + type ExistentialDeposit = ExistentialDeposit; + type FreezeIdentifier = RuntimeFreezeReason; + type MaxFreezes = VariantCountOf; + type MaxLocks = ConstU32<50>; + type MaxReserves = ConstU32<50>; + type ReserveIdentifier = [u8; 8]; + /// The ubiquitous event type. + type RuntimeEvent = RuntimeEvent; + type RuntimeFreezeReason = RuntimeFreezeReason; + type RuntimeHoldReason = RuntimeHoldReason; + type WeightInfo = pallet_balances::weights::SubstrateWeight; +} + +parameter_types! { + /// Relay Chain `TransactionByteFee` / 10 + pub const TransactionByteFee: Balance = fee::TRANSACTION_BYTE_FEE; + pub SudoAddress: AccountId = AccountId::from_ss58check("15NMV2JX1NeMwarQiiZvuJ8ixUcvayFDcu1F9Wz1HNpSc8gP").expect("sudo address is valid SS58"); +} + +impl pallet_transaction_payment::Config for Runtime { + type FeeMultiplierUpdate = SlowAdjustingFeeUpdate; + type LengthToFee = ConstantMultiplier; + type OnChargeTransaction = + pallet_transaction_payment::FungibleAdapter>; + type OperationalFeeMultiplier = ConstU8<5>; + type RuntimeEvent = RuntimeEvent; + type WeightToFee = fee::WeightToFee; +} + +impl pallet_sudo::Config for Runtime { + type RuntimeCall = RuntimeCall; + type RuntimeEvent = RuntimeEvent; + type WeightInfo = (); +} + +parameter_types! { + pub const ReservedXcmpWeight: Weight = MAXIMUM_BLOCK_WEIGHT.saturating_div(4); + pub const ReservedDmpWeight: Weight = MAXIMUM_BLOCK_WEIGHT.saturating_div(4); + pub const RelayOrigin: AggregateMessageOrigin = AggregateMessageOrigin::Parent; +} + +type ConsensusHook = cumulus_pallet_aura_ext::FixedVelocityConsensusHook< + Runtime, + RELAY_CHAIN_SLOT_DURATION_MILLIS, + BLOCK_PROCESSING_VELOCITY, + UNINCLUDED_SEGMENT_CAPACITY, +>; + +impl cumulus_pallet_parachain_system::Config for Runtime { + type CheckAssociatedRelayNumber = RelayNumberMonotonicallyIncreases; + type ConsensusHook = ConsensusHook; + type DmpQueue = frame_support::traits::EnqueueWithOrigin; + type OnSystemEvent = (); + type OutboundXcmpMessageSource = XcmpQueue; + type ReservedDmpWeight = ReservedDmpWeight; + type ReservedXcmpWeight = ReservedXcmpWeight; + type RuntimeEvent = RuntimeEvent; + type SelfParaId = parachain_info::Pallet; + type WeightInfo = (); + type XcmpMessageHandler = XcmpQueue; +} + +impl parachain_info::Config for Runtime {} + +parameter_types! { + pub MessageQueueServiceWeight: Weight = Perbill::from_percent(35) * RuntimeBlockWeights::get().max_block; + pub MessageQueueIdleServiceWeight: Weight = Perbill::from_percent(20) * RuntimeBlockWeights::get().max_block; +} + +impl pallet_message_queue::Config for Runtime { + type HeapSize = ConstU32<{ 64 * 1024 }>; + type IdleMaxServiceWeight = MessageQueueIdleServiceWeight; + type MaxStale = ConstU32<8>; + #[cfg(feature = "runtime-benchmarks")] + type MessageProcessor = + pallet_message_queue::mock_helpers::NoopMessageProcessor; + #[cfg(not(feature = "runtime-benchmarks"))] + type MessageProcessor = xcm_builder::ProcessXcmMessage< + AggregateMessageOrigin, + xcm_executor::XcmExecutor, + RuntimeCall, + >; + // The XCMP queue pallet is only ever able to handle the `Sibling(ParaId)` origin: + type QueueChangeHandler = NarrowOriginToSibling; + type QueuePausedQuery = NarrowOriginToSibling; + type RuntimeEvent = RuntimeEvent; + type ServiceWeight = MessageQueueServiceWeight; + type Size = u32; + type WeightInfo = (); +} + +impl cumulus_pallet_aura_ext::Config for Runtime {} + +impl cumulus_pallet_xcmp_queue::Config for Runtime { + type ChannelInfo = ParachainSystem; + type ControllerOrigin = EnsureRoot; + type ControllerOriginConverter = XcmOriginToTransactDispatchOrigin; + // Limit the number of messages and signals a HRMP channel can have at most + type MaxActiveOutboundChannels = ConstU32<128>; + type MaxInboundSuspended = ConstU32<1_000>; + // Limit the number of HRMP channels + type MaxPageSize = ConstU32<{ 103 * 1024 }>; + type PriceForSiblingDelivery = NoPriceForMessageDelivery; + type RuntimeEvent = RuntimeEvent; + type VersionWrapper = PolkadotXcm; + type WeightInfo = (); + // Enqueue XCMP messages from siblings for later processing. + type XcmpQueue = TransformOrigin; +} + +parameter_types! { + pub const Period: u32 = 6 * HOURS; + pub const Offset: u32 = 0; +} + +impl pallet_session::Config for Runtime { + type Keys = SessionKeys; + type NextSessionRotation = pallet_session::PeriodicSessions; + type RuntimeEvent = RuntimeEvent; + // Essentially just Aura, but let's be pedantic. + type SessionHandler = ::KeyTypeIdProviders; + type SessionManager = CollatorSelection; + type ShouldEndSession = pallet_session::PeriodicSessions; + type ValidatorId = ::AccountId; + // we don't have stash and controller, thus we don't need the convert as well. + type ValidatorIdOf = pallet_collator_selection::IdentityCollator; + type WeightInfo = (); +} + +impl pallet_aura::Config for Runtime { + type AllowMultipleBlocksPerSlot = ConstBool; + type AuthorityId = AuraId; + type DisabledValidators = (); + type MaxAuthorities = ConstU32<100_000>; + type SlotDuration = ConstU64; +} + +parameter_types! { + pub const PotId: PalletId = PalletId(*b"PotStake"); + // StakingAdmin pluralistic body. + pub const StakingAdminBodyId: BodyId = BodyId::Defense; +} + +/// We allow root and the StakingAdmin to execute privileged collator selection operations. +pub type CollatorSelectionUpdateOrigin = EitherOfDiverse< + EnsureRoot, + EnsureXcm>, +>; + +impl pallet_collator_selection::Config for Runtime { + type Currency = Balances; + // should be a multiple of session or things will get inconsistent + type KickThreshold = Period; + type MaxCandidates = ConstU32<0>; + type MaxInvulnerables = ConstU32<20>; + type MinEligibleCollators = ConstU32<3>; + type PotId = PotId; + type RuntimeEvent = RuntimeEvent; + type UpdateOrigin = CollatorSelectionUpdateOrigin; + type ValidatorId = ::AccountId; + type ValidatorIdOf = pallet_collator_selection::IdentityCollator; + type ValidatorRegistration = Session; + type WeightInfo = (); +} + +parameter_types! { + pub MaximumSchedulerWeight: Weight = Perbill::from_percent(60) * + RuntimeBlockWeights::get().max_block; +} + +impl pallet_scheduler::Config for Runtime { + #[cfg(feature = "runtime-benchmarks")] + type MaxScheduledPerBlock = ConstU32<512>; + #[cfg(not(feature = "runtime-benchmarks"))] + type MaxScheduledPerBlock = ConstU32<50>; + type MaximumWeight = MaximumSchedulerWeight; + type OriginPrivilegeCmp = EqualPrivilegeOnly; + type PalletsOrigin = OriginCaller; + type Preimages = Preimage; + type RuntimeCall = RuntimeCall; + type RuntimeEvent = RuntimeEvent; + type RuntimeOrigin = RuntimeOrigin; + type ScheduleOrigin = EnsureRoot; + type WeightInfo = pallet_scheduler::weights::SubstrateWeight; +} + +parameter_types! { + pub const PreimageHoldReason: RuntimeHoldReason = RuntimeHoldReason::Preimage(pallet_preimage::HoldReason::Preimage); + pub const PreimageBaseDeposit: Balance = deposit(2, 64); + pub const PreimageByteDeposit: Balance = deposit(0, 1); +} + +impl pallet_preimage::Config for Runtime { + type Consideration = HoldConsideration< + AccountId, + Balances, + PreimageHoldReason, + LinearStoragePrice, + >; + type Currency = Balances; + type ManagerOrigin = EnsureRoot; + type RuntimeEvent = RuntimeEvent; + type WeightInfo = pallet_preimage::weights::SubstrateWeight; +} + +parameter_types! { + // One storage item; key size is 32; value is size 4+4+16+32 bytes = 56 bytes. + pub const DepositBase: Balance = deposit(1, 88); + // Additional storage item size of 32 bytes. + pub const DepositFactor: Balance = deposit(0, 32); + pub const MaxSignatories: u32 = 100; +} + +impl pallet_multisig::Config for Runtime { + type Currency = Balances; + type DepositBase = DepositBase; + type DepositFactor = DepositFactor; + type MaxSignatories = MaxSignatories; + type RuntimeCall = RuntimeCall; + type RuntimeEvent = RuntimeEvent; + type WeightInfo = pallet_multisig::weights::SubstrateWeight; +} + +impl pallet_utility::Config for Runtime { + type PalletsOrigin = OriginCaller; + type RuntimeCall = RuntimeCall; + type RuntimeEvent = RuntimeEvent; + type WeightInfo = pallet_utility::weights::SubstrateWeight; +} + +#[frame_support::runtime] +mod runtime { + // Create the runtime by composing the FRAME pallets that were previously configured. + #[runtime::runtime] + #[runtime::derive( + RuntimeCall, + RuntimeEvent, + RuntimeError, + RuntimeOrigin, + RuntimeFreezeReason, + RuntimeHoldReason, + RuntimeSlashReason, + RuntimeLockId, + RuntimeTask + )] + pub struct Runtime; + + // System support stuff. + #[runtime::pallet_index(0)] + pub type System = frame_system::Pallet; + #[runtime::pallet_index(1)] + pub type ParachainSystem = cumulus_pallet_parachain_system::Pallet; + #[runtime::pallet_index(2)] + pub type Timestamp = pallet_timestamp::Pallet; + #[runtime::pallet_index(3)] + pub type ParachainInfo = parachain_info::Pallet; + + // Monetary stuff. + #[runtime::pallet_index(10)] + pub type Balances = pallet_balances::Pallet; + #[runtime::pallet_index(11)] + pub type TransactionPayment = pallet_transaction_payment::Pallet; + + // Governance + #[runtime::pallet_index(15)] + pub type Sudo = pallet_sudo; + + // Collator support. The order of these 4 are important and shall not change. + #[runtime::pallet_index(20)] + pub type Authorship = pallet_authorship::Pallet; + #[runtime::pallet_index(21)] + pub type CollatorSelection = pallet_collator_selection::Pallet; + #[runtime::pallet_index(22)] + pub type Session = pallet_session::Pallet; + #[runtime::pallet_index(23)] + pub type Aura = pallet_aura::Pallet; + #[runtime::pallet_index(24)] + pub type AuraExt = cumulus_pallet_aura_ext; + + // Scheduler + #[runtime::pallet_index(28)] + pub type Scheduler = pallet_scheduler; + + // Preimage + #[runtime::pallet_index(29)] + pub type Preimage = pallet_preimage; + + // XCM helpers. + #[runtime::pallet_index(30)] + pub type XcmpQueue = cumulus_pallet_xcmp_queue::Pallet; + #[runtime::pallet_index(31)] + pub type PolkadotXcm = pallet_xcm::Pallet; + #[runtime::pallet_index(32)] + pub type CumulusXcm = cumulus_pallet_xcm::Pallet; + #[runtime::pallet_index(33)] + pub type MessageQueue = pallet_message_queue::Pallet; + + // Proxy + #[runtime::pallet_index(41)] + pub type Proxy = pallet_proxy::Pallet; + // Multisig + #[runtime::pallet_index(42)] + pub type Multisig = pallet_multisig::Pallet; + // Utility + #[runtime::pallet_index(43)] + pub type Utility = pallet_utility::Pallet; +} + +#[cfg(feature = "runtime-benchmarks")] +mod benches { + frame_benchmarking::define_benchmarks!( + [frame_system, SystemBench::] + [pallet_balances, Balances] + [pallet_session, SessionBench::] + [pallet_timestamp, Timestamp] + [pallet_message_queue, MessageQueue] + [pallet_sudo, Sudo] + [pallet_collator_selection, CollatorSelection] + [cumulus_pallet_parachain_system, ParachainSystem] + [cumulus_pallet_xcmp_queue, XcmpQueue] + ); +} + +impl_runtime_apis! { + + impl sp_consensus_aura::AuraApi for Runtime { + fn slot_duration() -> sp_consensus_aura::SlotDuration { + sp_consensus_aura::SlotDuration::from_millis(SLOT_DURATION) + } + + fn authorities() -> Vec { + pallet_aura::Authorities::::get().into_inner() + } + } + + impl sp_api::Core for Runtime { + fn version() -> RuntimeVersion { + VERSION + } + + fn execute_block(block: Block) { + Executive::execute_block(block) + } + + fn initialize_block(header: &::Header) -> ExtrinsicInclusionMode{ + Executive::initialize_block(header) + } + } + + impl sp_api::Metadata for Runtime { + fn metadata() -> OpaqueMetadata { + OpaqueMetadata::new(Runtime::metadata().into()) + } + + fn metadata_at_version(version: u32) -> Option { + Runtime::metadata_at_version(version) + } + + fn metadata_versions() -> sp_std::vec::Vec { + Runtime::metadata_versions() + } + } + + impl sp_block_builder::BlockBuilder for Runtime { + fn apply_extrinsic(extrinsic: ::Extrinsic) -> ApplyExtrinsicResult { + Executive::apply_extrinsic(extrinsic) + } + + fn finalize_block() -> ::Header { + Executive::finalize_block() + } + + fn inherent_extrinsics(data: sp_inherents::InherentData) -> Vec<::Extrinsic> { + data.create_extrinsics() + } + + fn check_inherents( + block: Block, + data: sp_inherents::InherentData, + ) -> sp_inherents::CheckInherentsResult { + data.check_extrinsics(&block) + } + } + + impl sp_transaction_pool::runtime_api::TaggedTransactionQueue for Runtime { + fn validate_transaction( + source: TransactionSource, + tx: ::Extrinsic, + block_hash: ::Hash, + ) -> TransactionValidity { + Executive::validate_transaction(source, tx, block_hash) + } + } + + impl sp_offchain::OffchainWorkerApi for Runtime { + fn offchain_worker(header: &::Header) { + Executive::offchain_worker(header) + } + } + + impl sp_session::SessionKeys for Runtime { + fn generate_session_keys(seed: Option>) -> Vec { + SessionKeys::generate(seed) + } + + fn decode_session_keys( + encoded: Vec, + ) -> Option, KeyTypeId)>> { + SessionKeys::decode_into_raw_public_keys(&encoded) + } + } + + impl frame_system_rpc_runtime_api::AccountNonceApi for Runtime { + fn account_nonce(account: AccountId) -> Nonce { + System::account_nonce(account) + } + } + + impl pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi for Runtime { + fn query_info( + uxt: ::Extrinsic, + len: u32, + ) -> pallet_transaction_payment_rpc_runtime_api::RuntimeDispatchInfo { + TransactionPayment::query_info(uxt, len) + } + fn query_fee_details( + uxt: ::Extrinsic, + len: u32, + ) -> pallet_transaction_payment::FeeDetails { + TransactionPayment::query_fee_details(uxt, len) + } + fn query_weight_to_fee(weight: Weight) -> Balance { + TransactionPayment::weight_to_fee(weight) + } + fn query_length_to_fee(length: u32) -> Balance { + TransactionPayment::length_to_fee(length) + } + } + + impl pallet_transaction_payment_rpc_runtime_api::TransactionPaymentCallApi + for Runtime + { + fn query_call_info( + call: RuntimeCall, + len: u32, + ) -> pallet_transaction_payment::RuntimeDispatchInfo { + TransactionPayment::query_call_info(call, len) + } + fn query_call_fee_details( + call: RuntimeCall, + len: u32, + ) -> pallet_transaction_payment::FeeDetails { + TransactionPayment::query_call_fee_details(call, len) + } + fn query_weight_to_fee(weight: Weight) -> Balance { + TransactionPayment::weight_to_fee(weight) + } + fn query_length_to_fee(length: u32) -> Balance { + TransactionPayment::length_to_fee(length) + } + } + + impl cumulus_primitives_aura::AuraUnincludedSegmentApi for Runtime { + fn can_build_upon( + included_hash: ::Hash, + slot: cumulus_primitives_aura::Slot, + ) -> bool { + ConsensusHook::can_build_upon(included_hash, slot) + } + } + + impl cumulus_primitives_core::CollectCollationInfo for Runtime { + fn collect_collation_info(header: &::Header) -> cumulus_primitives_core::CollationInfo { + ParachainSystem::collect_collation_info(header) + } + } + + #[cfg(feature = "try-runtime")] + impl frame_try_runtime::TryRuntime for Runtime { + fn on_runtime_upgrade(checks: frame_try_runtime::UpgradeCheckSelect) -> (Weight, Weight) { + let weight = Executive::try_runtime_upgrade(checks).unwrap(); + (weight, RuntimeBlockWeights::get().max_block) + } + + fn execute_block( + block: Block, + state_root_check: bool, + signature_check: bool, + select: frame_try_runtime::TryStateSelect, + ) -> Weight { + // NOTE: intentional unwrap: we don't want to propagate the error backwards, and want to + // have a backtrace here. + Executive::try_execute_block(block, state_root_check, signature_check, select).unwrap() + } + } + + #[cfg(feature = "runtime-benchmarks")] + impl frame_benchmarking::Benchmark for Runtime { + fn benchmark_metadata(extra: bool) -> ( + Vec, + Vec, + ) { + use frame_benchmarking::{Benchmarking, BenchmarkList}; + use frame_support::traits::StorageInfoTrait; + use frame_system_benchmarking::Pallet as SystemBench; + use cumulus_pallet_session_benchmarking::Pallet as SessionBench; + + let mut list = Vec::::new(); + list_benchmarks!(list, extra); + + let storage_info = AllPalletsWithSystem::storage_info(); + (list, storage_info) + } + + fn dispatch_benchmark( + config: frame_benchmarking::BenchmarkConfig + ) -> Result, sp_runtime::RuntimeString> { + use frame_benchmarking::{BenchmarkError, Benchmarking, BenchmarkBatch}; + + use frame_system_benchmarking::Pallet as SystemBench; + impl frame_system_benchmarking::Config for Runtime { + fn setup_set_code_requirements(code: &sp_std::vec::Vec) -> Result<(), BenchmarkError> { + ParachainSystem::initialize_for_set_code_benchmark(code.len() as u32); + Ok(()) + } + + fn verify_set_code() { + System::assert_last_event(cumulus_pallet_parachain_system::Event::::ValidationFunctionStored.into()); + } + } + + use cumulus_pallet_session_benchmarking::Pallet as SessionBench; + impl cumulus_pallet_session_benchmarking::Config for Runtime {} + + use frame_support::traits::WhitelistedStorageKeys; + let whitelist = AllPalletsWithSystem::whitelisted_storage_keys(); + + let mut batches = Vec::::new(); + let params = (&config, &whitelist); + add_benchmarks!(params, batches); + + if batches.is_empty() { return Err("Benchmark not found for this pallet.".into()) } + Ok(batches) + } + } + + impl sp_genesis_builder::GenesisBuilder for Runtime { + fn build_state(config: Vec) -> sp_genesis_builder::Result { + build_state::(config) + } + + fn get_preset(id: &Option) -> Option> { + get_preset::(id, |_| None) + } + + fn preset_names() -> Vec { + Default::default() + } + } +} + +cumulus_pallet_parachain_system::register_validate_block! { + Runtime = Runtime, + BlockExecutor = cumulus_pallet_aura_ext::BlockExecutor::, +} + +#[cfg(test)] +mod tests { + use std::any::TypeId; + + use pallet_balances::AdjustmentDirection; + use BalancesCall::*; + use RuntimeCall::Balances; + + use super::*; + #[test] + fn filtering_force_adjust_total_issuance_works() { + assert!(FilteredCalls::contains(&Balances(force_adjust_total_issuance { + direction: AdjustmentDirection::Increase, + delta: 0 + }))); + } + + #[test] + fn filtering_force_set_balance_works() { + assert!(FilteredCalls::contains(&Balances(force_set_balance { + who: MultiAddress::Address32([0u8; 32]), + new_free: 0, + }))); + } + + #[test] + fn filtering_force_transfer_works() { + assert!(FilteredCalls::contains(&Balances(force_transfer { + source: MultiAddress::Address32([0u8; 32]), + dest: MultiAddress::Address32([0u8; 32]), + value: 0, + }))); + } + + #[test] + fn filtering_force_unreserve_works() { + assert!(FilteredCalls::contains(&Balances(force_unreserve { + who: MultiAddress::Address32([0u8; 32]), + amount: 0 + }))); + } + + #[test] + fn filtering_configured() { + assert_eq!( + TypeId::of::<::BaseCallFilter>(), + TypeId::of::>(), + ); + } + + #[test] + fn ed_is_correct() { + assert_eq!(ExistentialDeposit::get(), EXISTENTIAL_DEPOSIT * 100); + assert_eq!(ExistentialDeposit::get(), 1_000_000_000); + } + + #[test] + fn units_are_correct() { + // UNIT should have 10 decimals + assert_eq!(UNIT, 10_000_000_000); + assert_eq!(MILLIUNIT, 10_000_000); + assert_eq!(MICROUNIT, 10_000); + + // fee specific units + assert_eq!(fee::CENTS, 100_000_000); + assert_eq!(fee::MILLICENTS, 100_000); + } + + #[test] + fn transaction_byte_fee_is_correct() { + assert_eq!(fee::TRANSACTION_BYTE_FEE, 50_000); + } + + #[test] + fn deposit_works() { + const UNITS: Balance = 10_000_000_000; + const DOLLARS: Balance = UNITS; // 10_000_000_000 + const CENTS: Balance = DOLLARS / 100; // 100_000_000 + const MILLICENTS: Balance = CENTS / 1_000; // 100_000 + + // https://github.com/polkadot-fellows/runtimes/blob/e220854a081f30183999848ce6c11ca62647bcfa/relay/polkadot/constants/src/lib.rs#L36 + fn relay_deposit(items: u32, bytes: u32) -> Balance { + items as Balance * 20 * DOLLARS + (bytes as Balance) * 100 * MILLICENTS + } + + // https://github.com/polkadot-fellows/runtimes/blob/e220854a081f30183999848ce6c11ca62647bcfa/system-parachains/constants/src/polkadot.rs#L70 + fn system_para_deposit(items: u32, bytes: u32) -> Balance { + relay_deposit(items, bytes) / 100 + } + + assert_eq!(deposit(2, 64), system_para_deposit(2, 64)) + } +} diff --git a/runtime/mainnet/src/weights/block_weights.rs b/runtime/mainnet/src/weights/block_weights.rs new file mode 100644 index 00000000..e7fdb2aa --- /dev/null +++ b/runtime/mainnet/src/weights/block_weights.rs @@ -0,0 +1,53 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +pub mod constants { + use frame_support::{ + parameter_types, + weights::{constants, Weight}, + }; + + parameter_types! { + /// Importing a block with 0 Extrinsics. + pub const BlockExecutionWeight: Weight = + Weight::from_parts(constants::WEIGHT_REF_TIME_PER_NANOS.saturating_mul(5_000_000), 0); + } + + #[cfg(test)] + mod test_weights { + use frame_support::weights::constants; + + /// Checks that the weight exists and is sane. + // NOTE: If this test fails but you are sure that the generated values are fine, + // you can delete it. + #[test] + fn sane() { + let w = super::constants::BlockExecutionWeight::get(); + + // At least 100 µs. + assert!( + w.ref_time() >= 100u64 * constants::WEIGHT_REF_TIME_PER_MICROS, + "Weight should be at least 100 µs." + ); + // At most 50 ms. + assert!( + w.ref_time() <= 50u64 * constants::WEIGHT_REF_TIME_PER_MILLIS, + "Weight should be at most 50 ms." + ); + } + } +} diff --git a/runtime/mainnet/src/weights/extrinsic_weights.rs b/runtime/mainnet/src/weights/extrinsic_weights.rs new file mode 100644 index 00000000..1a4adb96 --- /dev/null +++ b/runtime/mainnet/src/weights/extrinsic_weights.rs @@ -0,0 +1,53 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +pub mod constants { + use frame_support::{ + parameter_types, + weights::{constants, Weight}, + }; + + parameter_types! { + /// Executing a NO-OP `System::remarks` Extrinsic. + pub const ExtrinsicBaseWeight: Weight = + Weight::from_parts(constants::WEIGHT_REF_TIME_PER_NANOS.saturating_mul(125_000), 0); + } + + #[cfg(test)] + mod test_weights { + use frame_support::weights::constants; + + /// Checks that the weight exists and is sane. + // NOTE: If this test fails but you are sure that the generated values are fine, + // you can delete it. + #[test] + fn sane() { + let w = super::constants::ExtrinsicBaseWeight::get(); + + // At least 10 µs. + assert!( + w.ref_time() >= 10u64 * constants::WEIGHT_REF_TIME_PER_MICROS, + "Weight should be at least 10 µs." + ); + // At most 1 ms. + assert!( + w.ref_time() <= constants::WEIGHT_REF_TIME_PER_MILLIS, + "Weight should be at most 1 ms." + ); + } + } +} diff --git a/runtime/mainnet/src/weights/mod.rs b/runtime/mainnet/src/weights/mod.rs new file mode 100644 index 00000000..b473d49e --- /dev/null +++ b/runtime/mainnet/src/weights/mod.rs @@ -0,0 +1,27 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//! Expose the auto generated weight files. + +pub mod block_weights; +pub mod extrinsic_weights; +pub mod paritydb_weights; +pub mod rocksdb_weights; + +pub use block_weights::constants::BlockExecutionWeight; +pub use extrinsic_weights::constants::ExtrinsicBaseWeight; +pub use rocksdb_weights::constants::RocksDbWeight; diff --git a/runtime/mainnet/src/weights/paritydb_weights.rs b/runtime/mainnet/src/weights/paritydb_weights.rs new file mode 100644 index 00000000..27f7f1b0 --- /dev/null +++ b/runtime/mainnet/src/weights/paritydb_weights.rs @@ -0,0 +1,64 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +pub mod constants { + use frame_support::{ + parameter_types, + weights::{constants, RuntimeDbWeight}, + }; + + parameter_types! { + /// `ParityDB` can be enabled with a feature flag, but is still experimental. These weights + /// are available for brave runtime engineers who may want to try this out as default. + pub const ParityDbWeight: RuntimeDbWeight = RuntimeDbWeight { + read: 8_000 * constants::WEIGHT_REF_TIME_PER_NANOS, + write: 50_000 * constants::WEIGHT_REF_TIME_PER_NANOS, + }; + } + + #[cfg(test)] + mod test_db_weights { + use frame_support::weights::constants; + + use super::constants::ParityDbWeight as W; + + /// Checks that all weights exist and have sane values. + // NOTE: If this test fails but you are sure that the generated values are fine, + // you can delete it. + #[test] + fn sane() { + // At least 1 µs. + assert!( + W::get().reads(1).ref_time() >= constants::WEIGHT_REF_TIME_PER_MICROS, + "Read weight should be at least 1 µs." + ); + assert!( + W::get().writes(1).ref_time() >= constants::WEIGHT_REF_TIME_PER_MICROS, + "Write weight should be at least 1 µs." + ); + // At most 1 ms. + assert!( + W::get().reads(1).ref_time() <= constants::WEIGHT_REF_TIME_PER_MILLIS, + "Read weight should be at most 1 ms." + ); + assert!( + W::get().writes(1).ref_time() <= constants::WEIGHT_REF_TIME_PER_MILLIS, + "Write weight should be at most 1 ms." + ); + } + } +} diff --git a/runtime/mainnet/src/weights/rocksdb_weights.rs b/runtime/mainnet/src/weights/rocksdb_weights.rs new file mode 100644 index 00000000..bacad98c --- /dev/null +++ b/runtime/mainnet/src/weights/rocksdb_weights.rs @@ -0,0 +1,64 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +pub mod constants { + use frame_support::{ + parameter_types, + weights::{constants, RuntimeDbWeight}, + }; + + parameter_types! { + /// By default, Substrate uses `RocksDB`, so this will be the weight used throughout + /// the runtime. + pub const RocksDbWeight: RuntimeDbWeight = RuntimeDbWeight { + read: 25_000 * constants::WEIGHT_REF_TIME_PER_NANOS, + write: 100_000 * constants::WEIGHT_REF_TIME_PER_NANOS, + }; + } + + #[cfg(test)] + mod test_db_weights { + use frame_support::weights::constants; + + use super::constants::RocksDbWeight as W; + + /// Checks that all weights exist and have sane values. + // NOTE: If this test fails but you are sure that the generated values are fine, + // you can delete it. + #[test] + fn sane() { + // At least 1 µs. + assert!( + W::get().reads(1).ref_time() >= constants::WEIGHT_REF_TIME_PER_MICROS, + "Read weight should be at least 1 µs." + ); + assert!( + W::get().writes(1).ref_time() >= constants::WEIGHT_REF_TIME_PER_MICROS, + "Write weight should be at least 1 µs." + ); + // At most 1 ms. + assert!( + W::get().reads(1).ref_time() <= constants::WEIGHT_REF_TIME_PER_MILLIS, + "Read weight should be at most 1 ms." + ); + assert!( + W::get().writes(1).ref_time() <= constants::WEIGHT_REF_TIME_PER_MILLIS, + "Write weight should be at most 1 ms." + ); + } + } +} diff --git a/runtime/testnet/Cargo.toml b/runtime/testnet/Cargo.toml index 53d20552..54fe7632 100644 --- a/runtime/testnet/Cargo.toml +++ b/runtime/testnet/Cargo.toml @@ -1,15 +1,15 @@ [package] -name = "pop-runtime-testnet" -version = "0.2.0" authors.workspace = true description.workspace = true -license = "Unlicense" +edition.workspace = true homepage.workspace = true +license = "Unlicense" +name = "pop-runtime-testnet" repository.workspace = true -edition.workspace = true +version = "0.4.1" [package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] +targets = [ "x86_64-unknown-linux-gnu" ] [build-dependencies] substrate-wasm-builder.workspace = true @@ -28,14 +28,15 @@ pop-runtime-common.workspace = true # Substrate frame-benchmarking.workspace = true frame-executive.workspace = true +frame-metadata-hash-extension.workspace = true frame-support.workspace = true frame-system.workspace = true frame-system-benchmarking.workspace = true frame-system-rpc-runtime-api.workspace = true frame-try-runtime.workspace = true +pallet-assets.workspace = true pallet-aura.workspace = true pallet-authorship.workspace = true -pallet-assets.workspace = true pallet-balances.workspace = true pallet-contracts.workspace = true pallet-message-queue.workspace = true @@ -43,22 +44,22 @@ pallet-multisig.workspace = true pallet-nft-fractionalization.workspace = true pallet-nfts.workspace = true pallet-nfts-runtime-api.workspace = true +pallet-preimage.workspace = true +pallet-proxy.workspace = true pallet-scheduler.workspace = true pallet-session.workspace = true pallet-sudo.workspace = true -pallet-preimage.workspace = true -pallet-proxy.workspace = true pallet-timestamp.workspace = true pallet-transaction-payment.workspace = true pallet-transaction-payment-rpc-runtime-api.workspace = true pallet-utility.workspace = true sp-api.workspace = true -sp-io.workspace = true sp-block-builder.workspace = true sp-consensus-aura.workspace = true sp-core.workspace = true sp-genesis-builder.workspace = true sp-inherents.workspace = true +sp-io.workspace = true sp-offchain.workspace = true sp-runtime.workspace = true sp-session.workspace = true @@ -82,142 +83,161 @@ cumulus-pallet-xcm.workspace = true cumulus-pallet-xcmp-queue.workspace = true cumulus-primitives-aura.workspace = true cumulus-primitives-core.workspace = true +cumulus-primitives-storage-weight-reclaim.workspace = true cumulus-primitives-utility.workspace = true pallet-collator-selection.workspace = true -parachains-common.workspace = true parachain-info.workspace = true +parachains-common.workspace = true [dev-dependencies] +enumflags2 = "0.7.9" env_logger = "0.11.2" hex = "0.4.3" [features] -default = ["std"] +default = [ "std" ] std = [ - "codec/std", - "cumulus-pallet-aura-ext/std", - "cumulus-pallet-parachain-system/std", - "cumulus-pallet-session-benchmarking/std", - "cumulus-pallet-xcm/std", - "cumulus-pallet-xcmp-queue/std", - "cumulus-primitives-aura/std", - "cumulus-primitives-core/std", - "cumulus-primitives-utility/std", - "frame-benchmarking/std", - "frame-executive/std", - "frame-support/std", - "frame-system-benchmarking/std", - "frame-system-rpc-runtime-api/std", - "frame-system/std", - "frame-try-runtime/std", - "log/std", - "pallet-aura/std", - "pallet-authorship/std", - "pallet-assets/std", - "pallet-balances/std", - "pallet-collator-selection/std", - "pallet-contracts/std", - "pallet-message-queue/std", - "pallet-multisig/std", - "pallet-nft-fractionalization/std", - "pallet-nfts/std", - "pallet-nfts-runtime-api/std", - "pallet-scheduler/std", - "pallet-session/std", - "pallet-sudo/std", - "pallet-preimage/std", - "pallet-proxy/std", - "pallet-timestamp/std", - "pallet-transaction-payment-rpc-runtime-api/std", - "pallet-transaction-payment/std", - "pallet-utility/std", - "pallet-xcm/std", - "parachain-info/std", - "parachains-common/std", - "polkadot-parachain-primitives/std", - "polkadot-runtime-common/std", - "pop-primitives/std", - "scale-info/std", - "sp-api/std", - "sp-io/std", - "sp-block-builder/std", - "sp-consensus-aura/std", - "sp-core/std", - "sp-genesis-builder/std", - "sp-inherents/std", - "sp-offchain/std", - "sp-runtime/std", - "sp-session/std", - "sp-std/std", - "sp-transaction-pool/std", - "sp-version/std", - "xcm-builder/std", - "xcm-executor/std", - "xcm/std", + "codec/std", + "cumulus-pallet-aura-ext/std", + "cumulus-pallet-parachain-system/std", + "cumulus-pallet-session-benchmarking/std", + "cumulus-pallet-xcm/std", + "cumulus-pallet-xcmp-queue/std", + "cumulus-primitives-aura/std", + "cumulus-primitives-core/std", + "cumulus-primitives-storage-weight-reclaim/std", + "cumulus-primitives-utility/std", + "frame-benchmarking/std", + "frame-executive/std", + "frame-metadata-hash-extension/std", + "frame-support/std", + "frame-system-benchmarking/std", + "frame-system-rpc-runtime-api/std", + "frame-system/std", + "frame-try-runtime/std", + "log/std", + "pallet-assets/std", + "pallet-aura/std", + "pallet-authorship/std", + "pallet-balances/std", + "pallet-collator-selection/std", + "pallet-contracts/std", + "pallet-message-queue/std", + "pallet-multisig/std", + "pallet-nft-fractionalization/std", + "pallet-nfts-runtime-api/std", + "pallet-nfts/std", + "pallet-preimage/std", + "pallet-proxy/std", + "pallet-scheduler/std", + "pallet-session/std", + "pallet-sudo/std", + "pallet-timestamp/std", + "pallet-transaction-payment-rpc-runtime-api/std", + "pallet-transaction-payment/std", + "pallet-utility/std", + "pallet-xcm/std", + "parachain-info/std", + "parachains-common/std", + "polkadot-parachain-primitives/std", + "polkadot-runtime-common/std", + "pop-primitives/std", + "pop-runtime-common/std", + "scale-info/std", + "sp-api/std", + "sp-block-builder/std", + "sp-consensus-aura/std", + "sp-core/std", + "sp-genesis-builder/std", + "sp-inherents/std", + "sp-io/std", + "sp-offchain/std", + "sp-runtime/std", + "sp-session/std", + "sp-std/std", + "sp-transaction-pool/std", + "sp-version/std", + "xcm-builder/std", + "xcm-executor/std", + "xcm/std", ] runtime-benchmarks = [ - "cumulus-pallet-parachain-system/runtime-benchmarks", - "cumulus-pallet-session-benchmarking/runtime-benchmarks", - "cumulus-pallet-xcmp-queue/runtime-benchmarks", - "cumulus-primitives-core/runtime-benchmarks", - "cumulus-primitives-utility/runtime-benchmarks", - "frame-benchmarking/runtime-benchmarks", - "frame-support/runtime-benchmarks", - "frame-system-benchmarking/runtime-benchmarks", - "frame-system/runtime-benchmarks", - "pallet-assets/runtime-benchmarks", - "pallet-balances/runtime-benchmarks", - "pallet-collator-selection/runtime-benchmarks", - "pallet-contracts/runtime-benchmarks", - "pallet-message-queue/runtime-benchmarks", - "pallet-multisig/runtime-benchmarks", - "pallet-nft-fractionalization/runtime-benchmarks", - "pallet-nfts/runtime-benchmarks", - "pallet-scheduler/runtime-benchmarks", - "pallet-sudo/runtime-benchmarks", - "pallet-preimage/runtime-benchmarks", - "pallet-proxy/runtime-benchmarks", - "pallet-timestamp/runtime-benchmarks", - "pallet-utility/runtime-benchmarks", - "pallet-xcm/runtime-benchmarks", - "parachains-common/runtime-benchmarks", - "polkadot-parachain-primitives/runtime-benchmarks", - "polkadot-runtime-common/runtime-benchmarks", - "sp-runtime/runtime-benchmarks", - "xcm-builder/runtime-benchmarks", - "xcm-executor/runtime-benchmarks", + "cumulus-pallet-parachain-system/runtime-benchmarks", + "cumulus-pallet-session-benchmarking/runtime-benchmarks", + "cumulus-pallet-xcmp-queue/runtime-benchmarks", + "cumulus-primitives-core/runtime-benchmarks", + "cumulus-primitives-utility/runtime-benchmarks", + "frame-benchmarking/runtime-benchmarks", + "frame-support/runtime-benchmarks", + "frame-system-benchmarking/runtime-benchmarks", + "frame-system/runtime-benchmarks", + "pallet-assets/runtime-benchmarks", + "pallet-balances/runtime-benchmarks", + "pallet-collator-selection/runtime-benchmarks", + "pallet-contracts/runtime-benchmarks", + "pallet-message-queue/runtime-benchmarks", + "pallet-multisig/runtime-benchmarks", + "pallet-nft-fractionalization/runtime-benchmarks", + "pallet-nfts/runtime-benchmarks", + "pallet-preimage/runtime-benchmarks", + "pallet-proxy/runtime-benchmarks", + "pallet-scheduler/runtime-benchmarks", + "pallet-sudo/runtime-benchmarks", + "pallet-timestamp/runtime-benchmarks", + "pallet-utility/runtime-benchmarks", + "pallet-xcm/runtime-benchmarks", + "parachains-common/runtime-benchmarks", + "polkadot-parachain-primitives/runtime-benchmarks", + "polkadot-runtime-common/runtime-benchmarks", + "pop-runtime-common/runtime-benchmarks", + "sp-runtime/runtime-benchmarks", + "xcm-builder/runtime-benchmarks", + "xcm-executor/runtime-benchmarks", ] try-runtime = [ - "cumulus-pallet-aura-ext/try-runtime", - "cumulus-pallet-parachain-system/try-runtime", - "cumulus-pallet-xcm/try-runtime", - "cumulus-pallet-xcmp-queue/try-runtime", - "frame-executive/try-runtime", - "frame-support/try-runtime", - "frame-system/try-runtime", - "frame-try-runtime/try-runtime", - "pallet-aura/try-runtime", - "pallet-authorship/try-runtime", - "pallet-assets/try-runtime", - "pallet-balances/try-runtime", - "pallet-collator-selection/try-runtime", - "pallet-contracts/try-runtime", - "pallet-message-queue/try-runtime", - "pallet-multisig/try-runtime", - "pallet-nft-fractionalization/try-runtime", - "pallet-nfts/try-runtime", - "pallet-scheduler/try-runtime", - "pallet-session/try-runtime", - "pallet-sudo/try-runtime", - "pallet-preimage/try-runtime", - "pallet-proxy/try-runtime", - "pallet-timestamp/try-runtime", - "pallet-transaction-payment/try-runtime", - "pallet-utility/try-runtime", - "pallet-xcm/try-runtime", - "parachain-info/try-runtime", - "polkadot-runtime-common/try-runtime", - "sp-runtime/try-runtime", -] \ No newline at end of file + "cumulus-pallet-aura-ext/try-runtime", + "cumulus-pallet-parachain-system/try-runtime", + "cumulus-pallet-xcm/try-runtime", + "cumulus-pallet-xcmp-queue/try-runtime", + "frame-executive/try-runtime", + "frame-support/try-runtime", + "frame-system/try-runtime", + "frame-try-runtime/try-runtime", + "pallet-assets/try-runtime", + "pallet-aura/try-runtime", + "pallet-authorship/try-runtime", + "pallet-balances/try-runtime", + "pallet-collator-selection/try-runtime", + "pallet-contracts/try-runtime", + "pallet-message-queue/try-runtime", + "pallet-multisig/try-runtime", + "pallet-nft-fractionalization/try-runtime", + "pallet-nfts/try-runtime", + "pallet-preimage/try-runtime", + "pallet-proxy/try-runtime", + "pallet-scheduler/try-runtime", + "pallet-session/try-runtime", + "pallet-sudo/try-runtime", + "pallet-timestamp/try-runtime", + "pallet-transaction-payment/try-runtime", + "pallet-utility/try-runtime", + "pallet-xcm/try-runtime", + "parachain-info/try-runtime", + "polkadot-runtime-common/try-runtime", + "sp-runtime/try-runtime", +] + +# Enable the metadata hash generation. +# +# This is hidden behind a feature because it increases the compile time. +# The wasm binary needs to be compiled twice, once to fetch the metadata, +# generate the metadata hash and then a second time with the +# `RUNTIME_METADATA_HASH` environment variable set for the `CheckMetadataHash` +# extension. +metadata-hash = [ "substrate-wasm-builder/metadata-hash" ] + +# A convenience feature for enabling things when doing a build +# for an on-chain release. +on-chain-release-build = [ "metadata-hash" ] diff --git a/runtime/testnet/build.rs b/runtime/testnet/build.rs index 02d6973f..6293cebb 100644 --- a/runtime/testnet/build.rs +++ b/runtime/testnet/build.rs @@ -1,12 +1,15 @@ -#[cfg(feature = "std")] +#[cfg(all(feature = "std", feature = "metadata-hash"))] fn main() { - substrate_wasm_builder::WasmBuilder::new() - .with_current_project() - .export_heap_base() - .import_memory() + substrate_wasm_builder::WasmBuilder::init_with_defaults() + .enable_metadata_hash("PAS", 10) .build() } +#[cfg(all(feature = "std", not(feature = "metadata-hash")))] +fn main() { + substrate_wasm_builder::WasmBuilder::build_using_defaults() +} + /// The wasm builder is deactivated when compiling /// this crate for wasm to speed up the compilation. #[cfg(not(feature = "std"))] diff --git a/runtime/testnet/src/config/assets.rs b/runtime/testnet/src/config/assets.rs index 2c8ea952..91322ecf 100644 --- a/runtime/testnet/src/config/assets.rs +++ b/runtime/testnet/src/config/assets.rs @@ -1,7 +1,3 @@ -use crate::{ - deposit, AccountId, Assets, Balance, Balances, BlockNumber, Nfts, Runtime, RuntimeEvent, - RuntimeHoldReason, DAYS, EXISTENTIAL_DEPOSIT, UNIT, -}; use frame_support::{ parameter_types, traits::{AsEnsureOriginWithArg, ConstU32}, @@ -12,6 +8,11 @@ use pallet_nfts::PalletFeatures; use parachains_common::{AssetIdForTrustBackedAssets, CollectionId, ItemId, Signature}; use sp_runtime::traits::Verify; +use crate::{ + deposit, AccountId, Assets, Balance, Balances, BlockNumber, Nfts, Runtime, RuntimeEvent, + RuntimeHoldReason, DAYS, EXISTENTIAL_DEPOSIT, UNIT, +}; + /// We allow root to execute privileged asset operations. pub type AssetsForceOrigin = EnsureRoot; @@ -37,36 +38,36 @@ parameter_types! { } impl pallet_nfts::Config for Runtime { - type RuntimeEvent = RuntimeEvent; // TODO: source from primitives - type CollectionId = CollectionId; + type ApprovalsLimit = ConstU32<20>; + type AttributeDepositBase = NftsAttributeDepositBase; + type CollectionDeposit = NftsCollectionDeposit; // TODO: source from primitives - type ItemId = ItemId; - type Currency = Balances; + type CollectionId = CollectionId; type CreateOrigin = AsEnsureOriginWithArg>; + type Currency = Balances; + type DepositPerByte = NftsDepositPerByte; + type Features = NftsPalletFeatures; type ForceOrigin = AssetsForceOrigin; - type Locker = (); - type CollectionDeposit = NftsCollectionDeposit; + #[cfg(feature = "runtime-benchmarks")] + type Helper = (); + type ItemAttributesApprovalsLimit = ConstU32<30>; type ItemDeposit = NftsItemDeposit; - type MetadataDepositBase = NftsMetadataDepositBase; - type AttributeDepositBase = NftsAttributeDepositBase; - type DepositPerByte = NftsDepositPerByte; - type StringLimit = ConstU32<256>; // TODO: source from primitives - type KeyLimit = ConstU32<64>; - type ValueLimit = ConstU32<256>; + type ItemId = ItemId; // TODO: source from primitives - type ApprovalsLimit = ConstU32<20>; - type ItemAttributesApprovalsLimit = ConstU32<30>; - type MaxTips = ConstU32<10>; - type MaxDeadlineDuration = NftsMaxDeadlineDuration; + type KeyLimit = ConstU32<64>; + type Locker = (); type MaxAttributesPerCall = ConstU32<10>; - type Features = NftsPalletFeatures; - type OffchainSignature = Signature; + type MaxDeadlineDuration = NftsMaxDeadlineDuration; + type MaxTips = ConstU32<10>; + type MetadataDepositBase = NftsMetadataDepositBase; type OffchainPublic = ::Signer; + type OffchainSignature = Signature; + type RuntimeEvent = RuntimeEvent; + type StringLimit = ConstU32<256>; + type ValueLimit = ConstU32<256>; type WeightInfo = pallet_nfts::weights::SubstrateWeight; - #[cfg(feature = "runtime-benchmarks")] - type Helper = (); } parameter_types! { @@ -76,46 +77,46 @@ parameter_types! { } impl pallet_nft_fractionalization::Config for Runtime { - type RuntimeEvent = RuntimeEvent; - type Deposit = AssetDeposit; + type AssetBalance = >::Balance; + type AssetId = >::AssetId; + type Assets = Assets; + #[cfg(feature = "runtime-benchmarks")] + type BenchmarkHelper = (); type Currency = Balances; - type NewAssetSymbol = NewAssetSymbol; + type Deposit = AssetDeposit; type NewAssetName = NewAssetName; - type StringLimit = AssetsStringLimit; + type NewAssetSymbol = NewAssetSymbol; type NftCollectionId = ::CollectionId; type NftId = ::ItemId; - type AssetBalance = >::Balance; - type AssetId = >::AssetId; - type Assets = Assets; type Nfts = Nfts; type PalletId = NftFractionalizationPalletId; - type WeightInfo = pallet_nft_fractionalization::weights::SubstrateWeight; + type RuntimeEvent = RuntimeEvent; type RuntimeHoldReason = RuntimeHoldReason; - #[cfg(feature = "runtime-benchmarks")] - type BenchmarkHelper = (); + type StringLimit = AssetsStringLimit; + type WeightInfo = pallet_nft_fractionalization::weights::SubstrateWeight; } pub type TrustBackedAssetsInstance = pallet_assets::Instance1; -pub(crate) type AssetsCall = pallet_assets::Call; +pub type TrustBackedAssetsCall = pallet_assets::Call; impl pallet_assets::Config for Runtime { - type RuntimeEvent = RuntimeEvent; - type Balance = Balance; + type ApprovalDeposit = ApprovalDeposit; + type AssetAccountDeposit = AssetAccountDeposit; + type AssetDeposit = AssetDeposit; type AssetId = AssetIdForTrustBackedAssets; type AssetIdParameter = codec::Compact; - type Currency = Balances; + type Balance = Balance; + #[cfg(feature = "runtime-benchmarks")] + type BenchmarkHelper = (); + type CallbackHandle = (); type CreateOrigin = AsEnsureOriginWithArg>; + type Currency = Balances; + type Extra = (); type ForceOrigin = AssetsForceOrigin; - type AssetDeposit = AssetDeposit; + type Freezer = (); type MetadataDepositBase = MetadataDepositBase; type MetadataDepositPerByte = MetadataDepositPerByte; - type ApprovalDeposit = ApprovalDeposit; + type RemoveItemsLimit = ConstU32<1000>; + type RuntimeEvent = RuntimeEvent; type StringLimit = AssetsStringLimit; - type Freezer = (); - type Extra = (); type WeightInfo = pallet_assets::weights::SubstrateWeight; - type CallbackHandle = (); - type AssetAccountDeposit = AssetAccountDeposit; - type RemoveItemsLimit = ConstU32<1000>; - #[cfg(feature = "runtime-benchmarks")] - type BenchmarkHelper = (); } diff --git a/runtime/testnet/src/config/contracts.rs b/runtime/testnet/src/config/contracts.rs index 36d62f7f..f052b1d3 100644 --- a/runtime/testnet/src/config/contracts.rs +++ b/runtime/testnet/src/config/contracts.rs @@ -1,12 +1,13 @@ -use crate::{ - deposit, extensions, Balance, Balances, BalancesCall, Perbill, Runtime, RuntimeCall, - RuntimeEvent, RuntimeHoldReason, Timestamp, -}; use frame_support::{ parameter_types, traits::{ConstBool, ConstU32, Randomness}, }; -use frame_system::pallet_prelude::BlockNumberFor; +use frame_system::{pallet_prelude::BlockNumberFor, EnsureSigned}; + +use crate::{ + deposit, extensions, Balance, Balances, BalancesCall, Perbill, Runtime, RuntimeCall, + RuntimeEvent, RuntimeHoldReason, Timestamp, +}; pub enum AllowBalancesCall {} @@ -45,12 +46,8 @@ parameter_types! { } impl pallet_contracts::Config for Runtime { - type Time = Timestamp; - type Randomness = DummyRandomness; - type Currency = Balances; - type RuntimeEvent = RuntimeEvent; - type RuntimeCall = RuntimeCall; - + type AddressGenerator = pallet_contracts::DefaultAddressGenerator; + type ApiVersion = (); /// The safest default is to allow no calls at all. /// /// Runtimes should whitelist dispatchables that are allowed to be called from contracts @@ -58,14 +55,16 @@ impl pallet_contracts::Config for Runtime { /// change because that would break already deployed contracts. The `RuntimeCall` structure /// itself is not allowed to change the indices of existing pallets, too. type CallFilter = AllowBalancesCall; - type DepositPerItem = DepositPerItem; - type DepositPerByte = DepositPerByte; type CallStack = [pallet_contracts::Frame; 23]; - type WeightPrice = pallet_transaction_payment::Pallet; - type WeightInfo = pallet_contracts::weights::SubstrateWeight; type ChainExtension = extensions::PopApiExtension; - type Schedule = Schedule; - type AddressGenerator = pallet_contracts::DefaultAddressGenerator; + type CodeHashLockupDepositPercent = CodeHashLockupDepositPercent; + type Currency = Balances; + type Debug = (); + type DefaultDepositLimit = DefaultDepositLimit; + type DepositPerByte = DepositPerByte; + type DepositPerItem = DepositPerItem; + type Environment = (); + type InstantiateOrigin = EnsureSigned; // This node is geared towards development and testing of contracts. // We decided to increase the default allowed contract size for this // reason (the default is `128 * 1024`). @@ -75,16 +74,19 @@ impl pallet_contracts::Config for Runtime { // less friction during development when the requirement here is // just more lax. type MaxCodeLen = ConstU32<{ 256 * 1024 }>; - type DefaultDepositLimit = DefaultDepositLimit; - type MaxStorageKeyLen = ConstU32<128>; type MaxDebugBufferLen = ConstU32<{ 2 * 1024 * 1024 }>; - type UnsafeUnstableInterface = ConstBool; - type CodeHashLockupDepositPercent = CodeHashLockupDepositPercent; type MaxDelegateDependencies = ConstU32<32>; + type MaxStorageKeyLen = ConstU32<128>; + type Migrations = (pallet_contracts::migration::v16::Migration,); + type Randomness = DummyRandomness; + type RuntimeCall = RuntimeCall; + type RuntimeEvent = RuntimeEvent; type RuntimeHoldReason = RuntimeHoldReason; - - type Environment = (); - type Debug = (); - type Migrations = (); + type Schedule = Schedule; + type Time = Timestamp; + type UnsafeUnstableInterface = ConstBool; + type UploadOrigin = EnsureSigned; + type WeightInfo = pallet_contracts::weights::SubstrateWeight; + type WeightPrice = pallet_transaction_payment::Pallet; type Xcm = pallet_xcm::Pallet; } diff --git a/runtime/testnet/src/config/proxy.rs b/runtime/testnet/src/config/proxy.rs index c1142126..ff70240e 100644 --- a/runtime/testnet/src/config/proxy.rs +++ b/runtime/testnet/src/config/proxy.rs @@ -1,5 +1,3 @@ -use super::assets::AssetsCall; -use crate::{Balances, Runtime, RuntimeCall, RuntimeEvent}; use frame_support::traits::InstanceFilter; use pop_runtime_common::proxy::{ AnnouncementDepositBase, AnnouncementDepositFactor, MaxPending, MaxProxies, ProxyDepositBase, @@ -7,6 +5,9 @@ use pop_runtime_common::proxy::{ }; use sp_runtime::traits::BlakeTwo256; +use super::assets::TrustBackedAssetsCall; +use crate::{Balances, Runtime, RuntimeCall, RuntimeEvent}; + impl InstanceFilter for ProxyType { fn filter(&self, c: &RuntimeCall) -> bool { match self { @@ -34,16 +35,16 @@ impl InstanceFilter for ProxyType { }, ProxyType::AssetOwner => matches!( c, - RuntimeCall::Assets(AssetsCall::create { .. }) | - RuntimeCall::Assets(AssetsCall::start_destroy { .. }) | - RuntimeCall::Assets(AssetsCall::destroy_accounts { .. }) | - RuntimeCall::Assets(AssetsCall::destroy_approvals { .. }) | - RuntimeCall::Assets(AssetsCall::finish_destroy { .. }) | - RuntimeCall::Assets(AssetsCall::transfer_ownership { .. }) | - RuntimeCall::Assets(AssetsCall::set_team { .. }) | - RuntimeCall::Assets(AssetsCall::set_metadata { .. }) | - RuntimeCall::Assets(AssetsCall::clear_metadata { .. }) | - RuntimeCall::Assets(AssetsCall::set_min_balance { .. }) | + RuntimeCall::Assets(TrustBackedAssetsCall::create { .. }) | + RuntimeCall::Assets(TrustBackedAssetsCall::start_destroy { .. }) | + RuntimeCall::Assets(TrustBackedAssetsCall::destroy_accounts { .. }) | + RuntimeCall::Assets(TrustBackedAssetsCall::destroy_approvals { .. }) | + RuntimeCall::Assets(TrustBackedAssetsCall::finish_destroy { .. }) | + RuntimeCall::Assets(TrustBackedAssetsCall::transfer_ownership { .. }) | + RuntimeCall::Assets(TrustBackedAssetsCall::set_team { .. }) | + RuntimeCall::Assets(TrustBackedAssetsCall::set_metadata { .. }) | + RuntimeCall::Assets(TrustBackedAssetsCall::clear_metadata { .. }) | + RuntimeCall::Assets(TrustBackedAssetsCall::set_min_balance { .. }) | RuntimeCall::Nfts(pallet_nfts::Call::create { .. }) | RuntimeCall::Nfts(pallet_nfts::Call::destroy { .. }) | RuntimeCall::Nfts(pallet_nfts::Call::redeposit { .. }) | @@ -56,15 +57,15 @@ impl InstanceFilter for ProxyType { ), ProxyType::AssetManager => matches!( c, - RuntimeCall::Assets(AssetsCall::mint { .. }) | - RuntimeCall::Assets(AssetsCall::burn { .. }) | - RuntimeCall::Assets(AssetsCall::freeze { .. }) | - RuntimeCall::Assets(AssetsCall::block { .. }) | - RuntimeCall::Assets(AssetsCall::thaw { .. }) | - RuntimeCall::Assets(AssetsCall::freeze_asset { .. }) | - RuntimeCall::Assets(AssetsCall::thaw_asset { .. }) | - RuntimeCall::Assets(AssetsCall::touch_other { .. }) | - RuntimeCall::Assets(AssetsCall::refund_other { .. }) | + RuntimeCall::Assets(TrustBackedAssetsCall::mint { .. }) | + RuntimeCall::Assets(TrustBackedAssetsCall::burn { .. }) | + RuntimeCall::Assets(TrustBackedAssetsCall::freeze { .. }) | + RuntimeCall::Assets(TrustBackedAssetsCall::block { .. }) | + RuntimeCall::Assets(TrustBackedAssetsCall::thaw { .. }) | + RuntimeCall::Assets(TrustBackedAssetsCall::freeze_asset { .. }) | + RuntimeCall::Assets(TrustBackedAssetsCall::thaw_asset { .. }) | + RuntimeCall::Assets(TrustBackedAssetsCall::touch_other { .. }) | + RuntimeCall::Assets(TrustBackedAssetsCall::refund_other { .. }) | RuntimeCall::Nfts(pallet_nfts::Call::force_mint { .. }) | RuntimeCall::Nfts(pallet_nfts::Call::update_mint_settings { .. }) | RuntimeCall::Nfts(pallet_nfts::Call::mint_pre_signed { .. }) | @@ -94,16 +95,16 @@ impl InstanceFilter for ProxyType { } impl pallet_proxy::Config for Runtime { - type RuntimeEvent = RuntimeEvent; - type RuntimeCall = RuntimeCall; + type AnnouncementDepositBase = AnnouncementDepositBase; + type AnnouncementDepositFactor = AnnouncementDepositFactor; + type CallHasher = BlakeTwo256; type Currency = Balances; - type ProxyType = ProxyType; + type MaxPending = MaxPending; + type MaxProxies = MaxProxies; type ProxyDepositBase = ProxyDepositBase; type ProxyDepositFactor = ProxyDepositFactor; - type MaxProxies = MaxProxies; + type ProxyType = ProxyType; + type RuntimeCall = RuntimeCall; + type RuntimeEvent = RuntimeEvent; type WeightInfo = pallet_proxy::weights::SubstrateWeight; - type MaxPending = MaxPending; - type CallHasher = BlakeTwo256; - type AnnouncementDepositBase = AnnouncementDepositBase; - type AnnouncementDepositFactor = AnnouncementDepositFactor; } diff --git a/runtime/testnet/src/config/xcm.rs b/runtime/testnet/src/config/xcm.rs index a5b7a04d..4fe54a4f 100644 --- a/runtime/testnet/src/config/xcm.rs +++ b/runtime/testnet/src/config/xcm.rs @@ -1,8 +1,5 @@ -use crate::{ - AccountId, AllPalletsWithSystem, Balances, ParachainInfo, ParachainSystem, PolkadotXcm, - Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin, WeightToFee, XcmpQueue, -}; use core::marker::PhantomData; + use frame_support::{ parameter_types, traits::{ConstU32, Contains, ContainsPair, Everything, Get, Nothing}, @@ -13,24 +10,29 @@ use pallet_xcm::XcmPassthrough; use polkadot_parachain_primitives::primitives::Sibling; use polkadot_runtime_common::impls::ToAuthor; use xcm::latest::prelude::*; -#[allow(deprecated)] -use xcm_builder::CurrencyAdapter; use xcm_builder::{ AccountId32Aliases, AllowExplicitUnpaidExecutionFrom, AllowKnownQueryResponses, AllowTopLevelPaidExecutionFrom, EnsureXcmOrigin, FixedWeightBounds, - FrameTransactionalProcessor, IsConcrete, NativeAsset, ParentIsPreset, RelayChainAsNative, - SiblingParachainAsNative, SiblingParachainConvertsVia, SignedAccountId32AsNative, - SignedToAccountId32, SovereignSignedViaLocation, TakeWeightCredit, TrailingSetTopicAsId, - UsingComponents, WithComputedOrigin, WithUniqueTopic, + FrameTransactionalProcessor, FungibleAdapter, IsConcrete, NativeAsset, ParentIsPreset, + RelayChainAsNative, SiblingParachainAsNative, SiblingParachainConvertsVia, + SignedAccountId32AsNative, SignedToAccountId32, SovereignSignedViaLocation, TakeWeightCredit, + TrailingSetTopicAsId, UsingComponents, WithComputedOrigin, WithUniqueTopic, }; use xcm_executor::XcmExecutor; +use crate::{ + AccountId, AllPalletsWithSystem, Balances, ParachainInfo, ParachainSystem, PolkadotXcm, + Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin, WeightToFee, XcmpQueue, +}; + parameter_types! { pub const RelayLocation: Location = Location::parent(); pub AssetHub: Location = Location::new(1, [Parachain(1000)]); // Note: Paseo currently uses Polkadot https://github.com/paseo-network/runtimes/blob/abc4ae9c5ae8f0166aab7ef2b427b3c2c6d5ce5c/relay/paseo/src/xcm_config.rs#L56 pub const RelayNetwork: Option = Some(Polkadot); pub RelayChainOrigin: RuntimeOrigin = cumulus_pallet_xcm::Origin::Relay.into(); + // For the real deployment, it is recommended to set `RelayNetwork` according to the relay chain + // and prepend `UniversalLocation` with `GlobalConsensus(RelayNetwork::get())`. pub UniversalLocation: InteriorLocation = Parachain(ParachainInfo::parachain_id().into()).into(); } @@ -48,7 +50,7 @@ pub type LocationToAccountId = ( /// Means for transacting assets on this chain. #[allow(deprecated)] -pub type LocalAssetTransactor = CurrencyAdapter< +pub type LocalAssetTransactor = FungibleAdapter< // Use this currency: Balances, // Use this currency when it is a fungible asset matching the given location or name: @@ -125,33 +127,38 @@ pub type TrustedReserves = (NativeAsset, NativeAssetFrom); pub struct XcmConfig; impl xcm_executor::Config for XcmConfig { - type RuntimeCall = RuntimeCall; - type XcmSender = XcmRouter; + type Aliasers = Nothing; + type AssetClaims = PolkadotXcm; + type AssetExchanger = (); + type AssetLocker = (); // How to withdraw and deposit an asset. type AssetTransactor = LocalAssetTransactor; - type OriginConverter = XcmOriginToTransactDispatchOrigin; - type IsReserve = TrustedReserves; - type IsTeleporter = (); // Teleporting is disabled. - type UniversalLocation = UniversalLocation; - type Barrier = Barrier; - type Weigher = FixedWeightBounds; - type Trader = - UsingComponents>; - type ResponseHandler = PolkadotXcm; type AssetTrap = PolkadotXcm; - type AssetClaims = PolkadotXcm; - type SubscriptionService = PolkadotXcm; - type PalletInstancesInfo = AllPalletsWithSystem; - type MaxAssetsIntoHolding = MaxAssetsIntoHolding; - type AssetLocker = (); - type AssetExchanger = (); + type Barrier = Barrier; + type CallDispatcher = RuntimeCall; type FeeManager = (); + type HrmpChannelAcceptedHandler = (); + type HrmpChannelClosingHandler = (); + type HrmpNewChannelOpenRequestHandler = (); + type IsReserve = TrustedReserves; + type IsTeleporter = (); + type MaxAssetsIntoHolding = MaxAssetsIntoHolding; type MessageExporter = (); - type UniversalAliases = Nothing; - type CallDispatcher = RuntimeCall; + type OriginConverter = XcmOriginToTransactDispatchOrigin; + type PalletInstancesInfo = AllPalletsWithSystem; + type ResponseHandler = PolkadotXcm; + type RuntimeCall = RuntimeCall; type SafeCallFilter = Everything; - type Aliasers = Nothing; + type SubscriptionService = PolkadotXcm; + type Trader = + UsingComponents>; type TransactionalProcessor = FrameTransactionalProcessor; + type UniversalAliases = Nothing; + // Teleporting is disabled. + type UniversalLocation = UniversalLocation; + type Weigher = FixedWeightBounds; + type XcmRecorder = PolkadotXcm; + type XcmSender = XcmRouter; } /// No local origins on this chain are allowed to dispatch XCM sends/executions. @@ -167,34 +174,32 @@ pub type XcmRouter = WithUniqueTopic<( )>; impl pallet_xcm::Config for Runtime { + type AdminOrigin = EnsureRoot; + // ^ Override for AdvertisedXcmVersion default. + type AdvertisedXcmVersion = pallet_xcm::CurrentXcmVersion; + type Currency = Balances; + type CurrencyMatcher = (); + type ExecuteXcmOrigin = EnsureXcmOrigin; + type MaxLockers = ConstU32<8>; + type MaxRemoteLockConsumers = ConstU32<0>; + type RemoteLockConsumerIdentifier = (); + type RuntimeCall = RuntimeCall; type RuntimeEvent = RuntimeEvent; + type RuntimeOrigin = RuntimeOrigin; type SendXcmOrigin = EnsureXcmOrigin; - type XcmRouter = XcmRouter; - type ExecuteXcmOrigin = EnsureXcmOrigin; - type XcmExecuteFilter = Nothing; - // ^ Disable dispatchable execute on the XCM pallet. - // Needs to be `Everything` for local testing. + type SovereignAccountOf = LocationToAccountId; + type TrustedLockers = (); + type UniversalLocation = UniversalLocation; + type Weigher = FixedWeightBounds; + type WeightInfo = pallet_xcm::TestWeightInfo; + type XcmExecuteFilter = Everything; type XcmExecutor = XcmExecutor; - type XcmTeleportFilter = Nothing; // TODO: add filter to only allow reserve transfers of native to relay/asset hub type XcmReserveTransferFilter = Everything; - type Weigher = FixedWeightBounds; - type UniversalLocation = UniversalLocation; - type RuntimeOrigin = RuntimeOrigin; - type RuntimeCall = RuntimeCall; + type XcmRouter = XcmRouter; + type XcmTeleportFilter = Everything; const VERSION_DISCOVERY_QUEUE_SIZE: u32 = 100; - // ^ Override for AdvertisedXcmVersion default - type AdvertisedXcmVersion = pallet_xcm::CurrentXcmVersion; - type Currency = Balances; - type CurrencyMatcher = (); - type TrustedLockers = (); - type SovereignAccountOf = LocationToAccountId; - type MaxLockers = ConstU32<8>; - type WeightInfo = pallet_xcm::TestWeightInfo; - type AdminOrigin = EnsureRoot; - type MaxRemoteLockConsumers = ConstU32<0>; - type RemoteLockConsumerIdentifier = (); } impl cumulus_pallet_xcm::Config for Runtime { diff --git a/runtime/testnet/src/extensions.rs b/runtime/testnet/src/extensions.rs index fc228b03..084778eb 100644 --- a/runtime/testnet/src/extensions.rs +++ b/runtime/testnet/src/extensions.rs @@ -3,8 +3,11 @@ use frame_support::{ pallet_prelude::*, traits::{Contains, OriginTrait}, }; -use pallet_contracts::chain_extension::{ - BufInBufOutState, ChainExtension, ChargedAmount, Environment, Ext, InitState, RetVal, +use pallet_contracts::{ + chain_extension::{ + BufInBufOutState, ChainExtension, ChargedAmount, Environment, Ext, InitState, RetVal, + }, + WeightInfo, }; use sp_core::crypto::UncheckedFrom; use sp_runtime::{traits::Dispatchable, DispatchError}; @@ -14,8 +17,6 @@ use crate::{AccountId, AllowedApiCalls, RuntimeCall, RuntimeOrigin}; const LOG_TARGET: &str = "pop-api::extension"; -type ContractSchedule = ::Schedule; - #[derive(Default)] pub struct PopApiExtension; @@ -29,10 +30,10 @@ where >, T::AccountId: UncheckedFrom + AsRef<[u8]>, { - fn call(&mut self, env: Environment) -> Result - where - E: Ext, - { + fn call>( + &mut self, + env: Environment, + ) -> Result { log::debug!(target:LOG_TARGET, " extension called "); match v0::FuncId::try_from(env.func_id())? { v0::FuncId::Dispatch => { @@ -123,16 +124,14 @@ where T: pallet_contracts::Config, E: Ext, { - let contract_host_weight = ContractSchedule::::get().host_fn_weights; - // calculate weight for reading bytes of `len` // reference: https://github.com/paritytech/polkadot-sdk/blob/117a9433dac88d5ac00c058c9b39c511d47749d2/substrate/frame/contracts/src/wasm/runtime.rs#L267 - let base_weight: Weight = contract_host_weight.return_per_byte.saturating_mul(len.into()); + let base_weight: Weight = T::WeightInfo::seal_return(len); // debug_message weight is a good approximation of the additional overhead of going // from contract layer to substrate layer. // reference: https://github.com/paritytech/ink-examples/blob/b8d2caa52cf4691e0ddd7c919e4462311deb5ad0/psp22-extension/runtime/psp22-extension-example.rs#L236 - let overhead = contract_host_weight.debug_message; + let overhead: Weight = T::WeightInfo::seal_debug_message(len); let charged_weight = env.charge_weight(base_weight.saturating_add(overhead))?; log::debug!(target: LOG_TARGET, "{} charged weight: {:?}", log_prefix, charged_weight); @@ -172,10 +171,7 @@ where let mut env = env.buf_in_buf_out(); // To be conservative, we charge the weight for reading the input bytes of a fixed-size type. - let base_weight: Weight = ContractSchedule::::get() - .host_fn_weights - .return_per_byte - .saturating_mul(env.in_len().into()); + let base_weight: Weight = T::WeightInfo::seal_return(env.in_len()); let charged_weight = env.charge_weight(base_weight)?; log::debug!(target:LOG_TARGET, "{} charged weight: {:?}", LOG_PREFIX, charged_weight); diff --git a/runtime/testnet/src/lib.rs b/runtime/testnet/src/lib.rs index 700257fa..c39d9928 100644 --- a/runtime/testnet/src/lib.rs +++ b/runtime/testnet/src/lib.rs @@ -10,34 +10,18 @@ mod config; mod extensions; mod weights; -use cumulus_pallet_parachain_system::RelayNumberMonotonicallyIncreases; -use polkadot_runtime_common::xcm_sender::NoPriceForMessageDelivery; -use smallvec::smallvec; -use sp_api::impl_runtime_apis; -use sp_core::{crypto::KeyTypeId, OpaqueMetadata}; -use sp_runtime::{ - create_runtime_str, generic, impl_opaque_keys, - traits::{BlakeTwo256, Block as BlockT, IdentifyAccount, Verify}, - transaction_validity::{TransactionSource, TransactionValidity}, - ApplyExtrinsicResult, -}; - -use sp_std::prelude::*; -#[cfg(feature = "std")] -use sp_version::NativeVersion; -use sp_version::RuntimeVersion; - use config::xcm::{RelayLocation, XcmOriginToTransactDispatchOrigin}; +use cumulus_pallet_parachain_system::RelayNumberMonotonicallyIncreases; use cumulus_primitives_core::{AggregateMessageOrigin, ParaId}; use frame_support::{ - construct_runtime, derive_impl, + derive_impl, dispatch::DispatchClass, - genesis_builder_helper::{build_config, create_default_config}, + genesis_builder_helper::{build_state, get_preset}, parameter_types, traits::{ fungible::HoldConsideration, tokens::nonfungibles_v2::Inspect, ConstBool, ConstU32, ConstU64, ConstU8, Contains, EitherOfDiverse, EqualPrivilegeOnly, EverythingBut, - LinearStoragePrice, TransformOrigin, + LinearStoragePrice, TransformOrigin, VariantCountOf, }, weights::{ ConstantMultiplier, Weight, WeightToFeeCoefficient, WeightToFeeCoefficients, @@ -49,26 +33,35 @@ use frame_system::{ limits::{BlockLength, BlockWeights}, EnsureRoot, }; +use pallet_balances::Call as BalancesCall; use pallet_xcm::{EnsureXcm, IsVoiceOfBody}; use parachains_common::message_queue::{NarrowOriginToSibling, ParaIdToSibling}; +use polkadot_runtime_common::xcm_sender::NoPriceForMessageDelivery; +// Polkadot imports +use polkadot_runtime_common::{BlockHashCount, SlowAdjustingFeeUpdate}; pub use pop_runtime_common::{ deposit, AuraId, Balance, BlockNumber, Hash, Nonce, Signature, AVERAGE_ON_INITIALIZE_RATIO, BLOCK_PROCESSING_VELOCITY, DAYS, EXISTENTIAL_DEPOSIT, HOURS, MAXIMUM_BLOCK_WEIGHT, MICROUNIT, MILLIUNIT, MINUTES, NORMAL_DISPATCH_RATIO, RELAY_CHAIN_SLOT_DURATION_MILLIS, SLOT_DURATION, UNINCLUDED_SEGMENT_CAPACITY, UNIT, }; -pub use sp_runtime::{MultiAddress, Perbill, Permill}; - +use smallvec::smallvec; +use sp_api::impl_runtime_apis; +use sp_core::{crypto::KeyTypeId, OpaqueMetadata}; #[cfg(any(feature = "std", test))] pub use sp_runtime::BuildStorage; - -use pallet_balances::Call as BalancesCall; - -// Polkadot imports -use polkadot_runtime_common::{BlockHashCount, SlowAdjustingFeeUpdate}; - +use sp_runtime::{ + create_runtime_str, generic, impl_opaque_keys, + traits::{BlakeTwo256, Block as BlockT, IdentifyAccount, Verify}, + transaction_validity::{TransactionSource, TransactionValidity}, + ApplyExtrinsicResult, +}; +pub use sp_runtime::{ExtrinsicInclusionMode, MultiAddress, Perbill, Permill}; +use sp_std::prelude::*; +#[cfg(feature = "std")] +use sp_version::NativeVersion; +use sp_version::RuntimeVersion; use weights::{BlockExecutionWeight, ExtrinsicBaseWeight, RocksDbWeight}; - // XCM Imports use xcm::latest::prelude::BodyId; @@ -101,6 +94,8 @@ pub type SignedExtra = ( frame_system::CheckNonce, frame_system::CheckWeight, pallet_transaction_payment::ChargeTransactionPayment, + cumulus_primitives_storage_weight_reclaim::StorageWeightReclaim, + frame_metadata_hash_extension::CheckMetadataHash, ); /// Unchecked extrinsic type as expected by this runtime. @@ -108,7 +103,11 @@ pub type UncheckedExtrinsic = generic::UncheckedExtrinsic; /// Migrations to apply on runtime upgrade. -pub type Migrations = (pallet_collator_selection::migration::v2::MigrationToV2,); +pub type Migrations = ( + pallet_contracts::Migration, + cumulus_pallet_xcmp_queue::migration::v5::MigrateV4ToV5, + pallet_xcm::migration::MigrateToLatestXcmVersion, +); /// Executive: handles dispatch to the various modules. pub type Executive = frame_executive::Executive< @@ -133,6 +132,7 @@ pub type Executive = frame_executive::Executive< pub struct WeightToFee; impl WeightToFeePolynomial for WeightToFee { type Balance = Balance; + fn polynomial() -> WeightToFeeCoefficients { // in Rococo, extrinsic base weight (smallest non-zero weight) is mapped to 1 MILLIUNIT: // we map to 1/10 of that, or 1/10 MILLIUNIT @@ -152,13 +152,13 @@ impl WeightToFeePolynomial for WeightToFee { /// of data like extrinsics, allowing for them to continue syncing the network through upgrades /// to even the core data structures. pub mod opaque { - use super::*; + pub use sp_runtime::OpaqueExtrinsic as UncheckedExtrinsic; use sp_runtime::{ generic, traits::{BlakeTwo256, Hash as HashT}, }; - pub use sp_runtime::OpaqueExtrinsic as UncheckedExtrinsic; + use super::*; /// Opaque block header type. pub type Header = generic::Header; /// Opaque block type. @@ -181,7 +181,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { impl_name: create_runtime_str!("pop"), authoring_version: 1, #[allow(clippy::zero_prefixed_literal)] - spec_version: 00_02_00, + spec_version: 00_04_01, impl_version: 0, apis: RUNTIME_API_VERSIONS, transaction_version: 1, @@ -233,7 +233,7 @@ parameter_types! { }) .avg_block_initialization(AVERAGE_ON_INITIALIZE_RATIO) .build_or_panic(); - pub const SS58Prefix: u16 = 42; + pub const SS58Prefix: u16 = 0; } /// A type to identify filtered calls. @@ -264,48 +264,48 @@ impl Contains for AllowedApiCalls { /// The default types are being injected by [`derive_impl`](`frame_support::derive_impl`) from /// [`ParaChainDefaultConfig`](`struct@frame_system::config_preludes::ParaChainDefaultConfig`), /// but overridden as needed. -#[derive_impl(frame_system::config_preludes::ParaChainDefaultConfig as frame_system::DefaultConfig)] +#[derive_impl(frame_system::config_preludes::ParaChainDefaultConfig)] impl frame_system::Config for Runtime { + /// The data to be stored in an account. + type AccountData = pallet_balances::AccountData; /// The identifier used to distinguish between accounts. type AccountId = AccountId; - /// The index type for storing how many extrinsics an account has signed. - type Nonce = Nonce; - /// The type for hashing blocks and tries. - type Hash = Hash; + /// The basic call filter to use in dispatchable. Supports everything as the default. + type BaseCallFilter = EverythingBut; /// The block type. type Block = Block; /// Maximum number of block number to block hash mappings to keep (oldest pruned first). type BlockHashCount = BlockHashCount; - /// Runtime version. - type Version = Version; - /// The data to be stored in an account. - type AccountData = pallet_balances::AccountData; - /// The weight of database operations that the runtime can invoke. - type DbWeight = RocksDbWeight; - /// Block & extrinsics weights: base values and limits. - type BlockWeights = RuntimeBlockWeights; /// The maximum length of a block (in bytes). type BlockLength = RuntimeBlockLength; - /// This is used as an identifier of the chain. 42 is the generic substrate prefix. - type SS58Prefix = SS58Prefix; - /// The basic call filter to use in dispatchable. Supports everything as the default. - type BaseCallFilter = EverythingBut; + /// Block & extrinsics weights: base values and limits. + type BlockWeights = RuntimeBlockWeights; + /// The weight of database operations that the runtime can invoke. + type DbWeight = RocksDbWeight; + /// The type for hashing blocks and tries. + type Hash = Hash; + type MaxConsumers = frame_support::traits::ConstU32<16>; + /// The index type for storing how many extrinsics an account has signed. + type Nonce = Nonce; /// The action to take on a Runtime Upgrade type OnSetCode = cumulus_pallet_parachain_system::ParachainSetCode; - type MaxConsumers = frame_support::traits::ConstU32<16>; + /// This is used as an identifier of the chain. 42 is the generic substrate prefix. + type SS58Prefix = SS58Prefix; + /// Runtime version. + type Version = Version; } impl pallet_timestamp::Config for Runtime { + type MinimumPeriod = ConstU64<0>; /// A timestamp: milliseconds since the unix epoch. type Moment = u64; type OnTimestampSet = Aura; - type MinimumPeriod = ConstU64<0>; type WeightInfo = (); } impl pallet_authorship::Config for Runtime { - type FindAuthor = pallet_session::FindAccountFromAuthorIndex; type EventHandler = (CollatorSelection,); + type FindAuthor = pallet_session::FindAccountFromAuthorIndex; } parameter_types! { @@ -313,21 +313,21 @@ parameter_types! { } impl pallet_balances::Config for Runtime { - type MaxLocks = ConstU32<50>; + type AccountStore = System; /// The type for recording an account's balance. type Balance = Balance; - /// The ubiquitous event type. - type RuntimeEvent = RuntimeEvent; type DustRemoval = (); type ExistentialDeposit = ExistentialDeposit; - type AccountStore = System; - type WeightInfo = pallet_balances::weights::SubstrateWeight; + type FreezeIdentifier = RuntimeFreezeReason; + type MaxFreezes = VariantCountOf; + type MaxLocks = ConstU32<50>; type MaxReserves = ConstU32<50>; type ReserveIdentifier = [u8; 8]; - type RuntimeHoldReason = RuntimeHoldReason; + /// The ubiquitous event type. + type RuntimeEvent = RuntimeEvent; type RuntimeFreezeReason = RuntimeFreezeReason; - type FreezeIdentifier = (); - type MaxFreezes = ConstU32<0>; + type RuntimeHoldReason = RuntimeHoldReason; + type WeightInfo = pallet_balances::weights::SubstrateWeight; } parameter_types! { @@ -336,17 +336,17 @@ parameter_types! { } impl pallet_transaction_payment::Config for Runtime { - type RuntimeEvent = RuntimeEvent; - type OnChargeTransaction = pallet_transaction_payment::CurrencyAdapter; - type WeightToFee = WeightToFee; - type LengthToFee = ConstantMultiplier; type FeeMultiplierUpdate = SlowAdjustingFeeUpdate; + type LengthToFee = ConstantMultiplier; + type OnChargeTransaction = pallet_transaction_payment::FungibleAdapter; type OperationalFeeMultiplier = ConstU8<5>; + type RuntimeEvent = RuntimeEvent; + type WeightToFee = WeightToFee; } impl pallet_sudo::Config for Runtime { - type RuntimeEvent = RuntimeEvent; type RuntimeCall = RuntimeCall; + type RuntimeEvent = RuntimeEvent; type WeightInfo = (); } @@ -364,17 +364,17 @@ type ConsensusHook = cumulus_pallet_aura_ext::FixedVelocityConsensusHook< >; impl cumulus_pallet_parachain_system::Config for Runtime { - type WeightInfo = (); - type RuntimeEvent = RuntimeEvent; + type CheckAssociatedRelayNumber = RelayNumberMonotonicallyIncreases; + type ConsensusHook = ConsensusHook; + type DmpQueue = frame_support::traits::EnqueueWithOrigin; type OnSystemEvent = (); - type SelfParaId = parachain_info::Pallet; type OutboundXcmpMessageSource = XcmpQueue; - type DmpQueue = frame_support::traits::EnqueueWithOrigin; type ReservedDmpWeight = ReservedDmpWeight; - type XcmpMessageHandler = XcmpQueue; type ReservedXcmpWeight = ReservedXcmpWeight; - type CheckAssociatedRelayNumber = RelayNumberMonotonicallyIncreases; - type ConsensusHook = ConsensusHook; + type RuntimeEvent = RuntimeEvent; + type SelfParaId = parachain_info::Pallet; + type WeightInfo = (); + type XcmpMessageHandler = XcmpQueue; } impl parachain_info::Config for Runtime {} @@ -384,8 +384,9 @@ parameter_types! { } impl pallet_message_queue::Config for Runtime { - type RuntimeEvent = RuntimeEvent; - type WeightInfo = (); + type HeapSize = sp_core::ConstU32<{ 103 * 1024 }>; + type IdleMaxServiceWeight = (); + type MaxStale = sp_core::ConstU32<8>; #[cfg(feature = "runtime-benchmarks")] type MessageProcessor = pallet_message_queue::mock_helpers::NoopMessageProcessor< cumulus_primitives_core::AggregateMessageOrigin, @@ -396,28 +397,37 @@ impl pallet_message_queue::Config for Runtime { xcm_executor::XcmExecutor, RuntimeCall, >; - type Size = u32; // The XCMP queue pallet is only ever able to handle the `Sibling(ParaId)` origin: type QueueChangeHandler = NarrowOriginToSibling; type QueuePausedQuery = NarrowOriginToSibling; - type HeapSize = sp_core::ConstU32<{ 64 * 1024 }>; - type MaxStale = sp_core::ConstU32<8>; + type RuntimeEvent = RuntimeEvent; type ServiceWeight = MessageQueueServiceWeight; + type Size = u32; + type WeightInfo = (); } impl cumulus_pallet_aura_ext::Config for Runtime {} impl cumulus_pallet_xcmp_queue::Config for Runtime { - type RuntimeEvent = RuntimeEvent; type ChannelInfo = ParachainSystem; - type VersionWrapper = (); - // Enqueue XCMP messages from siblings for later processing. - type XcmpQueue = TransformOrigin; - type MaxInboundSuspended = sp_core::ConstU32<1_000>; type ControllerOrigin = EnsureRoot; type ControllerOriginConverter = XcmOriginToTransactDispatchOrigin; - type WeightInfo = (); + // Limit the number of messages and signals a HRML channel can have at most + type MaxActiveOutboundChannels = ConstU32<128>; + type MaxInboundSuspended = sp_core::ConstU32<1_000>; + // Limit the number of HRML channels + type MaxPageSize = ConstU32<{ 103 * 1024 }>; type PriceForSiblingDelivery = NoPriceForMessageDelivery; + type RuntimeEvent = RuntimeEvent; + type VersionWrapper = (); + type WeightInfo = (); + // Enqueue XCMP messages from siblings for later processing. + type XcmpQueue = TransformOrigin; +} + +impl cumulus_pallet_xcmp_queue::migration::v5::V5Config for Runtime { + // This must be the same as the `ChannelInfo` from the `Config`: + type ChannelList = ParachainSystem; } parameter_types! { @@ -426,24 +436,24 @@ parameter_types! { } impl pallet_session::Config for Runtime { + type Keys = SessionKeys; + type NextSessionRotation = pallet_session::PeriodicSessions; type RuntimeEvent = RuntimeEvent; + // Essentially just Aura, but let's be pedantic. + type SessionHandler = ::KeyTypeIdProviders; + type SessionManager = CollatorSelection; + type ShouldEndSession = pallet_session::PeriodicSessions; type ValidatorId = ::AccountId; // we don't have stash and controller, thus we don't need the convert as well. type ValidatorIdOf = pallet_collator_selection::IdentityCollator; - type ShouldEndSession = pallet_session::PeriodicSessions; - type NextSessionRotation = pallet_session::PeriodicSessions; - type SessionManager = CollatorSelection; - // Essentially just Aura, but let's be pedantic. - type SessionHandler = ::KeyTypeIdProviders; - type Keys = SessionKeys; type WeightInfo = (); } impl pallet_aura::Config for Runtime { + type AllowMultipleBlocksPerSlot = ConstBool; type AuthorityId = AuraId; type DisabledValidators = (); type MaxAuthorities = ConstU32<100_000>; - type AllowMultipleBlocksPerSlot = ConstBool; type SlotDuration = ConstU64; } @@ -461,15 +471,15 @@ pub type CollatorSelectionUpdateOrigin = EitherOfDiverse< >; impl pallet_collator_selection::Config for Runtime { - type RuntimeEvent = RuntimeEvent; type Currency = Balances; - type UpdateOrigin = CollatorSelectionUpdateOrigin; - type PotId = PotId; - type MaxCandidates = ConstU32<100>; - type MinEligibleCollators = ConstU32<4>; - type MaxInvulnerables = ConstU32<20>; // should be a multiple of session or things will get inconsistent type KickThreshold = Period; + type MaxCandidates = ConstU32<100>; + type MaxInvulnerables = ConstU32<20>; + type MinEligibleCollators = ConstU32<4>; + type PotId = PotId; + type RuntimeEvent = RuntimeEvent; + type UpdateOrigin = CollatorSelectionUpdateOrigin; type ValidatorId = ::AccountId; type ValidatorIdOf = pallet_collator_selection::IdentityCollator; type ValidatorRegistration = Session; @@ -482,19 +492,19 @@ parameter_types! { } impl pallet_scheduler::Config for Runtime { - type RuntimeEvent = RuntimeEvent; - type RuntimeOrigin = RuntimeOrigin; - type PalletsOrigin = OriginCaller; - type RuntimeCall = RuntimeCall; - type MaximumWeight = MaximumSchedulerWeight; - type ScheduleOrigin = EnsureRoot; #[cfg(feature = "runtime-benchmarks")] type MaxScheduledPerBlock = ConstU32<512>; #[cfg(not(feature = "runtime-benchmarks"))] type MaxScheduledPerBlock = ConstU32<50>; - type WeightInfo = pallet_scheduler::weights::SubstrateWeight; + type MaximumWeight = MaximumSchedulerWeight; type OriginPrivilegeCmp = EqualPrivilegeOnly; + type PalletsOrigin = OriginCaller; type Preimages = Preimage; + type RuntimeCall = RuntimeCall; + type RuntimeEvent = RuntimeEvent; + type RuntimeOrigin = RuntimeOrigin; + type ScheduleOrigin = EnsureRoot; + type WeightInfo = pallet_scheduler::weights::SubstrateWeight; } parameter_types! { @@ -504,16 +514,16 @@ parameter_types! { } impl pallet_preimage::Config for Runtime { - type WeightInfo = pallet_preimage::weights::SubstrateWeight; - type RuntimeEvent = RuntimeEvent; - type Currency = Balances; - type ManagerOrigin = EnsureRoot; type Consideration = HoldConsideration< AccountId, Balances, PreimageHoldReason, LinearStoragePrice, >; + type Currency = Balances; + type ManagerOrigin = EnsureRoot; + type RuntimeEvent = RuntimeEvent; + type WeightInfo = pallet_preimage::weights::SubstrateWeight; } parameter_types! { @@ -525,73 +535,111 @@ parameter_types! { } impl pallet_multisig::Config for Runtime { - type RuntimeEvent = RuntimeEvent; - type RuntimeCall = RuntimeCall; type Currency = Balances; type DepositBase = DepositBase; type DepositFactor = DepositFactor; type MaxSignatories = MaxSignatories; + type RuntimeCall = RuntimeCall; + type RuntimeEvent = RuntimeEvent; type WeightInfo = pallet_multisig::weights::SubstrateWeight; } impl pallet_utility::Config for Runtime { - type RuntimeEvent = RuntimeEvent; - type RuntimeCall = RuntimeCall; type PalletsOrigin = OriginCaller; + type RuntimeCall = RuntimeCall; + type RuntimeEvent = RuntimeEvent; type WeightInfo = pallet_utility::weights::SubstrateWeight; } -// Create the runtime by composing the FRAME pallets that were previously configured. -construct_runtime!( - pub enum Runtime { - // System support stuff. - System: frame_system = 0, - ParachainSystem: cumulus_pallet_parachain_system = 1, - Timestamp: pallet_timestamp = 2, - ParachainInfo: parachain_info = 3, - - // Monetary stuff. - Balances: pallet_balances = 10, - TransactionPayment: pallet_transaction_payment = 11, - - // Governance - Sudo: pallet_sudo = 15, - - // Collator support. The order of these 4 are important and shall not change. - Authorship: pallet_authorship = 20, - CollatorSelection: pallet_collator_selection = 21, - Session: pallet_session = 22, - Aura: pallet_aura = 23, - AuraExt: cumulus_pallet_aura_ext = 24, - - // Scheduler - Scheduler: pallet_scheduler = 28, - - // Preimage - Preimage: pallet_preimage = 29, - - // XCM helpers. - XcmpQueue: cumulus_pallet_xcmp_queue = 30, - PolkadotXcm: pallet_xcm = 31, - CumulusXcm: cumulus_pallet_xcm = 32, - MessageQueue: pallet_message_queue = 33, - - // Contracts - Contracts: pallet_contracts = 40, - - // Proxy - Proxy: pallet_proxy = 41, - // Multisig - Multisig: pallet_multisig = 42, - // Utility - Utility: pallet_utility = 43, - - // Assets - Nfts: pallet_nfts = 50, - NftFractionalization: pallet_nft_fractionalization = 51, - Assets: pallet_assets:: = 52, - } -); +#[frame_support::runtime] +mod runtime { + // Create the runtime by composing the FRAME pallets that were previously configured. + #[runtime::runtime] + #[runtime::derive( + RuntimeCall, + RuntimeEvent, + RuntimeError, + RuntimeOrigin, + RuntimeFreezeReason, + RuntimeHoldReason, + RuntimeSlashReason, + RuntimeLockId, + RuntimeTask + )] + pub struct Runtime; + + // System support stuff. + #[runtime::pallet_index(0)] + pub type System = frame_system::Pallet; + #[runtime::pallet_index(1)] + pub type ParachainSystem = cumulus_pallet_parachain_system::Pallet; + #[runtime::pallet_index(2)] + pub type Timestamp = pallet_timestamp::Pallet; + #[runtime::pallet_index(3)] + pub type ParachainInfo = parachain_info::Pallet; + + // Monetary stuff. + #[runtime::pallet_index(10)] + pub type Balances = pallet_balances::Pallet; + #[runtime::pallet_index(11)] + pub type TransactionPayment = pallet_transaction_payment::Pallet; + + // Governance + #[runtime::pallet_index(15)] + pub type Sudo = pallet_sudo; + + // Collator support. The order of these 4 are important and shall not change. + #[runtime::pallet_index(20)] + pub type Authorship = pallet_authorship::Pallet; + #[runtime::pallet_index(21)] + pub type CollatorSelection = pallet_collator_selection::Pallet; + #[runtime::pallet_index(22)] + pub type Session = pallet_session::Pallet; + #[runtime::pallet_index(23)] + pub type Aura = pallet_aura::Pallet; + #[runtime::pallet_index(24)] + pub type AuraExt = cumulus_pallet_aura_ext; + + // Scheduler + #[runtime::pallet_index(28)] + pub type Scheduler = pallet_scheduler; + + // Preimage + #[runtime::pallet_index(29)] + pub type Preimage = pallet_preimage; + + // XCM helpers. + #[runtime::pallet_index(30)] + pub type XcmpQueue = cumulus_pallet_xcmp_queue::Pallet; + #[runtime::pallet_index(31)] + pub type PolkadotXcm = pallet_xcm::Pallet; + #[runtime::pallet_index(32)] + pub type CumulusXcm = cumulus_pallet_xcm::Pallet; + #[runtime::pallet_index(33)] + pub type MessageQueue = pallet_message_queue::Pallet; + + // Contracts + #[runtime::pallet_index(40)] + pub type Contracts = pallet_contracts::Pallet; + + // Proxy + #[runtime::pallet_index(41)] + pub type Proxy = pallet_proxy::Pallet; + // Multisig + #[runtime::pallet_index(42)] + pub type Multisig = pallet_multisig::Pallet; + // Utility + #[runtime::pallet_index(43)] + pub type Utility = pallet_utility::Pallet; + + // Assets + #[runtime::pallet_index(50)] + pub type Nfts = pallet_nfts::Pallet; + #[runtime::pallet_index(51)] + pub type NftFractionalization = pallet_nft_fractionalization::Pallet; + #[runtime::pallet_index(52)] + pub type Assets = pallet_assets::Pallet; +} #[cfg(feature = "runtime-benchmarks")] mod benches { @@ -616,7 +664,7 @@ impl_runtime_apis! { } fn authorities() -> Vec { - Aura::authorities().into_inner() + pallet_aura::Authorities::::get().into_inner() } } @@ -629,7 +677,7 @@ impl_runtime_apis! { Executive::execute_block(block) } - fn initialize_block(header: &::Header) { + fn initialize_block(header: &::Header) -> ExtrinsicInclusionMode{ Executive::initialize_block(header) } } @@ -943,12 +991,16 @@ impl_runtime_apis! { } impl sp_genesis_builder::GenesisBuilder for Runtime { - fn create_default_config() -> Vec { - create_default_config::() + fn build_state(config: Vec) -> sp_genesis_builder::Result { + build_state::(config) + } + + fn get_preset(id: &Option) -> Option> { + get_preset::(id, |_| None) } - fn build_config(config: Vec) -> sp_genesis_builder::Result { - build_config::(config) + fn preset_names() -> Vec { + Default::default() } } } diff --git a/runtime/testnet/src/weights/paritydb_weights.rs b/runtime/testnet/src/weights/paritydb_weights.rs index 25679703..27f7f1b0 100644 --- a/runtime/testnet/src/weights/paritydb_weights.rs +++ b/runtime/testnet/src/weights/paritydb_weights.rs @@ -32,9 +32,10 @@ pub mod constants { #[cfg(test)] mod test_db_weights { - use super::constants::ParityDbWeight as W; use frame_support::weights::constants; + use super::constants::ParityDbWeight as W; + /// Checks that all weights exist and have sane values. // NOTE: If this test fails but you are sure that the generated values are fine, // you can delete it. diff --git a/runtime/testnet/src/weights/rocksdb_weights.rs b/runtime/testnet/src/weights/rocksdb_weights.rs index 3dd817aa..bacad98c 100644 --- a/runtime/testnet/src/weights/rocksdb_weights.rs +++ b/runtime/testnet/src/weights/rocksdb_weights.rs @@ -32,9 +32,10 @@ pub mod constants { #[cfg(test)] mod test_db_weights { - use super::constants::RocksDbWeight as W; use frame_support::weights::constants; + use super::constants::RocksDbWeight as W; + /// Checks that all weights exist and have sane values. // NOTE: If this test fails but you are sure that the generated values are fine, // you can delete it. diff --git a/rust-toolchain.toml b/rust-toolchain.toml index 12d44b03..a7445512 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,4 +1,4 @@ [toolchain] channel = "stable" -components = ["rust-src", "rustfmt", "clippy"] -targets = ["wasm32-unknown-unknown"] +components = [ "clippy", "rust-src", "rustfmt" ] +targets = [ "wasm32-unknown-unknown" ] diff --git a/tests/contracts/filtered-call/Cargo.toml b/tests/contracts/filtered-call/Cargo.toml index 53148822..091beabe 100755 --- a/tests/contracts/filtered-call/Cargo.toml +++ b/tests/contracts/filtered-call/Cargo.toml @@ -1,21 +1,21 @@ [package] -name = "pop_api_filtered_call" edition = "2021" +name = "pop_api_filtered_call" [dependencies] ink = { version = "5.0.0", default-features = false } -scale = { package = "parity-scale-codec", version = "3", default-features = false, features = ["derive"] } -scale-info = { version = "2.6", default-features = false, features = ["derive"], optional = true } +scale = { package = "parity-scale-codec", version = "3", default-features = false, features = [ "derive" ] } +scale-info = { version = "2.6", default-features = false, features = [ "derive" ], optional = true } [lib] path = "lib.rs" [features] -default = ["std"] +default = [ "std" ] +e2e-tests = [ ] +ink-as-dependency = [ ] std = [ - "ink/std", - "scale/std", - "scale-info/std", + "ink/std", + "scale-info/std", + "scale/std", ] -ink-as-dependency = [] -e2e-tests = [] From d92a4c5f2aa6c3e0350948b900864178858acac3 Mon Sep 17 00:00:00 2001 From: Frank Bell Date: Sat, 7 Sep 2024 15:08:32 +0100 Subject: [PATCH 051/112] chore(runtime): use workspace dependencies --- Cargo.toml | 2 ++ runtime/devnet/Cargo.toml | 6 +++--- runtime/testnet/Cargo.toml | 6 +++--- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 3c2f5a1c..09fe0b0c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -34,8 +34,10 @@ codec = { package = "parity-scale-codec", version = "3.6.12", default-features = "derive", ] } contract-build = "4.1.1" +enumflags2 = "0.7.9" env_logger = "0.11.5" futures = "0.3.28" +hex = "0.4.3" hex-literal = "0.4.1" impl-trait-for-tuples = "0.2.2" jsonrpsee = { version = "0.23.2", features = [ "server" ] } diff --git a/runtime/devnet/Cargo.toml b/runtime/devnet/Cargo.toml index b0eec2c2..a94e2831 100644 --- a/runtime/devnet/Cargo.toml +++ b/runtime/devnet/Cargo.toml @@ -92,9 +92,9 @@ parachain-info.workspace = true parachains-common.workspace = true [dev-dependencies] -enumflags2 = "0.7.9" -env_logger = "0.11.2" -hex = "0.4.3" +enumflags2.workspace = true +env_logger.workspace = true +hex.workspace = true [features] default = [ "std" ] diff --git a/runtime/testnet/Cargo.toml b/runtime/testnet/Cargo.toml index 54fe7632..6dc58e18 100644 --- a/runtime/testnet/Cargo.toml +++ b/runtime/testnet/Cargo.toml @@ -90,9 +90,9 @@ parachain-info.workspace = true parachains-common.workspace = true [dev-dependencies] -enumflags2 = "0.7.9" -env_logger = "0.11.2" -hex = "0.4.3" +enumflags2.workspace = true +env_logger.workspace = true +hex.workspace = true [features] default = [ "std" ] From d7cba0ad6b786b6556edd68d9a72837c142979ef Mon Sep 17 00:00:00 2001 From: Frank Bell Date: Sat, 7 Sep 2024 18:56:31 +0100 Subject: [PATCH 052/112] chore: resolve merge issues --- Cargo.lock | 117 ------------------------------------------ primitives/Cargo.toml | 1 - 2 files changed, 118 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 379b1f32..960e68f5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1281,25 +1281,6 @@ dependencies = [ "sp-std", ] -[[package]] -name = "bp-polkadot-bulletin" -version = "0.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfb5b3cd885b40b52bf96e52ffbec92d0c435f7303fc11374ccfcfa5bebfbc4f" -dependencies = [ - "bp-header-chain", - "bp-messages", - "bp-polkadot-core", - "bp-runtime", - "frame-support", - "frame-system", - "parity-scale-codec", - "scale-info", - "sp-api", - "sp-runtime", - "sp-std", -] - [[package]] name = "bp-polkadot-core" version = "0.15.0" @@ -7086,15 +7067,6 @@ dependencies = [ "memchr", ] -[[package]] -name = "object" -version = "0.36.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "576dfe1fc8f9df304abb159d767a29d0476f7750fbf8aa7ad07816004a207434" -dependencies = [ - "memchr", -] - [[package]] name = "oid-registry" version = "0.6.1" @@ -8228,25 +8200,6 @@ dependencies = [ "sp-std", ] -[[package]] -name = "pallet-parameters" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58d9a81a93202105a660e6aa3d3f81638bdd109ca0497f3e528529cd52d034db" -dependencies = [ - "docify", - "frame-benchmarking", - "frame-support", - "frame-system", - "parity-scale-codec", - "paste", - "scale-info", - "serde", - "sp-core", - "sp-runtime", - "sp-std", -] - [[package]] name = "pallet-preimage" version = "36.0.0" @@ -10474,37 +10427,6 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "26e85d3456948e650dff0cfc85603915847faf893ed1e66b020bb82ef4557120" -[[package]] -name = "polkavm-derive-impl-macro" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ba81f7b5faac81e528eb6158a6f3c9e0bb1008e0ffa19653bc8dea925ecb429" -dependencies = [ - "polkavm-derive-impl", - "syn 2.0.66", -] - -[[package]] -name = "polkavm-linker" -version = "0.9.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c7be503e60cf56c0eb785f90aaba4b583b36bff00e93997d93fef97f9553c39" -dependencies = [ - "gimli 0.28.1", - "hashbrown 0.14.5", - "log", - "object 0.32.2", - "polkavm-common", - "regalloc2 0.9.3", - "rustc-demangle", -] - -[[package]] -name = "polkavm-linux-raw" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26e85d3456948e650dff0cfc85603915847faf893ed1e66b020bb82ef4557120" - [[package]] name = "polling" version = "2.8.0" @@ -11170,27 +11092,6 @@ dependencies = [ "tempfile", ] -[[package]] -name = "prost-build" -version = "0.12.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22505a5c94da8e3b7c2996394d1c933236c4d743e81a410bcca4e6989fc066a4" -dependencies = [ - "bytes", - "heck 0.5.0", - "itertools 0.11.0", - "log", - "multimap 0.10.0", - "once_cell", - "petgraph", - "prettyplease 0.2.20", - "prost 0.12.6", - "prost-types 0.12.6", - "regex", - "syn 2.0.66", - "tempfile", -] - [[package]] name = "prost-derive" version = "0.11.9" @@ -16310,24 +16211,6 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" -[[package]] -name = "utf-8" -version = "0.7.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" - -[[package]] -name = "utf16_iter" -version = "1.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8232dd3cdaed5356e0f716d285e4b40b932ac434100fe9b7e0e8e935b9e6246" - -[[package]] -name = "utf8_iter" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" - [[package]] name = "utf8parse" version = "0.2.2" diff --git a/primitives/Cargo.toml b/primitives/Cargo.toml index 24566240..0cb46198 100644 --- a/primitives/Cargo.toml +++ b/primitives/Cargo.toml @@ -1,7 +1,6 @@ [package] description = "Primitives crate for Pop" edition = "2021" -name = "pop-primitives" license = "GPL-3.0-only" name = "pop-primitives" version = "0.0.0" From a2726574e4c49db3e077736b20e105950c343d5b Mon Sep 17 00:00:00 2001 From: Frank Bell Date: Sat, 7 Sep 2024 21:36:27 +0100 Subject: [PATCH 053/112] ci: clear more space Required due to failure or coverage CI job. --- .github/actions/init/action.yml | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/.github/actions/init/action.yml b/.github/actions/init/action.yml index 69bb346b..f82d4fcc 100644 --- a/.github/actions/init/action.yml +++ b/.github/actions/init/action.yml @@ -14,9 +14,14 @@ runs: - name: Free up space on runner shell: bash run: | - sudo rm -rf /usr/share/dotnet sudo rm -rf /opt/ghc - sudo rm -rf "/usr/local/share/boost" + sudo rm -rf /opt/hostedtoolcache/CodeQL + sudo rm -rf /usr/local/.ghcup + sudo rm -rf /usr/local/lib/android + sudo rm -rf /usr/local/share/boost + sudo rm -rf /usr/local/share/powershell + sudo rm -rf /usr/share/dotnet + sudo rm -rf /usr/share/swift sudo rm -rf "$AGENT_TOOLSDIRECTORY" - name: Rust Cache From c0ea3ed1ad6f3d07cc8e156cfc310f43ae2e946d Mon Sep 17 00:00:00 2001 From: Frank Bell Date: Sat, 7 Sep 2024 21:38:21 +0100 Subject: [PATCH 054/112] ci: disable debug info for coverage Required due to failure or coverage CI job. --- .github/workflows/ci.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 953aa723..ee041702 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -110,6 +110,8 @@ jobs: coverage: needs: lint runs-on: ubuntu-latest + env: + RUSTFLAGS: "-C debuginfo=0" steps: - uses: actions/checkout@v4 From 206757bb660679af83c8a4a3bf060eecbb1b855f Mon Sep 17 00:00:00 2001 From: Daan van der Plas <93204684+Daanvdplas@users.noreply.github.com> Date: Mon, 9 Sep 2024 17:34:45 +0200 Subject: [PATCH 055/112] style: token terminology (#215) Co-authored-by: Tin Chung <56880684+chungquantin@users.noreply.github.com> Co-authored-by: Frank Bell <60948618+evilrobot-01@users.noreply.github.com> --- pallets/api/src/fungibles/benchmarking.rs | 18 +- pallets/api/src/fungibles/mod.rs | 215 ++++++------- pallets/api/src/fungibles/tests.rs | 234 +++++++------- pallets/api/src/mock.rs | 5 +- pop-api/Cargo.toml | 3 +- .../create_token_in_constructor/lib.rs | 23 +- .../contracts/fungibles/lib.rs | 85 +++-- .../integration-tests/src/fungibles/mod.rs | 115 +++---- .../integration-tests/src/fungibles/utils.rs | 4 +- pop-api/src/lib.rs | 3 +- pop-api/src/v0/assets/mod.rs | 3 - pop-api/src/v0/{assets => }/fungibles.rs | 290 +++++++++--------- pop-api/src/v0/mod.rs | 6 +- primitives/src/lib.rs | 4 +- runtime/devnet/src/config/api/mod.rs | 22 +- 15 files changed, 510 insertions(+), 520 deletions(-) delete mode 100644 pop-api/src/v0/assets/mod.rs rename pop-api/src/v0/{assets => }/fungibles.rs (66%) diff --git a/pallets/api/src/fungibles/benchmarking.rs b/pallets/api/src/fungibles/benchmarking.rs index f346df1a..e143ae47 100644 --- a/pallets/api/src/fungibles/benchmarking.rs +++ b/pallets/api/src/fungibles/benchmarking.rs @@ -1,4 +1,4 @@ -//! Benchmarking setup for pallet-api::fungibles +//! Benchmarking setup for pallet_api::fungibles use frame_benchmarking::{account, v2::*}; use frame_support::{ @@ -14,7 +14,7 @@ use frame_support::{ use frame_system::RawOrigin; use sp_runtime::traits::Zero; -use super::{AccountIdOf, AssetIdOf, AssetsInstanceOf, AssetsOf, BalanceOf, Call, Config, Pallet}; +use super::{AccountIdOf, AssetsInstanceOf, AssetsOf, BalanceOf, Call, Config, Pallet, TokenIdOf}; const SEED: u32 = 1; @@ -37,7 +37,7 @@ mod benchmarks { // - 'c': whether `cancel_approval` is required. #[benchmark] fn approve(a: Linear<0, 1>, c: Linear<0, 1>) -> Result<(), BenchmarkError> { - let asset_id = AssetIdOf::::zero(); + let token_id = TokenIdOf::::zero(); let min_balance = >::from(1u32); let owner: AccountIdOf = account("Alice", 0, SEED); let spender: AccountIdOf = account("Bob", 0, SEED); @@ -45,13 +45,13 @@ mod benchmarks { T::Currency::make_free_balance_be(&owner, u32::MAX.into()); // Set the `current_allowance`. assert_ok!( as Create>>::create( - asset_id.clone(), + token_id.clone(), owner.clone(), true, min_balance )); assert_ok!( as Mutate>>::approve( - asset_id.clone(), + token_id.clone(), &owner, &spender, current_allowance, @@ -69,13 +69,13 @@ mod benchmarks { }; #[extrinsic_call] - _(RawOrigin::Signed(owner.clone()), asset_id.clone(), spender.clone(), approval_value); + _(RawOrigin::Signed(owner.clone()), token_id.clone(), spender.clone(), approval_value); - assert_eq!(AssetsOf::::allowance(asset_id.clone(), &owner, &spender), approval_value); + assert_eq!(AssetsOf::::allowance(token_id.clone(), &owner, &spender), approval_value); if c == 1 { assert_has_event::( pallet_assets::Event::ApprovalCancelled { - asset_id: asset_id.clone(), + asset_id: token_id.clone(), owner: owner.clone(), delegate: spender.clone(), } @@ -92,7 +92,7 @@ mod benchmarks { }; assert_has_event::( pallet_assets::Event::ApprovedTransfer { - asset_id, + asset_id: token_id, source: owner, delegate: spender, amount, diff --git a/pallets/api/src/fungibles/mod.rs b/pallets/api/src/fungibles/mod.rs index 76f3b28a..311b717e 100644 --- a/pallets/api/src/fungibles/mod.rs +++ b/pallets/api/src/fungibles/mod.rs @@ -1,4 +1,4 @@ -//! The fungibles pallet offers a streamlined interface for interacting with fungible assets. The +//! The fungibles pallet offers a streamlined interface for interacting with fungible tokens. The //! goal is to provide a simplified, consistent API that adheres to standards in the smart contract //! space. @@ -14,10 +14,10 @@ mod tests; pub mod weights; type AccountIdOf = ::AccountId; -type AssetIdOf = > as Inspect< +type TokenIdOf = > as Inspect< ::AccountId, >>::AssetId; -type AssetIdParameterOf = >>::AssetIdParameter; +type TokenIdParameterOf = >>::AssetIdParameter; type AssetsOf = pallet_assets::Pallet>; type AssetsInstanceOf = ::AssetsInstance; type AssetsWeightInfoOf = >>::WeightInfo; @@ -48,58 +48,58 @@ pub mod pallet { #[repr(u8)] #[allow(clippy::unnecessary_cast)] pub enum Read { - /// Total token supply for a specified asset. + /// Total token supply for a specified token. #[codec(index = 0)] - TotalSupply(AssetIdOf), - /// Account balance for a specified `asset` and `owner`. + TotalSupply(TokenIdOf), + /// Account balance for a specified `token` and `owner`. #[codec(index = 1)] BalanceOf { - /// The asset. - asset: AssetIdOf, - /// The owner of the asset. + /// The token. + token: TokenIdOf, + /// The owner of the token. owner: AccountIdOf, }, - /// Allowance for a `spender` approved by an `owner`, for a specified `asset`. + /// Allowance for a `spender` approved by an `owner`, for a specified `token`. #[codec(index = 2)] Allowance { - /// The asset. - asset: AssetIdOf, - /// The owner of the asset. + /// The token. + token: TokenIdOf, + /// The owner of the token. owner: AccountIdOf, /// The spender with an allowance. spender: AccountIdOf, }, - /// Name of the specified asset. + /// Name of the specified token. #[codec(index = 8)] - TokenName(AssetIdOf), - /// Symbol for the specified asset. + TokenName(TokenIdOf), + /// Symbol for the specified token. #[codec(index = 9)] - TokenSymbol(AssetIdOf), - /// Decimals for the specified asset. + TokenSymbol(TokenIdOf), + /// Decimals for the specified token. #[codec(index = 10)] - TokenDecimals(AssetIdOf), - /// Check if a specified asset exists. + TokenDecimals(TokenIdOf), + /// Check if a specified token exists. #[codec(index = 18)] - AssetExists(AssetIdOf), + TokenExists(TokenIdOf), } /// Results of state reads for the fungibles API. #[derive(Debug)] pub enum ReadResult { - /// Total token supply for a specified asset. + /// Total token supply for a specified token. TotalSupply(BalanceOf), - /// Account balance for a specified `asset` and `owner`. + /// Account balance for a specified token and owner. BalanceOf(BalanceOf), - /// Allowance for a `spender` approved by an `owner`, for a specified `asset`. + /// Allowance for a spender approved by an owner, for a specified token. Allowance(BalanceOf), - /// Name of the specified asset. + /// Name of the specified token. TokenName(Vec), - /// Symbol for the specified asset. + /// Symbol for the specified token. TokenSymbol(Vec), - /// Decimals for the specified asset. + /// Decimals for the specified token. TokenDecimals(u8), - /// Whether the specified asset exists. - AssetExists(bool), + /// Whether the specified token exists. + TokenExists(bool), } impl ReadResult { @@ -113,7 +113,7 @@ pub mod pallet { TokenName(result) => result.encode(), TokenSymbol(result) => result.encode(), TokenDecimals(result) => result.encode(), - AssetExists(result) => result.encode(), + TokenExists(result) => result.encode(), } } } @@ -138,8 +138,8 @@ pub mod pallet { pub enum Event { /// Event emitted when allowance by `owner` to `spender` changes. Approval { - /// The asset. - asset: AssetIdOf, + /// The token. + token: TokenIdOf, /// The owner providing the allowance. owner: AccountIdOf, /// The beneficiary of the allowance. @@ -147,10 +147,10 @@ pub mod pallet { /// The new allowance amount. value: BalanceOf, }, - /// Event emitted when an asset transfer occurs. + /// Event emitted when a token transfer occurs. Transfer { - /// The asset. - asset: AssetIdOf, + /// The token. + token: TokenIdOf, /// The source of the transfer. `None` when minting. from: Option>, /// The recipient of the transfer. `None` when burning. @@ -158,13 +158,13 @@ pub mod pallet { /// The amount transferred (or minted/burned). value: BalanceOf, }, - /// Event emitted when an asset is created. + /// Event emitted when an token is created. Create { - /// The asset identifier. - id: AssetIdOf, - /// The creator of the asset. + /// The token identifier. + id: TokenIdOf, + /// The creator of the token. creator: AccountIdOf, - /// The administrator of the asset. + /// The administrator of the token. admin: AccountIdOf, }, } @@ -174,72 +174,73 @@ pub mod pallet { /// Transfers `value` amount of tokens from the caller's account to account `to`. /// /// # Parameters - /// - `asset` - The asset to transfer. + /// - `token` - The token to transfer. /// - `to` - The recipient account. /// - `value` - The number of tokens to transfer. #[pallet::call_index(3)] #[pallet::weight(AssetsWeightInfoOf::::transfer_keep_alive())] pub fn transfer( origin: OriginFor, - asset: AssetIdOf, + token: TokenIdOf, to: AccountIdOf, value: BalanceOf, ) -> DispatchResult { let from = ensure_signed(origin.clone())?; AssetsOf::::transfer_keep_alive( origin, - asset.clone().into(), + token.clone().into(), T::Lookup::unlookup(to.clone()), value, )?; - Self::deposit_event(Event::Transfer { asset, from: Some(from), to: Some(to), value }); + Self::deposit_event(Event::Transfer { token, from: Some(from), to: Some(to), value }); Ok(()) } - /// Transfers `value` amount tokens on behalf of `from` to account `to`. + /// Transfers `value` amount tokens on behalf of `from` to account `to` with additional + /// `data` in unspecified format. /// /// # Parameters - /// - `asset` - The asset to transfer. - /// - `from` - The account from which the asset balance will be withdrawn. + /// - `token` - The token to transfer. + /// - `from` - The account from which the token balance will be withdrawn. /// - `to` - The recipient account. /// - `value` - The number of tokens to transfer. #[pallet::call_index(4)] #[pallet::weight(AssetsWeightInfoOf::::transfer_approved())] pub fn transfer_from( origin: OriginFor, - asset: AssetIdOf, + token: TokenIdOf, from: AccountIdOf, to: AccountIdOf, value: BalanceOf, ) -> DispatchResult { AssetsOf::::transfer_approved( origin, - asset.clone().into(), + token.clone().into(), T::Lookup::unlookup(from.clone()), T::Lookup::unlookup(to.clone()), value, )?; - Self::deposit_event(Event::Transfer { asset, from: Some(from), to: Some(to), value }); + Self::deposit_event(Event::Transfer { token, from: Some(from), to: Some(to), value }); Ok(()) } /// Approves `spender` to spend `value` amount of tokens on behalf of the caller. /// /// # Parameters - /// - `asset` - The asset to approve. + /// - `token` - The token to approve. /// - `spender` - The account that is allowed to spend the tokens. /// - `value` - The number of tokens to approve. #[pallet::call_index(5)] #[pallet::weight(::WeightInfo::approve(1, 1))] pub fn approve( origin: OriginFor, - asset: AssetIdOf, + token: TokenIdOf, spender: AccountIdOf, value: BalanceOf, ) -> DispatchResultWithPostInfo { let owner = ensure_signed(origin.clone()) .map_err(|e| e.with_weight(Self::weight_approve(0, 0)))?; - let current_allowance = AssetsOf::::allowance(asset.clone(), &owner, &spender); + let current_allowance = AssetsOf::::allowance(token.clone(), &owner, &spender); let weight = match value.cmp(¤t_allowance) { // If the new value is equal to the current allowance, do nothing. @@ -249,7 +250,7 @@ pub mod pallet { Greater => { AssetsOf::::approve_transfer( origin, - asset.clone().into(), + token.clone().into(), T::Lookup::unlookup(spender.clone()), value.saturating_sub(current_allowance), ) @@ -259,11 +260,11 @@ pub mod pallet { // If the new value is less than the current allowance, cancel the approval and // set the new value. Less => { - let asset_param: AssetIdParameterOf = asset.clone().into(); + let token_param: TokenIdParameterOf = token.clone().into(); let spender_source = T::Lookup::unlookup(spender.clone()); AssetsOf::::cancel_approval( origin.clone(), - asset_param.clone(), + token_param.clone(), spender_source.clone(), ) .map_err(|e| e.with_weight(Self::weight_approve(0, 1)))?; @@ -272,7 +273,7 @@ pub mod pallet { } else { AssetsOf::::approve_transfer( origin, - asset_param, + token_param, spender_source, value, )?; @@ -280,21 +281,21 @@ pub mod pallet { } }, }; - Self::deposit_event(Event::Approval { asset, owner, spender, value }); + Self::deposit_event(Event::Approval { token, owner, spender, value }); Ok(Some(weight).into()) } /// Increases the allowance of `spender` by `value` amount of tokens. /// /// # Parameters - /// - `asset` - The asset to have an allowance increased. + /// - `token` - The token to have an allowance increased. /// - `spender` - The account that is allowed to spend the tokens. /// - `value` - The number of tokens to increase the allowance by. #[pallet::call_index(6)] #[pallet::weight(::WeightInfo::approve(1, 0))] pub fn increase_allowance( origin: OriginFor, - asset: AssetIdOf, + token: TokenIdOf, spender: AccountIdOf, value: BalanceOf, ) -> DispatchResultWithPostInfo { @@ -302,27 +303,27 @@ pub mod pallet { .map_err(|e| e.with_weight(Self::weight_approve(0, 0)))?; AssetsOf::::approve_transfer( origin, - asset.clone().into(), + token.clone().into(), T::Lookup::unlookup(spender.clone()), value, ) .map_err(|e| e.with_weight(AssetsWeightInfoOf::::approve_transfer()))?; - let value = AssetsOf::::allowance(asset.clone(), &owner, &spender); - Self::deposit_event(Event::Approval { asset, owner, spender, value }); + let value = AssetsOf::::allowance(token.clone(), &owner, &spender); + Self::deposit_event(Event::Approval { token, owner, spender, value }); Ok(().into()) } - /// Decreases the allowance of a `spender` by `value` amount of tokens. + /// Decreases the allowance of `spender` by `value` amount of tokens. /// /// # Parameters - /// - `asset` - The asset to have an allowance decreased. + /// - `token` - The token to have an allowance decreased. /// - `spender` - The account that is allowed to spend the tokens. /// - `value` - The number of tokens to decrease the allowance by. #[pallet::call_index(7)] #[pallet::weight(::WeightInfo::approve(1, 1))] pub fn decrease_allowance( origin: OriginFor, - asset: AssetIdOf, + token: TokenIdOf, spender: AccountIdOf, value: BalanceOf, ) -> DispatchResultWithPostInfo { @@ -331,14 +332,14 @@ pub mod pallet { if value.is_zero() { return Ok(Some(Self::weight_approve(0, 0)).into()); } - let current_allowance = AssetsOf::::allowance(asset.clone(), &owner, &spender); + let current_allowance = AssetsOf::::allowance(token.clone(), &owner, &spender); let spender_source = T::Lookup::unlookup(spender.clone()); - let asset_param: AssetIdParameterOf = asset.clone().into(); + let token_param: TokenIdParameterOf = token.clone().into(); // Cancel the approval and set the new value if `new_allowance` is more than zero. AssetsOf::::cancel_approval( origin.clone(), - asset_param.clone(), + token_param.clone(), spender_source.clone(), ) .map_err(|e| e.with_weight(Self::weight_approve(0, 1)))?; @@ -348,27 +349,27 @@ pub mod pallet { } else { AssetsOf::::approve_transfer( origin, - asset_param, + token_param, spender_source, new_allowance, )?; Self::weight_approve(1, 1) }; - Self::deposit_event(Event::Approval { asset, owner, spender, value: new_allowance }); + Self::deposit_event(Event::Approval { token, owner, spender, value: new_allowance }); Ok(Some(weight).into()) } /// Create a new token with a given identifier. /// /// # Parameters - /// - `id` - The identifier of the asset. - /// - `admin` - The account that will administer the asset. - /// - `min_balance` - The minimum balance required for accounts holding this asset. + /// - `id` - The identifier of the token. + /// - `admin` - The account that will administer the token. + /// - `min_balance` - The minimum balance required for accounts holding this token. #[pallet::call_index(11)] #[pallet::weight(AssetsWeightInfoOf::::create())] pub fn create( origin: OriginFor, - id: AssetIdOf, + id: TokenIdOf, admin: AccountIdOf, min_balance: BalanceOf, ) -> DispatchResult { @@ -386,88 +387,88 @@ pub mod pallet { /// Start the process of destroying a token. /// /// # Parameters - /// - `asset` - The asset to be destroyed. + /// - `token` - The token to be destroyed. #[pallet::call_index(12)] #[pallet::weight(AssetsWeightInfoOf::::start_destroy())] - pub fn start_destroy(origin: OriginFor, asset: AssetIdOf) -> DispatchResult { - AssetsOf::::start_destroy(origin, asset.into()) + pub fn start_destroy(origin: OriginFor, token: TokenIdOf) -> DispatchResult { + AssetsOf::::start_destroy(origin, token.into()) } /// Set the metadata for a token. /// /// # Parameters - /// - `asset`: The asset to update. - /// - `name`: The user friendly name of this asset. - /// - `symbol`: The exchange symbol for this asset. - /// - `decimals`: The number of decimals this asset uses to represent one unit. + /// - `token`: The token to update. + /// - `name`: The user friendly name of this token. + /// - `symbol`: The exchange symbol for this token. + /// - `decimals`: The number of decimals this token uses to represent one unit. #[pallet::call_index(16)] #[pallet::weight(AssetsWeightInfoOf::::set_metadata(name.len() as u32, symbol.len() as u32))] pub fn set_metadata( origin: OriginFor, - asset: AssetIdOf, + token: TokenIdOf, name: Vec, symbol: Vec, decimals: u8, ) -> DispatchResult { - AssetsOf::::set_metadata(origin, asset.into(), name, symbol, decimals) + AssetsOf::::set_metadata(origin, token.into(), name, symbol, decimals) } /// Clear the metadata for a token. /// /// # Parameters - /// - `asset` - The asset to update. + /// - `token` - The token to update. #[pallet::call_index(17)] #[pallet::weight(AssetsWeightInfoOf::::clear_metadata())] - pub fn clear_metadata(origin: OriginFor, asset: AssetIdOf) -> DispatchResult { - AssetsOf::::clear_metadata(origin, asset.into()) + pub fn clear_metadata(origin: OriginFor, token: TokenIdOf) -> DispatchResult { + AssetsOf::::clear_metadata(origin, token.into()) } /// Creates `value` amount of tokens and assigns them to `account`, increasing the total /// supply. /// /// # Parameters - /// - `asset` - The asset to mint. + /// - `token` - The token to mint. /// - `account` - The account to be credited with the created tokens. /// - `value` - The number of tokens to mint. #[pallet::call_index(19)] #[pallet::weight(AssetsWeightInfoOf::::mint())] pub fn mint( origin: OriginFor, - asset: AssetIdOf, + token: TokenIdOf, account: AccountIdOf, value: BalanceOf, ) -> DispatchResult { AssetsOf::::mint( origin, - asset.clone().into(), + token.clone().into(), T::Lookup::unlookup(account.clone()), value, )?; - Self::deposit_event(Event::Transfer { asset, from: None, to: Some(account), value }); + Self::deposit_event(Event::Transfer { token, from: None, to: Some(account), value }); Ok(()) } /// Destroys `value` amount of tokens from `account`, reducing the total supply. /// /// # Parameters - /// - `asset` - the asset to burn. + /// - `token` - the token to burn. /// - `account` - The account from which the tokens will be destroyed. /// - `value` - The number of tokens to destroy. #[pallet::call_index(20)] #[pallet::weight(AssetsWeightInfoOf::::burn())] pub fn burn( origin: OriginFor, - asset: AssetIdOf, + token: TokenIdOf, account: AccountIdOf, value: BalanceOf, ) -> DispatchResult { AssetsOf::::burn( origin, - asset.clone().into(), + token.clone().into(), T::Lookup::unlookup(account.clone()), value, )?; - Self::deposit_event(Event::Transfer { asset, from: Some(account), to: None, value }); + Self::deposit_event(Event::Transfer { token, from: Some(account), to: None, value }); Ok(()) } } @@ -501,21 +502,21 @@ pub mod pallet { fn read(request: Self::Read) -> Self::Result { use Read::*; match request { - TotalSupply(asset) => ReadResult::TotalSupply(AssetsOf::::total_supply(asset)), - BalanceOf { asset, owner } => - ReadResult::BalanceOf(AssetsOf::::balance(asset, owner)), - Allowance { asset, owner, spender } => - ReadResult::Allowance(AssetsOf::::allowance(asset, &owner, &spender)), - TokenName(asset) => ReadResult::TokenName( as MetadataInspect< + TotalSupply(token) => ReadResult::TotalSupply(AssetsOf::::total_supply(token)), + BalanceOf { token, owner } => + ReadResult::BalanceOf(AssetsOf::::balance(token, owner)), + Allowance { token, owner, spender } => + ReadResult::Allowance(AssetsOf::::allowance(token, &owner, &spender)), + TokenName(token) => ReadResult::TokenName( as MetadataInspect< AccountIdOf, - >>::name(asset)), - TokenSymbol(asset) => ReadResult::TokenSymbol( as MetadataInspect< + >>::name(token)), + TokenSymbol(token) => ReadResult::TokenSymbol( as MetadataInspect< AccountIdOf, - >>::symbol(asset)), - TokenDecimals(asset) => ReadResult::TokenDecimals( - as MetadataInspect>>::decimals(asset), + >>::symbol(token)), + TokenDecimals(token) => ReadResult::TokenDecimals( + as MetadataInspect>>::decimals(token), ), - AssetExists(asset) => ReadResult::AssetExists(AssetsOf::::asset_exists(asset)), + TokenExists(token) => ReadResult::TokenExists(AssetsOf::::asset_exists(token)), } } } diff --git a/pallets/api/src/fungibles/tests.rs b/pallets/api/src/fungibles/tests.rs index d850474b..c57c753c 100644 --- a/pallets/api/src/fungibles/tests.rs +++ b/pallets/api/src/fungibles/tests.rs @@ -9,7 +9,7 @@ use frame_support::{ use crate::{fungibles::Read::*, mock::*, Read}; -const ASSET: u32 = 42; +const TOKEN: u32 = 42; type Event = crate::fungibles::Event; @@ -17,16 +17,16 @@ type Event = crate::fungibles::Event; fn transfer_works() { new_test_ext().execute_with(|| { let value: Balance = 100 * UNIT; - let asset = ASSET; + let token = TOKEN; let from = Some(ALICE); let to = Some(BOB); - create_asset_and_mint_to(ALICE, asset, ALICE, value * 2); - let balance_before_transfer = Assets::balance(asset, &BOB); - assert_ok!(Fungibles::transfer(signed(ALICE), asset, BOB, value)); - let balance_after_transfer = Assets::balance(asset, &BOB); + create_token_and_mint_to(ALICE, token, ALICE, value * 2); + let balance_before_transfer = Assets::balance(token, &BOB); + assert_ok!(Fungibles::transfer(signed(ALICE), token, BOB, value)); + let balance_after_transfer = Assets::balance(token, &BOB); assert_eq!(balance_after_transfer, balance_before_transfer + value); - System::assert_last_event(Event::Transfer { asset, from, to, value }.into()); + System::assert_last_event(Event::Transfer { token, from, to, value }.into()); }); } @@ -34,22 +34,22 @@ fn transfer_works() { fn transfer_from_works() { new_test_ext().execute_with(|| { let value: Balance = 100 * UNIT; - let asset = ASSET; + let token = TOKEN; let from = Some(ALICE); let to = Some(BOB); // Approve CHARLIE to transfer up to `value` to BOB. - create_asset_mint_and_approve(ALICE, asset, ALICE, value * 2, CHARLIE, value); + create_token_mint_and_approve(ALICE, token, ALICE, value * 2, CHARLIE, value); // Successfully call transfer from. - let alice_balance_before_transfer = Assets::balance(asset, &ALICE); - let bob_balance_before_transfer = Assets::balance(asset, &BOB); - assert_ok!(Fungibles::transfer_from(signed(CHARLIE), asset, ALICE, BOB, value)); - let alice_balance_after_transfer = Assets::balance(asset, &ALICE); - let bob_balance_after_transfer = Assets::balance(asset, &BOB); + let alice_balance_before_transfer = Assets::balance(token, &ALICE); + let bob_balance_before_transfer = Assets::balance(token, &BOB); + assert_ok!(Fungibles::transfer_from(signed(CHARLIE), token, ALICE, BOB, value)); + let alice_balance_after_transfer = Assets::balance(token, &ALICE); + let bob_balance_after_transfer = Assets::balance(token, &BOB); // Check that BOB receives the `value` and ALICE `amount` is spent successfully by CHARLIE. assert_eq!(bob_balance_after_transfer, bob_balance_before_transfer + value); assert_eq!(alice_balance_after_transfer, alice_balance_before_transfer - value); - System::assert_last_event(Event::Transfer { asset, from, to, value }.into()); + System::assert_last_event(Event::Transfer { token, from, to, value }.into()); }); } @@ -58,37 +58,37 @@ fn transfer_from_works() { fn approve_works() { new_test_ext().execute_with(|| { let value: Balance = 100 * UNIT; - let asset = ASSET; + let token = TOKEN; let owner = ALICE; let spender = BOB; - create_asset_and_mint_to(ALICE, asset, ALICE, value); - assert_eq!(0, Assets::allowance(asset, &ALICE, &BOB)); - assert_ok!(Fungibles::approve(signed(ALICE), asset, BOB, value)); - assert_eq!(Assets::allowance(asset, &ALICE, &BOB), value); - System::assert_last_event(Event::Approval { asset, owner, spender, value }.into()); + create_token_and_mint_to(ALICE, token, ALICE, value); + assert_eq!(0, Assets::allowance(token, &ALICE, &BOB)); + assert_ok!(Fungibles::approve(signed(ALICE), token, BOB, value)); + assert_eq!(Assets::allowance(token, &ALICE, &BOB), value); + System::assert_last_event(Event::Approval { token, owner, spender, value }.into()); // Approves an value to spend that is lower than the current allowance. - assert_ok!(Fungibles::approve(signed(ALICE), asset, BOB, value / 2)); - assert_eq!(Assets::allowance(asset, &ALICE, &BOB), value / 2); + assert_ok!(Fungibles::approve(signed(ALICE), token, BOB, value / 2)); + assert_eq!(Assets::allowance(token, &ALICE, &BOB), value / 2); System::assert_last_event( - Event::Approval { asset, owner, spender, value: value / 2 }.into(), + Event::Approval { token, owner, spender, value: value / 2 }.into(), ); // Approves an value to spend that is higher than the current allowance. - assert_ok!(Fungibles::approve(signed(ALICE), asset, BOB, value * 2)); - assert_eq!(Assets::allowance(asset, &ALICE, &BOB), value * 2); + assert_ok!(Fungibles::approve(signed(ALICE), token, BOB, value * 2)); + assert_eq!(Assets::allowance(token, &ALICE, &BOB), value * 2); System::assert_last_event( - Event::Approval { asset, owner, spender, value: value * 2 }.into(), + Event::Approval { token, owner, spender, value: value * 2 }.into(), ); // Approves an value to spend that is equal to the current allowance. - assert_ok!(Fungibles::approve(signed(ALICE), asset, BOB, value * 2)); - assert_eq!(Assets::allowance(asset, &ALICE, &BOB), value * 2); + assert_ok!(Fungibles::approve(signed(ALICE), token, BOB, value * 2)); + assert_eq!(Assets::allowance(token, &ALICE, &BOB), value * 2); System::assert_last_event( - Event::Approval { asset, owner, spender, value: value * 2 }.into(), + Event::Approval { token, owner, spender, value: value * 2 }.into(), ); // Sets allowance to zero. - assert_ok!(Fungibles::approve(signed(ALICE), asset, BOB, 0)); - assert_eq!(Assets::allowance(asset, &ALICE, &BOB), 0); - System::assert_last_event(Event::Approval { asset, owner, spender, value: 0 }.into()); + assert_ok!(Fungibles::approve(signed(ALICE), token, BOB, 0)); + assert_eq!(Assets::allowance(token, &ALICE, &BOB), 0); + System::assert_last_event(Event::Approval { token, owner, spender, value: 0 }.into()); }); } @@ -96,20 +96,20 @@ fn approve_works() { fn increase_allowance_works() { new_test_ext().execute_with(|| { let value: Balance = 100 * UNIT; - let asset = ASSET; + let token = TOKEN; let owner = ALICE; let spender = BOB; - create_asset_and_mint_to(ALICE, asset, ALICE, value); - assert_eq!(0, Assets::allowance(asset, &ALICE, &BOB)); - assert_ok!(Fungibles::increase_allowance(signed(ALICE), asset, BOB, value)); - assert_eq!(Assets::allowance(asset, &ALICE, &BOB), value); - System::assert_last_event(Event::Approval { asset, owner, spender, value }.into()); + create_token_and_mint_to(ALICE, token, ALICE, value); + assert_eq!(0, Assets::allowance(token, &ALICE, &BOB)); + assert_ok!(Fungibles::increase_allowance(signed(ALICE), token, BOB, value)); + assert_eq!(Assets::allowance(token, &ALICE, &BOB), value); + System::assert_last_event(Event::Approval { token, owner, spender, value }.into()); // Additive. - assert_ok!(Fungibles::increase_allowance(signed(ALICE), asset, BOB, value)); - assert_eq!(Assets::allowance(asset, &ALICE, &BOB), value * 2); + assert_ok!(Fungibles::increase_allowance(signed(ALICE), token, BOB, value)); + assert_eq!(Assets::allowance(token, &ALICE, &BOB), value * 2); System::assert_last_event( - Event::Approval { asset, owner, spender, value: value * 2 }.into(), + Event::Approval { token, owner, spender, value: value * 2 }.into(), ); }); } @@ -118,32 +118,32 @@ fn increase_allowance_works() { fn decrease_allowance_works() { new_test_ext().execute_with(|| { let value: Balance = 100 * UNIT; - let asset = ASSET; + let token = TOKEN; let owner = ALICE; let spender = BOB; - create_asset_mint_and_approve(ALICE, asset, ALICE, value, BOB, value); - assert_eq!(Assets::allowance(asset, &ALICE, &BOB), value); + create_token_mint_and_approve(ALICE, token, ALICE, value, BOB, value); + assert_eq!(Assets::allowance(token, &ALICE, &BOB), value); // Owner balance is not changed if decreased by zero. - assert_ok!(Fungibles::decrease_allowance(signed(ALICE), asset, BOB, 0)); - assert_eq!(Assets::allowance(asset, &ALICE, &BOB), value); + assert_ok!(Fungibles::decrease_allowance(signed(ALICE), token, BOB, 0)); + assert_eq!(Assets::allowance(token, &ALICE, &BOB), value); // Decrease allowance successfully. - assert_ok!(Fungibles::decrease_allowance(signed(ALICE), asset, BOB, value / 2)); - assert_eq!(Assets::allowance(asset, &ALICE, &BOB), value / 2); + assert_ok!(Fungibles::decrease_allowance(signed(ALICE), token, BOB, value / 2)); + assert_eq!(Assets::allowance(token, &ALICE, &BOB), value / 2); System::assert_last_event( - Event::Approval { asset, owner, spender, value: value / 2 }.into(), + Event::Approval { token, owner, spender, value: value / 2 }.into(), ); // Saturating if current allowance is decreased more than the owner balance. - assert_ok!(Fungibles::decrease_allowance(signed(ALICE), asset, BOB, value)); - assert_eq!(Assets::allowance(asset, &ALICE, &BOB), 0); - System::assert_last_event(Event::Approval { asset, owner, spender, value: 0 }.into()); + assert_ok!(Fungibles::decrease_allowance(signed(ALICE), token, BOB, value)); + assert_eq!(Assets::allowance(token, &ALICE, &BOB), 0); + System::assert_last_event(Event::Approval { token, owner, spender, value: 0 }.into()); }); } #[test] fn create_works() { new_test_ext().execute_with(|| { - let id = ASSET; + let id = TOKEN; let creator = ALICE; let admin = ALICE; @@ -157,45 +157,45 @@ fn create_works() { #[test] fn start_destroy_works() { new_test_ext().execute_with(|| { - let asset = ASSET; + let token = TOKEN; - create_asset(ALICE, asset); - assert_ok!(Fungibles::start_destroy(signed(ALICE), asset)); + create_token(ALICE, token); + assert_ok!(Fungibles::start_destroy(signed(ALICE), token)); }); } #[test] fn set_metadata_works() { new_test_ext().execute_with(|| { - let asset = ASSET; + let token = TOKEN; let name = vec![42]; let symbol = vec![42]; let decimals = 42; - create_asset(ALICE, asset); + create_token(ALICE, token); assert_ok!(Fungibles::set_metadata( signed(ALICE), - asset, + token, name.clone(), symbol.clone(), decimals )); - assert_eq!(Assets::name(asset), name); - assert_eq!(Assets::symbol(asset), symbol); - assert_eq!(Assets::decimals(asset), decimals); + assert_eq!(Assets::name(token), name); + assert_eq!(Assets::symbol(token), symbol); + assert_eq!(Assets::decimals(token), decimals); }); } #[test] fn clear_metadata_works() { new_test_ext().execute_with(|| { - let asset = ASSET; + let token = TOKEN; - create_asset_and_set_metadata(ALICE, asset, vec![42], vec![42], 42); - assert_ok!(Fungibles::clear_metadata(signed(ALICE), asset)); - assert!(Assets::name(asset).is_empty()); - assert!(Assets::symbol(asset).is_empty()); - assert!(Assets::decimals(asset).is_zero()); + create_token_and_set_metadata(ALICE, token, vec![42], vec![42], 42); + assert_ok!(Fungibles::clear_metadata(signed(ALICE), token)); + assert!(Assets::name(token).is_empty()); + assert!(Assets::symbol(token).is_empty()); + assert!(Assets::decimals(token).is_zero()); }); } @@ -203,16 +203,16 @@ fn clear_metadata_works() { fn mint_works() { new_test_ext().execute_with(|| { let value: Balance = 100 * UNIT; - let asset = ASSET; + let token = TOKEN; let from = None; let to = Some(BOB); - create_asset(ALICE, asset); - let balance_before_mint = Assets::balance(asset, &BOB); - assert_ok!(Fungibles::mint(signed(ALICE), asset, BOB, value)); - let balance_after_mint = Assets::balance(asset, &BOB); + create_token(ALICE, token); + let balance_before_mint = Assets::balance(token, &BOB); + assert_ok!(Fungibles::mint(signed(ALICE), token, BOB, value)); + let balance_after_mint = Assets::balance(token, &BOB); assert_eq!(balance_after_mint, balance_before_mint + value); - System::assert_last_event(Event::Transfer { asset, from, to, value }.into()); + System::assert_last_event(Event::Transfer { token, from, to, value }.into()); }); } @@ -220,26 +220,26 @@ fn mint_works() { fn burn_works() { new_test_ext().execute_with(|| { let value: Balance = 100 * UNIT; - let asset = ASSET; + let token = TOKEN; let from = Some(BOB); let to = None; - create_asset_and_mint_to(ALICE, asset, BOB, value); - let balance_before_burn = Assets::balance(asset, &BOB); - assert_ok!(Fungibles::burn(signed(ALICE), asset, BOB, value)); - let balance_after_burn = Assets::balance(asset, &BOB); + create_token_and_mint_to(ALICE, token, BOB, value); + let balance_before_burn = Assets::balance(token, &BOB); + assert_ok!(Fungibles::burn(signed(ALICE), token, BOB, value)); + let balance_after_burn = Assets::balance(token, &BOB); assert_eq!(balance_after_burn, balance_before_burn - value); - System::assert_last_event(Event::Transfer { asset, from, to, value }.into()); + System::assert_last_event(Event::Transfer { token, from, to, value }.into()); }); } #[test] fn total_supply_works() { new_test_ext().execute_with(|| { - create_asset_and_mint_to(ALICE, ASSET, ALICE, 100); + create_token_and_mint_to(ALICE, TOKEN, ALICE, 100); assert_eq!( - Assets::total_supply(ASSET).encode(), - Fungibles::read(TotalSupply(ASSET)).encode() + Assets::total_supply(TOKEN).encode(), + Fungibles::read(TotalSupply(TOKEN)).encode() ); }); } @@ -247,10 +247,10 @@ fn total_supply_works() { #[test] fn balance_of_works() { new_test_ext().execute_with(|| { - create_asset_and_mint_to(ALICE, ASSET, ALICE, 100); + create_token_and_mint_to(ALICE, TOKEN, ALICE, 100); assert_eq!( - Assets::balance(ASSET, ALICE).encode(), - Fungibles::read(BalanceOf { asset: ASSET, owner: ALICE }).encode() + Assets::balance(TOKEN, ALICE).encode(), + Fungibles::read(BalanceOf { token: TOKEN, owner: ALICE }).encode() ); }); } @@ -258,10 +258,10 @@ fn balance_of_works() { #[test] fn allowance_works() { new_test_ext().execute_with(|| { - create_asset_mint_and_approve(ALICE, ASSET, BOB, 100, ALICE, 50); + create_token_mint_and_approve(ALICE, TOKEN, BOB, 100, ALICE, 50); assert_eq!( - Assets::allowance(ASSET, &ALICE, &BOB).encode(), - Fungibles::read(Allowance { asset: ASSET, owner: ALICE, spender: BOB }).encode() + Assets::allowance(TOKEN, &ALICE, &BOB).encode(), + Fungibles::read(Allowance { token: TOKEN, owner: ALICE, spender: BOB }).encode() ); }); } @@ -272,23 +272,23 @@ fn token_metadata_works() { let name: Vec = vec![11, 12, 13]; let symbol: Vec = vec![21, 22, 23]; let decimals: u8 = 69; - create_asset_and_set_metadata(ALICE, ASSET, name.clone(), symbol.clone(), decimals); - assert_eq!(Assets::name(ASSET).encode(), Fungibles::read(TokenName(ASSET)).encode()); - assert_eq!(Assets::symbol(ASSET).encode(), Fungibles::read(TokenSymbol(ASSET)).encode()); + create_token_and_set_metadata(ALICE, TOKEN, name.clone(), symbol.clone(), decimals); + assert_eq!(Assets::name(TOKEN).encode(), Fungibles::read(TokenName(TOKEN)).encode()); + assert_eq!(Assets::symbol(TOKEN).encode(), Fungibles::read(TokenSymbol(TOKEN)).encode()); assert_eq!( - Assets::decimals(ASSET).encode(), - Fungibles::read(TokenDecimals(ASSET)).encode() + Assets::decimals(TOKEN).encode(), + Fungibles::read(TokenDecimals(TOKEN)).encode() ); }); } #[test] -fn asset_exists_works() { +fn token_exists_works() { new_test_ext().execute_with(|| { - create_asset(ALICE, ASSET); + create_token(ALICE, TOKEN); assert_eq!( - Assets::asset_exists(ASSET).encode(), - Fungibles::read(AssetExists(ASSET)).encode() + Assets::asset_exists(TOKEN).encode(), + Fungibles::read(TokenExists(TOKEN)).encode() ); }); } @@ -297,48 +297,48 @@ fn signed(account: AccountId) -> RuntimeOrigin { RuntimeOrigin::signed(account) } -fn create_asset(owner: AccountId, asset: AssetId) { - assert_ok!(Assets::create(signed(owner), asset, owner, 1)); +fn create_token(owner: AccountId, token: TokenId) { + assert_ok!(Assets::create(signed(owner), token, owner, 1)); } -fn mint_asset(owner: AccountId, asset: AssetId, to: AccountId, value: Balance) { - assert_ok!(Assets::mint(signed(owner), asset, to, value)); +fn mint_token(owner: AccountId, token: TokenId, to: AccountId, value: Balance) { + assert_ok!(Assets::mint(signed(owner), token, to, value)); } -fn create_asset_and_mint_to(owner: AccountId, asset: AssetId, to: AccountId, value: Balance) { - create_asset(owner, asset); - mint_asset(owner, asset, to, value) +fn create_token_and_mint_to(owner: AccountId, token: TokenId, to: AccountId, value: Balance) { + create_token(owner, token); + mint_token(owner, token, to, value) } -fn create_asset_mint_and_approve( +fn create_token_mint_and_approve( owner: AccountId, - asset: AssetId, + token: TokenId, to: AccountId, mint: Balance, spender: AccountId, approve: Balance, ) { - create_asset_and_mint_to(owner, asset, to, mint); - assert_ok!(Assets::approve_transfer(signed(to), asset, spender, approve,)); + create_token_and_mint_to(owner, token, to, mint); + assert_ok!(Assets::approve_transfer(signed(to), token, spender, approve,)); } -fn create_asset_and_set_metadata( +fn create_token_and_set_metadata( owner: AccountId, - asset: AssetId, + token: TokenId, name: Vec, symbol: Vec, decimals: u8, ) { - assert_ok!(Assets::create(signed(owner), asset, owner, 100)); - set_metadata_asset(owner, asset, name, symbol, decimals); + assert_ok!(Assets::create(signed(owner), token, owner, 100)); + set_metadata_token(owner, token, name, symbol, decimals); } -fn set_metadata_asset( +fn set_metadata_token( owner: AccountId, - asset: AssetId, + token: TokenId, name: Vec, symbol: Vec, decimals: u8, ) { - assert_ok!(Assets::set_metadata(signed(owner), asset, name, symbol, decimals)); + assert_ok!(Assets::set_metadata(signed(owner), token, name, symbol, decimals)); } diff --git a/pallets/api/src/mock.rs b/pallets/api/src/mock.rs index fe2b2c9a..b736656f 100644 --- a/pallets/api/src/mock.rs +++ b/pallets/api/src/mock.rs @@ -11,8 +11,9 @@ use sp_runtime::{ type Block = frame_system::mocking::MockBlock; pub(crate) type AccountId = u64; -pub(crate) type AssetId = u32; pub(crate) type Balance = u128; +// For terminology in tests. +pub(crate) type TokenId = u32; // Configure a mock runtime to test the pallet. frame_support::construct_runtime!( @@ -78,7 +79,7 @@ impl pallet_assets::Config for Test { type ApprovalDeposit = ConstU128<1>; type AssetAccountDeposit = ConstU128<10>; type AssetDeposit = ConstU128<1>; - type AssetId = AssetId; + type AssetId = TokenId; type AssetIdParameter = u32; type Balance = Balance; #[cfg(feature = "runtime-benchmarks")] diff --git a/pop-api/Cargo.toml b/pop-api/Cargo.toml index 8296569a..ae381d08 100644 --- a/pop-api/Cargo.toml +++ b/pop-api/Cargo.toml @@ -20,7 +20,6 @@ name = "pop_api" path = "src/lib.rs" [features] -assets = [ ] default = [ "std" ] -fungibles = [ "assets" ] +fungibles = [ ] std = [ "ink/std", "pop-primitives/std", "sp-io/std" ] diff --git a/pop-api/integration-tests/contracts/create_token_in_constructor/lib.rs b/pop-api/integration-tests/contracts/create_token_in_constructor/lib.rs index e9e5d127..93838f3c 100755 --- a/pop-api/integration-tests/contracts/create_token_in_constructor/lib.rs +++ b/pop-api/integration-tests/contracts/create_token_in_constructor/lib.rs @@ -1,9 +1,8 @@ #![cfg_attr(not(feature = "std"), no_std, no_main)] -use ink::prelude::vec::Vec; use pop_api::{ - assets::fungibles::{self as api}, - primitives::AssetId, + fungibles::{self as api}, + primitives::TokenId, StatusCode, }; @@ -15,12 +14,12 @@ mod create_token_in_constructor { #[ink(storage)] pub struct Fungible { - id: AssetId, + id: TokenId, } impl Fungible { #[ink(constructor, payable)] - pub fn new(id: AssetId, min_balance: Balance) -> Result { + pub fn new(id: TokenId, min_balance: Balance) -> Result { let contract = Self { id }; // AccountId of the contract which will be set to the owner of the fungible token. let owner = contract.env().account_id(); @@ -29,18 +28,8 @@ mod create_token_in_constructor { } #[ink(message)] - pub fn asset_exists(&self) -> Result { - api::asset_exists(self.id) - } - } - - #[cfg(test)] - mod tests { - use super::*; - - #[ink::test] - fn default_works() { - PopApiFungiblesExample::new(); + pub fn token_exists(&self) -> Result { + api::token_exists(self.id) } } } diff --git a/pop-api/integration-tests/contracts/fungibles/lib.rs b/pop-api/integration-tests/contracts/fungibles/lib.rs index 2b33ce04..6530968a 100755 --- a/pop-api/integration-tests/contracts/fungibles/lib.rs +++ b/pop-api/integration-tests/contracts/fungibles/lib.rs @@ -1,14 +1,13 @@ #![cfg_attr(not(feature = "std"), no_std, no_main)] -/// Local Fungibles: -/// 1. PSP-22 Interface -/// 2. PSP-22 Metadata Interface -/// 3. Asset Management -/// +/// 1. PSP-22 +/// 2. PSP-22 Metadata +/// 3. Management +/// 4. PSP-22 Mintable & Burnable use ink::prelude::vec::Vec; use pop_api::{ - assets::fungibles::{self as api}, - primitives::AssetId, + fungibles::{self as api}, + primitives::TokenId, StatusCode, }; @@ -40,66 +39,66 @@ mod fungibles { /// - decrease_allowance #[ink(message)] - pub fn total_supply(&self, id: AssetId) -> Result { - api::total_supply(id) + pub fn total_supply(&self, token: TokenId) -> Result { + api::total_supply(token) } #[ink(message)] - pub fn balance_of(&self, id: AssetId, owner: AccountId) -> Result { - api::balance_of(id, owner) + pub fn balance_of(&self, token: TokenId, owner: AccountId) -> Result { + api::balance_of(token, owner) } #[ink(message)] pub fn allowance( &self, - id: AssetId, + token: TokenId, owner: AccountId, spender: AccountId, ) -> Result { - api::allowance(id, owner, spender) + api::allowance(token, owner, spender) } #[ink(message)] - pub fn transfer(&mut self, id: AssetId, to: AccountId, value: Balance) -> Result<()> { - api::transfer(id, to, value) + pub fn transfer(&mut self, token: TokenId, to: AccountId, value: Balance) -> Result<()> { + api::transfer(token, to, value) } #[ink(message)] pub fn transfer_from( &mut self, - id: AssetId, + token: TokenId, from: AccountId, to: AccountId, value: Balance, // In the PSP-22 standard a `[u8]`, but the size needs to be known at compile time. _data: Vec, ) -> Result<()> { - api::transfer_from(id, from, to, value) + api::transfer_from(token, from, to, value) } #[ink(message)] - pub fn approve(&mut self, id: AssetId, spender: AccountId, value: Balance) -> Result<()> { - api::approve(id, spender, value) + pub fn approve(&mut self, token: TokenId, spender: AccountId, value: Balance) -> Result<()> { + api::approve(token, spender, value) } #[ink(message)] pub fn increase_allowance( &mut self, - id: AssetId, + token: TokenId, spender: AccountId, value: Balance, ) -> Result<()> { - api::increase_allowance(id, spender, value) + api::increase_allowance(token, spender, value) } #[ink(message)] pub fn decrease_allowance( &mut self, - id: AssetId, + token: TokenId, spender: AccountId, value: Balance, ) -> Result<()> { - api::decrease_allowance(id, spender, value) + api::decrease_allowance(token, spender, value) } /// 2. PSP-22 Metadata Interface: @@ -108,18 +107,18 @@ mod fungibles { /// - token_decimals #[ink(message)] - pub fn token_name(&self, id: AssetId) -> Result> { - api::token_name(id) + pub fn token_name(&self, token: TokenId) -> Result> { + api::token_name(token) } #[ink(message)] - pub fn token_symbol(&self, id: AssetId) -> Result> { - api::token_symbol(id) + pub fn token_symbol(&self, token: TokenId) -> Result> { + api::token_symbol(token) } #[ink(message)] - pub fn token_decimals(&self, id: AssetId) -> Result { - api::token_decimals(id) + pub fn token_decimals(&self, token: TokenId) -> Result { + api::token_decimals(token) } /// 3. Asset Management: @@ -127,12 +126,12 @@ mod fungibles { /// - start_destroy /// - set_metadata /// - clear_metadata - /// - asset_exists + /// - token_exists #[ink(message)] pub fn create( &mut self, - id: AssetId, + id: TokenId, admin: AccountId, min_balance: Balance, ) -> Result<()> { @@ -140,29 +139,29 @@ mod fungibles { } #[ink(message)] - pub fn start_destroy(&mut self, id: AssetId) -> Result<()> { - api::start_destroy(id) + pub fn start_destroy(&mut self, token: TokenId) -> Result<()> { + api::start_destroy(token) } #[ink(message)] pub fn set_metadata( &mut self, - id: AssetId, + token: TokenId, name: Vec, symbol: Vec, decimals: u8, ) -> Result<()> { - api::set_metadata(id, name, symbol, decimals) + api::set_metadata(token, name, symbol, decimals) } #[ink(message)] - pub fn clear_metadata(&self, id: AssetId) -> Result<()> { - api::clear_metadata(id) + pub fn clear_metadata(&self, token: TokenId) -> Result<()> { + api::clear_metadata(token) } #[ink(message)] - pub fn asset_exists(&self, id: AssetId) -> Result { - api::asset_exists(id) + pub fn token_exists(&self, token: TokenId) -> Result { + api::token_exists(token) } /// 4. PSP-22 Mintable & Burnable Interface: @@ -170,13 +169,13 @@ mod fungibles { /// - burn #[ink(message)] - pub fn mint(&mut self, id: AssetId, account: AccountId, amount: Balance) -> Result<()> { - api::mint(id, account, amount) + pub fn mint(&mut self, token: TokenId, account: AccountId, amount: Balance) -> Result<()> { + api::mint(token, account, amount) } #[ink(message)] - pub fn burn(&mut self, id: AssetId, account: AccountId, amount: Balance) -> Result<()> { - api::burn(id, account, amount) + pub fn burn(&mut self, token: TokenId, account: AccountId, amount: Balance) -> Result<()> { + api::burn(token, account, amount) } } diff --git a/pop-api/integration-tests/src/fungibles/mod.rs b/pop-api/integration-tests/src/fungibles/mod.rs index 0d895aa3..bfea0b45 100644 --- a/pop-api/integration-tests/src/fungibles/mod.rs +++ b/pop-api/integration-tests/src/fungibles/mod.rs @@ -1,10 +1,11 @@ -use super::*; -use pop_primitives::{ArithmeticError::*, AssetId, Error::*, TokenError::*, *}; +use pop_primitives::{ArithmeticError::*, Error::*, TokenError::*, TokenId, *}; use utils::*; +use super::*; + mod utils; -const ASSET_ID: AssetId = 1; +const TOKEN_ID: TokenId = 1; const CONTRACT: &str = "contracts/fungibles/target/ink/fungibles.wasm"; /// 1. PSP-22 Interface: @@ -24,13 +25,13 @@ fn total_supply_works() { let addr = instantiate(CONTRACT, INIT_VALUE, vec![]); // No tokens in circulation. - assert_eq!(total_supply(addr.clone(), ASSET_ID), Ok(Assets::total_supply(ASSET_ID))); - assert_eq!(total_supply(addr.clone(), ASSET_ID), Ok(0)); + assert_eq!(total_supply(addr.clone(), TOKEN_ID), Ok(Assets::total_supply(TOKEN_ID))); + assert_eq!(total_supply(addr.clone(), TOKEN_ID), Ok(0)); // Tokens in circulation. - create_asset_and_mint_to(addr.clone(), ASSET_ID, BOB, 100); - assert_eq!(total_supply(addr.clone(), ASSET_ID), Ok(Assets::total_supply(ASSET_ID))); - assert_eq!(total_supply(addr, ASSET_ID), Ok(100)); + create_asset_and_mint_to(addr.clone(), TOKEN_ID, BOB, 100); + assert_eq!(total_supply(addr.clone(), TOKEN_ID), Ok(Assets::total_supply(TOKEN_ID))); + assert_eq!(total_supply(addr, TOKEN_ID), Ok(100)); }); } @@ -41,13 +42,13 @@ fn balance_of_works() { let addr = instantiate(CONTRACT, INIT_VALUE, vec![]); // No tokens in circulation. - assert_eq!(balance_of(addr.clone(), ASSET_ID, BOB), Ok(Assets::balance(ASSET_ID, BOB))); - assert_eq!(balance_of(addr.clone(), ASSET_ID, BOB), Ok(0)); + assert_eq!(balance_of(addr.clone(), TOKEN_ID, BOB), Ok(Assets::balance(TOKEN_ID, BOB))); + assert_eq!(balance_of(addr.clone(), TOKEN_ID, BOB), Ok(0)); // Tokens in circulation. - create_asset_and_mint_to(addr.clone(), ASSET_ID, BOB, 100); - assert_eq!(balance_of(addr.clone(), ASSET_ID, BOB), Ok(Assets::balance(ASSET_ID, BOB))); - assert_eq!(balance_of(addr, ASSET_ID, BOB), Ok(100)); + create_asset_and_mint_to(addr.clone(), TOKEN_ID, BOB, 100); + assert_eq!(balance_of(addr.clone(), TOKEN_ID, BOB), Ok(Assets::balance(TOKEN_ID, BOB))); + assert_eq!(balance_of(addr, TOKEN_ID, BOB), Ok(100)); }); } @@ -59,18 +60,18 @@ fn allowance_works() { // No tokens in circulation. assert_eq!( - allowance(addr.clone(), ASSET_ID, BOB, ALICE), - Ok(Assets::allowance(ASSET_ID, &BOB, &ALICE)) + allowance(addr.clone(), TOKEN_ID, BOB, ALICE), + Ok(Assets::allowance(TOKEN_ID, &BOB, &ALICE)) ); - assert_eq!(allowance(addr.clone(), ASSET_ID, BOB, ALICE), Ok(0)); + assert_eq!(allowance(addr.clone(), TOKEN_ID, BOB, ALICE), Ok(0)); // Tokens in circulation. - create_asset_mint_and_approve(addr.clone(), ASSET_ID, BOB, 100, ALICE, 50); + create_asset_mint_and_approve(addr.clone(), TOKEN_ID, BOB, 100, ALICE, 50); assert_eq!( - allowance(addr.clone(), ASSET_ID, BOB, ALICE), - Ok(Assets::allowance(ASSET_ID, &BOB, &ALICE)) + allowance(addr.clone(), TOKEN_ID, BOB, ALICE), + Ok(Assets::allowance(TOKEN_ID, &BOB, &ALICE)) ); - assert_eq!(allowance(addr, ASSET_ID, BOB, ALICE), Ok(50)); + assert_eq!(allowance(addr, TOKEN_ID, BOB, ALICE), Ok(50)); }); } @@ -296,26 +297,26 @@ fn token_metadata_works() { let decimals: u8 = 69; // Token does not exist. - assert_eq!(token_name(addr.clone(), ASSET_ID), Ok(token_name_asset(ASSET_ID))); - assert_eq!(token_name(addr.clone(), ASSET_ID), Ok(Vec::::new())); - assert_eq!(token_symbol(addr.clone(), ASSET_ID), Ok(token_symbol_asset(ASSET_ID))); - assert_eq!(token_symbol(addr.clone(), ASSET_ID), Ok(Vec::::new())); - assert_eq!(token_decimals(addr.clone(), ASSET_ID), Ok(token_decimals_asset(ASSET_ID))); - assert_eq!(token_decimals(addr.clone(), ASSET_ID), Ok(0)); + assert_eq!(token_name(addr.clone(), TOKEN_ID), Ok(token_name_asset(TOKEN_ID))); + assert_eq!(token_name(addr.clone(), TOKEN_ID), Ok(Vec::::new())); + assert_eq!(token_symbol(addr.clone(), TOKEN_ID), Ok(token_symbol_asset(TOKEN_ID))); + assert_eq!(token_symbol(addr.clone(), TOKEN_ID), Ok(Vec::::new())); + assert_eq!(token_decimals(addr.clone(), TOKEN_ID), Ok(token_decimals_asset(TOKEN_ID))); + assert_eq!(token_decimals(addr.clone(), TOKEN_ID), Ok(0)); // Create Token. create_asset_and_set_metadata( addr.clone(), - ASSET_ID, + TOKEN_ID, name.clone(), symbol.clone(), decimals, ); - assert_eq!(token_name(addr.clone(), ASSET_ID), Ok(token_name_asset(ASSET_ID))); - assert_eq!(token_name(addr.clone(), ASSET_ID), Ok(name)); - assert_eq!(token_symbol(addr.clone(), ASSET_ID), Ok(token_symbol_asset(ASSET_ID))); - assert_eq!(token_symbol(addr.clone(), ASSET_ID), Ok(symbol)); - assert_eq!(token_decimals(addr.clone(), ASSET_ID), Ok(token_decimals_asset(ASSET_ID))); - assert_eq!(token_decimals(addr.clone(), ASSET_ID), Ok(decimals)); + assert_eq!(token_name(addr.clone(), TOKEN_ID), Ok(token_name_asset(TOKEN_ID))); + assert_eq!(token_name(addr.clone(), TOKEN_ID), Ok(name)); + assert_eq!(token_symbol(addr.clone(), TOKEN_ID), Ok(token_symbol_asset(TOKEN_ID))); + assert_eq!(token_symbol(addr.clone(), TOKEN_ID), Ok(symbol)); + assert_eq!(token_decimals(addr.clone(), TOKEN_ID), Ok(token_decimals_asset(TOKEN_ID))); + assert_eq!(token_decimals(addr.clone(), TOKEN_ID), Ok(decimals)); }); } @@ -324,7 +325,7 @@ fn token_metadata_works() { /// - start_destroy /// - set_metadata /// - clear_metadata -/// - asset_exists +/// - token_exists #[test] fn create_works() { @@ -334,7 +335,7 @@ fn create_works() { let addr = instantiate(CONTRACT, 0, vec![0]); // No balance to pay for fees. assert_eq!( - create(addr.clone(), ASSET_ID, addr.clone(), 1), + create(addr.clone(), TOKEN_ID, addr.clone(), 1), Err(Module { index: 10, error: [2, 0] }), ); @@ -342,26 +343,26 @@ fn create_works() { let addr = instantiate(CONTRACT, 100, vec![1]); // No balance to pay the deposit. assert_eq!( - create(addr.clone(), ASSET_ID, addr.clone(), 1), + create(addr.clone(), TOKEN_ID, addr.clone(), 1), Err(Module { index: 10, error: [2, 0] }), ); // Instantiate a contract with enough balance. let addr = instantiate(CONTRACT, INIT_VALUE, vec![2]); assert_eq!( - create(addr.clone(), ASSET_ID, BOB, 0), + create(addr.clone(), TOKEN_ID, BOB, 0), Err(Module { index: 52, error: [7, 0] }), ); // The minimal balance for an asset must be non zero. assert_eq!( - create(addr.clone(), ASSET_ID, BOB, 0), + create(addr.clone(), TOKEN_ID, BOB, 0), Err(Module { index: 52, error: [7, 0] }), ); // Create asset successfully. - assert_ok!(create(addr.clone(), ASSET_ID, BOB, 1)); + assert_ok!(create(addr.clone(), TOKEN_ID, BOB, 1)); // Asset ID is already taken. assert_eq!( - create(addr.clone(), ASSET_ID, BOB, 1), + create(addr.clone(), TOKEN_ID, BOB, 1), Err(Module { index: 52, error: [5, 0] }), ); }); @@ -381,8 +382,8 @@ fn instantiate_and_create_fungible_works() { Err(Module { index: 52, error: [5, 0] }) ); // Successfully create an asset when instantiating the contract. - assert_ok!(instantiate_and_create_fungible(contract, ASSET_ID, 1)); - assert!(Assets::asset_exists(ASSET_ID)); + assert_ok!(instantiate_and_create_fungible(contract, TOKEN_ID, 1)); + assert!(Assets::asset_exists(TOKEN_ID)); }); } @@ -393,12 +394,12 @@ fn start_destroy_works() { let addr = instantiate(CONTRACT, INIT_VALUE, vec![2]); // Asset does not exist. - assert_eq!(start_destroy(addr.clone(), ASSET_ID), Err(Module { index: 52, error: [3, 0] }),); + assert_eq!(start_destroy(addr.clone(), TOKEN_ID), Err(Module { index: 52, error: [3, 0] }),); // Create assets where contract is not the owner. let asset = create_asset(ALICE, 0, 1); // No Permission. assert_eq!(start_destroy(addr.clone(), asset), Err(Module { index: 52, error: [2, 0] }),); - let asset = create_asset(addr.clone(), ASSET_ID, 1); + let asset = create_asset(addr.clone(), TOKEN_ID, 1); assert_ok!(start_destroy(addr.clone(), asset)); }); } @@ -414,7 +415,7 @@ fn set_metadata_works() { // Asset does not exist. assert_eq!( - set_metadata(addr.clone(), ASSET_ID, vec![0], vec![0], 0u8), + set_metadata(addr.clone(), TOKEN_ID, vec![0], vec![0], 0u8), Err(Module { index: 52, error: [3, 0] }), ); // Create assets where contract is not the owner. @@ -424,11 +425,11 @@ fn set_metadata_works() { set_metadata(addr.clone(), asset, vec![0], vec![0], 0u8), Err(Module { index: 52, error: [2, 0] }), ); - let asset = create_asset(addr.clone(), ASSET_ID, 1); + let asset = create_asset(addr.clone(), TOKEN_ID, 1); // Asset is not live, i.e. frozen or being destroyed. freeze_asset(addr.clone(), asset); assert_eq!( - set_metadata(addr.clone(), ASSET_ID, vec![0], vec![0], 0u8), + set_metadata(addr.clone(), TOKEN_ID, vec![0], vec![0], 0u8), Err(Module { index: 52, error: [16, 0] }), ); thaw_asset(addr.clone(), asset); @@ -436,15 +437,15 @@ fn set_metadata_works() { // `OutputBufferTooSmall. Added to security analysis issue #131 to revisit. // Set bad metadata - too large values. assert_eq!( - set_metadata(addr.clone(), ASSET_ID, vec![0; 1000], vec![0; 1000], 0u8), + set_metadata(addr.clone(), TOKEN_ID, vec![0; 1000], vec![0; 1000], 0u8), Err(Module { index: 52, error: [9, 0] }), ); // Set metadata successfully. - assert_ok!(set_metadata(addr.clone(), ASSET_ID, name, symbol, decimals)); + assert_ok!(set_metadata(addr.clone(), TOKEN_ID, name, symbol, decimals)); // Asset is not live, i.e. frozen or being destroyed. start_destroy_asset(addr.clone(), asset); assert_eq!( - set_metadata(addr.clone(), ASSET_ID, vec![0], vec![0], 0), + set_metadata(addr.clone(), TOKEN_ID, vec![0], vec![0], 0), Err(Module { index: 52, error: [16, 0] }), ); }); @@ -465,7 +466,7 @@ fn clear_metadata_works() { let asset = create_asset_and_set_metadata(ALICE, 0, vec![0], vec![0], 0); // No Permission. assert_eq!(clear_metadata(addr.clone(), asset), Err(Module { index: 52, error: [2, 0] }),); - let asset = create_asset(addr.clone(), ASSET_ID, 1); + let asset = create_asset(addr.clone(), TOKEN_ID, 1); // Asset is not live, i.e. frozen or being destroyed. freeze_asset(addr.clone(), asset); assert_eq!(clear_metadata(addr.clone(), asset), Err(Module { index: 52, error: [16, 0] }),); @@ -474,28 +475,28 @@ fn clear_metadata_works() { assert_eq!(clear_metadata(addr.clone(), asset), Err(Module { index: 52, error: [3, 0] }),); set_metadata_asset(addr.clone(), asset, name, symbol, decimals); // Clear metadata successfully. - assert_ok!(clear_metadata(addr.clone(), ASSET_ID)); + assert_ok!(clear_metadata(addr.clone(), TOKEN_ID)); // Asset is not live, i.e. frozen or being destroyed. start_destroy_asset(addr.clone(), asset); assert_eq!( - set_metadata(addr.clone(), ASSET_ID, vec![0], vec![0], decimals), + set_metadata(addr.clone(), TOKEN_ID, vec![0], vec![0], decimals), Err(Module { index: 52, error: [16, 0] }), ); }); } #[test] -fn asset_exists_works() { +fn token_exists_works() { new_test_ext().execute_with(|| { let _ = env_logger::try_init(); let addr = instantiate(CONTRACT, INIT_VALUE, vec![]); // No tokens in circulation. - assert_eq!(asset_exists(addr.clone(), ASSET_ID), Ok(Assets::asset_exists(ASSET_ID))); + assert_eq!(token_exists(addr.clone(), TOKEN_ID), Ok(Assets::asset_exists(TOKEN_ID))); // Tokens in circulation. - create_asset(addr.clone(), ASSET_ID, 1); - assert_eq!(asset_exists(addr.clone(), ASSET_ID), Ok(Assets::asset_exists(ASSET_ID))); + create_asset(addr.clone(), TOKEN_ID, 1); + assert_eq!(token_exists(addr.clone(), TOKEN_ID), Ok(Assets::asset_exists(TOKEN_ID))); }); } diff --git a/pop-api/integration-tests/src/fungibles/utils.rs b/pop-api/integration-tests/src/fungibles/utils.rs index 33a25f7a..35761673 100644 --- a/pop-api/integration-tests/src/fungibles/utils.rs +++ b/pop-api/integration-tests/src/fungibles/utils.rs @@ -57,8 +57,8 @@ pub(super) fn token_decimals(addr: AccountId32, asset_id: AssetId) -> Result Result { - let result = do_bare_call("asset_exists", addr, asset_id.encode()); +pub(super) fn token_exists(addr: AccountId32, asset_id: AssetId) -> Result { + let result = do_bare_call("token_exists", addr, asset_id.encode()); decoded::>(result.clone()) .unwrap_or_else(|_| panic!("Contract reverted: {:?}", result)) } diff --git a/pop-api/src/lib.rs b/pop-api/src/lib.rs index cc785c14..0a080c56 100644 --- a/pop-api/src/lib.rs +++ b/pop-api/src/lib.rs @@ -9,8 +9,7 @@ use constants::DECODING_FAILED; use ink::env::chain_extension::{ChainExtensionMethod, FromStatusCode}; -#[cfg(feature = "assets")] -pub use v0::assets; +pub use v0::*; /// Module providing primitives types. pub mod primitives; diff --git a/pop-api/src/v0/assets/mod.rs b/pop-api/src/v0/assets/mod.rs deleted file mode 100644 index 2d5ae236..00000000 --- a/pop-api/src/v0/assets/mod.rs +++ /dev/null @@ -1,3 +0,0 @@ -/// APIs for fungible assets. -#[cfg(feature = "fungibles")] -pub mod fungibles; diff --git a/pop-api/src/v0/assets/fungibles.rs b/pop-api/src/v0/fungibles.rs similarity index 66% rename from pop-api/src/v0/assets/fungibles.rs rename to pop-api/src/v0/fungibles.rs index 56d2f9af..5c9b9a30 100644 --- a/pop-api/src/v0/assets/fungibles.rs +++ b/pop-api/src/v0/fungibles.rs @@ -1,21 +1,22 @@ -//! The `fungibles` module provides an API for interacting and managing fungible assets on Pop Network. +//! The `fungibles` module provides an API for interacting and managing fungible tokens. //! //! The API includes the following interfaces: //! 1. PSP-22 //! 2. PSP-22 Metadata -//! 3. Asset Management +//! 3. Management //! 4. PSP-22 Mintable & Burnable -use crate::{ - constants::{ASSETS, BALANCES, FUNGIBLES}, - primitives::{AccountId, AssetId, Balance}, - Result, StatusCode, -}; use constants::*; use ink::{env::chain_extension::ChainExtensionMethod, prelude::vec::Vec}; pub use management::*; pub use metadata::*; +use crate::{ + constants::{ASSETS, BALANCES, FUNGIBLES}, + primitives::{AccountId, Balance, TokenId}, + Result, StatusCode, +}; + // Helper method to build a dispatch call. // // Parameters: @@ -53,7 +54,7 @@ mod constants { pub(super) const START_DESTROY: u8 = 12; pub(super) const SET_METADATA: u8 = 16; pub(super) const CLEAR_METADATA: u8 = 17; - pub(super) const ASSET_EXISTS: u8 = 18; + pub(super) const TOKEN_EXISTS: u8 = 18; /// 4. PSP-22 Mintable & Burnable interface: pub(super) const MINT: u8 = 19; @@ -66,7 +67,7 @@ mod constants { /// (`Create`, `StartDestroy`, `SetMetadata`, `ClearMetadata`) are provided for convenience. /// /// These events are not emitted by the API itself but can be used in your contracts to -/// track asset operations. Be mindful of the costs associated with emitting events. +/// track token operations. Be mindful of the costs associated with emitting events. /// /// For more details, refer to [ink! events](https://use.ink/basics/events). pub mod events { @@ -75,354 +76,357 @@ pub mod events { /// Event emitted when allowance by `owner` to `spender` changes. #[ink::event] pub struct Approval { - /// Account providing allowance. + /// The owner providing the allowance. #[ink(topic)] pub owner: AccountId, - /// Allowance beneficiary. + /// The beneficiary of the allowance. #[ink(topic)] pub spender: AccountId, - /// New allowance amount. + /// The new allowance amount. pub value: u128, } /// Event emitted when transfer of tokens occurs. #[ink::event] pub struct Transfer { - /// Transfer sender. `None` in case of minting new tokens. + /// The source of the transfer. `None` when minting. #[ink(topic)] pub from: Option, - /// Transfer recipient. `None` in case of burning tokens. + /// The recipient of the transfer. `None` when burning. #[ink(topic)] pub to: Option, - /// Amount of tokens transferred (or minted/burned). + /// The amount transferred (or minted/burned). pub value: u128, } - /// Event emitted when a token class is created. + /// Event emitted when an token is created. #[ink::event] pub struct Create { - /// The ID of the asset. + /// The token identifier. #[ink(topic)] - pub id: AssetId, - /// Creator of the asset. + pub id: TokenId, + /// The creator of the token. #[ink(topic)] pub creator: AccountId, - /// Admin of the asset. + /// The administrator of the token. #[ink(topic)] pub admin: AccountId, } - /// Event emitted when a asset is in the process of being destroyed. + /// Event emitted when a token is in the process of being destroyed. #[ink::event] pub struct StartDestroy { - /// The ID of the asset. + /// The token. #[ink(topic)] - pub id: AssetId, + pub token: TokenId, } - /// Event emitted when new metadata is set for an asset. + /// Event emitted when new metadata is set for a token. #[ink::event] pub struct SetMetadata { - /// The ID of the asset created. + /// The token. #[ink(topic)] - pub id: AssetId, - /// The name of the asset. + pub token: TokenId, + /// The name of the token. #[ink(topic)] pub name: Vec, - /// The symbol of the asset. + /// The symbol of the token. #[ink(topic)] pub symbol: Vec, - /// The decimals of the asset. + /// The decimals of the token. pub decimals: u8, } /// Event emitted when metadata is cleared for a token. #[ink::event] pub struct ClearMetadata { - /// The ID of the asset. + /// The token. #[ink(topic)] - pub id: AssetId, + pub token: TokenId, } } -/// Returns the total token supply for a given asset ID. +/// Returns the total token supply for a specified token. /// /// # Parameters -/// - `id` - The ID of the asset. +/// - `token` - The token. #[inline] -pub fn total_supply(id: AssetId) -> Result { +pub fn total_supply(token: TokenId) -> Result { build_read_state(TOTAL_SUPPLY) - .input::() + .input::() .output::, true>() .handle_error_code::() - .call(&(id)) + .call(&(token)) } -/// Returns the account balance for the specified `owner` for a given asset ID. Returns `0` if +/// Returns the account balance for a specified `token` and `owner`. Returns `0` if /// the account is non-existent. /// /// # Parameters -/// - `id` - The ID of the asset. +/// - `token` - The token. /// - `owner` - The account whose balance is being queried. #[inline] -pub fn balance_of(id: AssetId, owner: AccountId) -> Result { +pub fn balance_of(token: TokenId, owner: AccountId) -> Result { build_read_state(BALANCE_OF) - .input::<(AssetId, AccountId)>() + .input::<(TokenId, AccountId)>() .output::, true>() .handle_error_code::() - .call(&(id, owner)) + .call(&(token, owner)) } -/// Returns the amount which `spender` is still allowed to withdraw from `owner` for a given -/// asset ID. Returns `0` if no allowance has been set. +/// Returns the allowance for a `spender` approved by an `owner`, for a specified `token`. Returns +/// `0` if no allowance has been set. /// /// # Parameters -/// - `id` - The ID of the asset. +/// - `token` - The token. /// - `owner` - The account that owns the tokens. /// - `spender` - The account that is allowed to spend the tokens. #[inline] -pub fn allowance(id: AssetId, owner: AccountId, spender: AccountId) -> Result { +pub fn allowance(token: TokenId, owner: AccountId, spender: AccountId) -> Result { build_read_state(ALLOWANCE) - .input::<(AssetId, AccountId, AccountId)>() + .input::<(TokenId, AccountId, AccountId)>() .output::, true>() .handle_error_code::() - .call(&(id, owner, spender)) + .call(&(token, owner, spender)) } -/// Transfers `value` amount of tokens from the caller's account to account `to`, with additional -/// `data` in unspecified format. +/// Transfers `value` amount of tokens from the caller's account to account `to`. /// /// # Parameters -/// - `id` - The ID of the asset. +/// - `token` - The token to transfer. /// - `to` - The recipient account. /// - `value` - The number of tokens to transfer. #[inline] -pub fn transfer(id: AssetId, to: AccountId, value: Balance) -> Result<()> { +pub fn transfer(token: TokenId, to: AccountId, value: Balance) -> Result<()> { build_dispatch(TRANSFER) - .input::<(AssetId, AccountId, Balance)>() + .input::<(TokenId, AccountId, Balance)>() .output::, true>() .handle_error_code::() - .call(&(id, to, value)) + .call(&(token, to, value)) } -/// Transfers `value` amount tokens on behalf of `from` to account `to` with additional `data` -/// in unspecified format. +/// Transfers `value` amount tokens on behalf of `from` to account `to`. /// /// # Parameters -/// - `id` - The ID of the asset. -/// - `from` - The account from which the tokens are transferred. +/// - `token` - The token to transfer. +/// - `from` - The account from which the token balance will be withdrawn. /// - `to` - The recipient account. /// - `value` - The number of tokens to transfer. #[inline] -pub fn transfer_from(id: AssetId, from: AccountId, to: AccountId, value: Balance) -> Result<()> { +pub fn transfer_from(token: TokenId, from: AccountId, to: AccountId, value: Balance) -> Result<()> { build_dispatch(TRANSFER_FROM) - .input::<(AssetId, AccountId, AccountId, Balance)>() + .input::<(TokenId, AccountId, AccountId, Balance)>() .output::, true>() .handle_error_code::() - .call(&(id, from, to, value)) + .call(&(token, from, to, value)) } -/// Approves an account to spend a specified number of tokens on behalf of the caller. +/// Approves `spender` to spend `value` amount of tokens on behalf of the caller. /// /// # Parameters -/// - `id` - The ID of the asset. +/// - `token` - The token to approve. /// - `spender` - The account that is allowed to spend the tokens. /// - `value` - The number of tokens to approve. #[inline] -pub fn approve(id: AssetId, spender: AccountId, value: Balance) -> Result<()> { +pub fn approve(token: TokenId, spender: AccountId, value: Balance) -> Result<()> { build_dispatch(APPROVE) - .input::<(AssetId, AccountId, Balance)>() + .input::<(TokenId, AccountId, Balance)>() .output::, true>() .handle_error_code::() - .call(&(id, spender, value)) + .call(&(token, spender, value)) } -/// Increases the allowance of a spender. +/// Increases the allowance of `spender` by `value` amount of tokens. /// /// # Parameters -/// - `id` - The ID of the asset. +/// - `token` - The token to have an allowance increased. /// - `spender` - The account that is allowed to spend the tokens. /// - `value` - The number of tokens to increase the allowance by. #[inline] -pub fn increase_allowance(id: AssetId, spender: AccountId, value: Balance) -> Result<()> { +pub fn increase_allowance(token: TokenId, spender: AccountId, value: Balance) -> Result<()> { build_dispatch(INCREASE_ALLOWANCE) - .input::<(AssetId, AccountId, Balance)>() + .input::<(TokenId, AccountId, Balance)>() .output::, true>() .handle_error_code::() - .call(&(id, spender, value)) + .call(&(token, spender, value)) } -/// Decreases the allowance of a spender. +/// Decreases the allowance of `spender` by `value` amount of tokens. /// /// # Parameters -/// - `id` - The ID of the asset. +/// - `token` - The token to have an allowance decreased. /// - `spender` - The account that is allowed to spend the tokens. /// - `value` - The number of tokens to decrease the allowance by. #[inline] -pub fn decrease_allowance(id: AssetId, spender: AccountId, value: Balance) -> Result<()> { +pub fn decrease_allowance(token: TokenId, spender: AccountId, value: Balance) -> Result<()> { build_dispatch(DECREASE_ALLOWANCE) - .input::<(AssetId, AccountId, Balance)>() + .input::<(TokenId, AccountId, Balance)>() .output::, true>() .handle_error_code::() - .call(&(id, spender, value)) + .call(&(token, spender, value)) } -/// Creates `value` amount tokens and assigns them to `account`, increasing the total supply. +/// Creates `value` amount of tokens and assigns them to `account`, increasing the total supply. /// /// # Parameters -/// - `id` - The ID of the asset. +/// - `token` - The token to mint. /// - `account` - The account to be credited with the created tokens. /// - `value` - The number of tokens to mint. #[inline] -pub fn mint(id: AssetId, account: AccountId, value: Balance) -> Result<()> { +pub fn mint(token: TokenId, account: AccountId, value: Balance) -> Result<()> { build_dispatch(MINT) - .input::<(AssetId, AccountId, Balance)>() + .input::<(TokenId, AccountId, Balance)>() .output::, true>() .handle_error_code::() - .call(&(id, account, value)) + .call(&(token, account, value)) } -/// Destroys `value` amount tokens from `account`, reducing the total supply. +/// Destroys `value` amount of tokens from `account`, reducing the total supply. /// /// # Parameters -/// - `id` - The ID of the asset. +/// - `token` - the token to burn. /// - `account` - The account from which the tokens will be destroyed. /// - `value` - The number of tokens to destroy. #[inline] -pub fn burn(id: AssetId, account: AccountId, value: Balance) -> Result<()> { +pub fn burn(token: TokenId, account: AccountId, value: Balance) -> Result<()> { build_dispatch(BURN) - .input::<(AssetId, AccountId, Balance)>() + .input::<(TokenId, AccountId, Balance)>() .output::, true>() .handle_error_code::() - .call(&(id, account, value)) + .call(&(token, account, value)) } /// The PSP-22 Metadata interface for querying metadata. pub mod metadata { use super::*; - /// Returns the token name for a given asset ID. + /// Returns the name of the specified token. /// /// # Parameters - /// - `id` - The ID of the asset. + /// - `token` - The token. #[inline] - pub fn token_name(id: AssetId) -> Result> { + pub fn token_name(token: TokenId) -> Result> { build_read_state(TOKEN_NAME) - .input::() + .input::() .output::>, true>() .handle_error_code::() - .call(&(id)) + .call(&(token)) } - /// Returns the token symbol for a given asset ID. + /// Returns the symbol for the specified token. /// /// # Parameters - /// - `id` - The ID of the asset. + /// - `token` - The token. #[inline] - pub fn token_symbol(id: AssetId) -> Result> { + pub fn token_symbol(token: TokenId) -> Result> { build_read_state(TOKEN_SYMBOL) - .input::() + .input::() .output::>, true>() .handle_error_code::() - .call(&(id)) + .call(&(token)) } - /// Returns the token decimals for a given asset ID. + /// Returns the decimals for the specified token. /// /// # Parameters - /// - `id` - The ID of the asset. + /// - `token` - The token. #[inline] - pub fn token_decimals(id: AssetId) -> Result { + pub fn token_decimals(token: TokenId) -> Result { build_read_state(TOKEN_DECIMALS) - .input::() + .input::() .output::, true>() .handle_error_code::() - .call(&(id)) + .call(&(token)) } } -/// The interface for creating, managing and destroying fungible assets. +/// The interface for creating, managing and destroying fungible tokens. pub mod management { use super::*; - /// Create a new token with a given asset ID. + /// Create a new token with a given identifier. /// /// # Parameters - /// - `id` - The ID of the asset. - /// - `admin` - The account that will administer the asset. - /// - `min_balance` - The minimum balance required for accounts holding this asset. + /// - `id` - The identifier of the token. + /// - `admin` - The account that will administer the token. + /// - `min_balance` - The minimum balance required for accounts holding this token. #[inline] - pub fn create(id: AssetId, admin: AccountId, min_balance: Balance) -> Result<()> { + pub fn create(id: TokenId, admin: AccountId, min_balance: Balance) -> Result<()> { build_dispatch(CREATE) - .input::<(AssetId, AccountId, Balance)>() + .input::<(TokenId, AccountId, Balance)>() .output::, true>() .handle_error_code::() .call(&(id, admin, min_balance)) } - /// Start the process of destroying a token with a given asset ID. + /// Start the process of destroying a token. /// /// # Parameters - /// - `id` - The ID of the asset. + /// - `token` - The token to be destroyed. #[inline] - pub fn start_destroy(id: AssetId) -> Result<()> { + pub fn start_destroy(token: TokenId) -> Result<()> { build_dispatch(START_DESTROY) - .input::() + .input::() .output::, true>() .handle_error_code::() - .call(&(id)) + .call(&(token)) } - /// Set the metadata for a token with a given asset ID. + /// Set the metadata for a token. /// /// # Parameters - /// - `id`: The identifier of the asset to update. - /// - `name`: The user friendly name of this asset. Limited in length by `StringLimit`. - /// - `symbol`: The exchange symbol for this asset. Limited in length by `StringLimit`. - /// - `decimals`: The number of decimals this asset uses to represent one unit. + /// - `token`: The token to update. + /// - `name`: The user friendly name of this token. + /// - `symbol`: The exchange symbol for this token. + /// - `decimals`: The number of decimals this token uses to represent one unit. #[inline] - pub fn set_metadata(id: AssetId, name: Vec, symbol: Vec, decimals: u8) -> Result<()> { + pub fn set_metadata( + token: TokenId, + name: Vec, + symbol: Vec, + decimals: u8, + ) -> Result<()> { build_dispatch(SET_METADATA) - .input::<(AssetId, Vec, Vec, u8)>() + .input::<(TokenId, Vec, Vec, u8)>() .output::, true>() .handle_error_code::() - .call(&(id, name, symbol, decimals)) + .call(&(token, name, symbol, decimals)) } - /// Clear the metadata for a token with a given asset ID. + /// Clear the metadata for a token. /// /// # Parameters - /// - `id` - The ID of the asset. + /// - `token` - The token to update #[inline] - pub fn clear_metadata(id: AssetId) -> Result<()> { + pub fn clear_metadata(token: TokenId) -> Result<()> { build_dispatch(CLEAR_METADATA) - .input::() + .input::() .output::, true>() .handle_error_code::() - .call(&(id)) + .call(&(token)) } - /// Checks if token with a given asset ID exists. + /// Checks if a specified token exists. /// /// # Parameters - /// - `id` - The ID of the asset. + /// - `token` - The token. #[inline] - pub fn asset_exists(id: AssetId) -> Result { - build_read_state(ASSET_EXISTS) - .input::() + pub fn token_exists(token: TokenId) -> Result { + build_read_state(TOKEN_EXISTS) + .input::() .output::, true>() .handle_error_code::() - .call(&(id)) + .call(&(token)) } } -/// Represents various errors related to local fungible assets in the Pop API. +/// Represents various errors related to fungible tokens. /// /// The `FungiblesError` provides a detailed and specific set of error types that can occur when -/// interacting with fungible assets through the Pop API. Each variant signifies a particular error +/// interacting with fungible tokens. Each variant signifies a particular error /// condition, facilitating precise error handling and debugging. /// -/// It is designed to be lightweight, including only the essential errors relevant to fungible asset +/// It is designed to be lightweight, including only the essential errors relevant to fungible token /// operations. The `Other` variant serves as a catch-all for any unexpected errors. For more /// detailed debugging, the `Other` variant can be converted into the richer `Error` type defined in /// the primitives crate. @@ -431,13 +435,13 @@ pub mod management { pub enum FungiblesError { /// An unspecified or unknown error occurred. Other(StatusCode), - /// The asset is not live; either frozen or being destroyed. - AssetNotLive, + /// The token is not live; either frozen or being destroyed. + NotLive, /// Not enough allowance to fulfill a request is available. InsufficientAllowance, /// Not enough balance to fulfill a request is available. InsufficientBalance, - /// The asset ID is already taken. + /// The token ID is already taken. InUse, /// Minimum balance should be non-zero. MinBalanceZero, @@ -445,12 +449,12 @@ pub enum FungiblesError { NoAccount, /// The signing account has no permission to do the operation. NoPermission, - /// The given asset ID is unknown. + /// The given token ID is unknown. Unknown, - /// No balance for creation of assets or fees. + /// No balance for creation of tokens or fees. // TODO: Originally `pallet_balances::Error::InsufficientBalance` but collides with the - // `InsufficientBalance` error that is used for `pallet_assets::Error::BalanceLow` to adhere to - // standard. This deserves a second look. + // `InsufficientBalance` error that is used for `pallet_assets::Error::BalanceLow` to adhere + // to the standard. This deserves a second look. NoBalance, } @@ -472,7 +476,7 @@ impl From for FungiblesError { [_, ASSETS, 3, _] => FungiblesError::InUse, [_, ASSETS, 5, _] => FungiblesError::MinBalanceZero, [_, ASSETS, 7, _] => FungiblesError::InsufficientAllowance, - [_, ASSETS, 10, _] => FungiblesError::AssetNotLive, + [_, ASSETS, 10, _] => FungiblesError::NotLive, _ => FungiblesError::Other(value), } } @@ -578,7 +582,7 @@ mod tests { ); assert_eq!( into_fungibles_error(Module { index: ASSETS, error: [10, 0] }), - FungiblesError::AssetNotLive + FungiblesError::NotLive ); } } diff --git a/pop-api/src/v0/mod.rs b/pop-api/src/v0/mod.rs index 55732e2d..8ed35058 100644 --- a/pop-api/src/v0/mod.rs +++ b/pop-api/src/v0/mod.rs @@ -6,9 +6,9 @@ use crate::{ }; use ink::env::chain_extension::ChainExtensionMethod; -/// APIs for asset-related use cases. -#[cfg(feature = "assets")] -pub mod assets; +/// APIs for fungible tokens. +#[cfg(feature = "fungibles")] +pub mod fungibles; pub(crate) const V0: u8 = 0; diff --git a/primitives/src/lib.rs b/primitives/src/lib.rs index ef6ae3a9..e6942432 100644 --- a/primitives/src/lib.rs +++ b/primitives/src/lib.rs @@ -5,8 +5,8 @@ use codec::{Decode, Encode}; use scale_info::TypeInfo; pub use v0::*; -/// Identifier for the class of asset. -pub type AssetId = u32; +/// The identifier of a token. +pub type TokenId = u32; pub mod v0 { pub use error::*; diff --git a/runtime/devnet/src/config/api/mod.rs b/runtime/devnet/src/config/api/mod.rs index 16ea92fb..6d27fcde 100644 --- a/runtime/devnet/src/config/api/mod.rs +++ b/runtime/devnet/src/config/api/mod.rs @@ -157,7 +157,7 @@ impl Contains for Filter { Allowance { .. } | TokenName(..) | TokenSymbol(..) | TokenDecimals(..) | - AssetExists(..) + TokenExists(..) ) ) } @@ -196,17 +196,17 @@ fn filter_allows_fungibles_calls() { const ACCOUNT: AccountId32 = AccountId32::new([0u8; 32]); const CALLS: [RuntimeCall; 11] = [ - Fungibles(transfer { asset: 0, to: ACCOUNT, value: 0 }), - Fungibles(transfer_from { asset: 0, from: ACCOUNT, to: ACCOUNT, value: 0 }), - Fungibles(approve { asset: 0, spender: ACCOUNT, value: 0 }), - Fungibles(increase_allowance { asset: 0, spender: ACCOUNT, value: 0 }), - Fungibles(decrease_allowance { asset: 0, spender: ACCOUNT, value: 0 }), + Fungibles(transfer { token: 0, to: ACCOUNT, value: 0 }), + Fungibles(transfer_from { token: 0, from: ACCOUNT, to: ACCOUNT, value: 0 }), + Fungibles(approve { token: 0, spender: ACCOUNT, value: 0 }), + Fungibles(increase_allowance { token: 0, spender: ACCOUNT, value: 0 }), + Fungibles(decrease_allowance { token: 0, spender: ACCOUNT, value: 0 }), Fungibles(create { id: 0, admin: ACCOUNT, min_balance: 0 }), - Fungibles(set_metadata { asset: 0, name: vec![], symbol: vec![], decimals: 0 }), - Fungibles(start_destroy { asset: 0 }), - Fungibles(clear_metadata { asset: 0 }), - Fungibles(mint { asset: 0, account: ACCOUNT, value: 0 }), - Fungibles(burn { asset: 0, account: ACCOUNT, value: 0 }), + Fungibles(set_metadata { token: 0, name: vec![], symbol: vec![], decimals: 0 }), + Fungibles(start_destroy { token: 0 }), + Fungibles(clear_metadata { token: 0 }), + Fungibles(mint { token: 0, account: ACCOUNT, value: 0 }), + Fungibles(burn { token: 0, account: ACCOUNT, value: 0 }), ]; for call in CALLS { From 07a07311af26553cdecca0fb159e5b0a8c4dc96b Mon Sep 17 00:00:00 2001 From: chungquantin <56880684+chungquantin@users.noreply.github.com> Date: Wed, 11 Sep 2024 15:40:05 +0700 Subject: [PATCH 056/112] chore: add sandbox crate --- Cargo.toml | 7 +- pop-sandbox/Cargo.toml | 57 ++++++ pop-sandbox/examples/.gitignore | 9 + pop-sandbox/examples/flipper/.gitignore | 9 + pop-sandbox/examples/flipper/Cargo.toml | 27 +++ pop-sandbox/examples/flipper/lib.rs | 167 ++++++++++++++++ pop-sandbox/examples/fungibles/Cargo.toml | 36 ++++ pop-sandbox/examples/fungibles/lib.rs | 57 ++++++ pop-sandbox/examples/proxy/Cargo.toml | 38 ++++ pop-sandbox/examples/proxy/lib.rs | 76 ++++++++ pop-sandbox/src/api/mod.rs | 159 ++++++++++++++++ pop-sandbox/src/api/versioning.rs | 220 ++++++++++++++++++++++ pop-sandbox/src/lib.rs | 158 ++++++++++++++++ 13 files changed, 1019 insertions(+), 1 deletion(-) create mode 100644 pop-sandbox/Cargo.toml create mode 100644 pop-sandbox/examples/.gitignore create mode 100644 pop-sandbox/examples/flipper/.gitignore create mode 100644 pop-sandbox/examples/flipper/Cargo.toml create mode 100644 pop-sandbox/examples/flipper/lib.rs create mode 100644 pop-sandbox/examples/fungibles/Cargo.toml create mode 100644 pop-sandbox/examples/fungibles/lib.rs create mode 100644 pop-sandbox/examples/proxy/Cargo.toml create mode 100644 pop-sandbox/examples/proxy/lib.rs create mode 100644 pop-sandbox/src/api/mod.rs create mode 100644 pop-sandbox/src/api/versioning.rs create mode 100644 pop-sandbox/src/lib.rs diff --git a/Cargo.toml b/Cargo.toml index 0c44755a..5699915b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,7 +15,12 @@ license = "Unlicense" repository = "https://github.com/r0gue-io/pop-node/" [workspace] -exclude = [ "extension/contract", "pop-api", "tests/contracts" ] +exclude = [ + "extension/contract", + "pop-api", + "pop-sandbox", + "tests/contracts", +] members = [ "integration-tests", "node", diff --git a/pop-sandbox/Cargo.toml b/pop-sandbox/Cargo.toml new file mode 100644 index 00000000..6debda40 --- /dev/null +++ b/pop-sandbox/Cargo.toml @@ -0,0 +1,57 @@ +[package] +description = "Sandboxing environment for contract quasi testing with Pop Network runtimes." +edition = "2021" +license = "GPL-3.0-only" +name = "pop-sandbox" +version = "0.0.0" + +[dependencies] +codec = { package = "parity-scale-codec", version = "3", default-features = false, features = [ + "derive", +] } +scale-info = { version = "2.11", default-features = false } + +# Local +drink = { path = "../../pop-drink/drink", default-features = false } +pallet-api = { path = "../pallets/api", default-features = false } +pop-chain-extension = { path = "../extension", default-features = false } +pop-primitives = { path = "../primitives", default-features = false } + +# Substrate +cumulus-primitives-core = { version = "0.14.0", default-features = false } +frame-support = { version = "36.0.0", default-features = false } +frame-system = { version = "36.1.0", default-features = false } +pallet-assets = { version = "37.0.0", default-features = false } +pallet-balances = { version = "37.0.0", default-features = false } +pallet-contracts = { version = "35.0.0", default-features = false } +pallet-timestamp = { version = "35.0.0", default-features = false } +sp-core = { version = "34.0.0", default-features = false } +sp-runtime = { version = "38.0.0", default-features = false } +sp-std = { version = "14.0.0", default-features = false } + +[lib] +crate-type = [ "rlib" ] +name = "pop_sandbox" +path = "src/lib.rs" + +[features] +default = [ "std" ] +std = [ + "codec/std", + "cumulus-primitives-core/std", + "drink/std", + "frame-support/std", + "frame-system/std", + "pallet-api/std", + "pallet-api/std", + "pallet-assets/std", + "pallet-balances/std", + "pallet-contracts/std", + "pallet-timestamp/std", + "pop-chain-extension/std", + "pop-primitives/std", + "scale-info/std", + "sp-core/std", + "sp-runtime/std", + "sp-std/std", +] diff --git a/pop-sandbox/examples/.gitignore b/pop-sandbox/examples/.gitignore new file mode 100644 index 00000000..d60800c8 --- /dev/null +++ b/pop-sandbox/examples/.gitignore @@ -0,0 +1,9 @@ +# Ignore build artifacts from the local tests sub-crate. +**/target/ + +# Ignore backup files creates by cargo fmt. +**/*.rs.bk + +# Remove Cargo.lock when creating an executable, leave it for libraries +# More information here http://doc.crates.io/guide.html#cargotoml-vs-cargolock +**/Cargo.lock diff --git a/pop-sandbox/examples/flipper/.gitignore b/pop-sandbox/examples/flipper/.gitignore new file mode 100644 index 00000000..8de8f877 --- /dev/null +++ b/pop-sandbox/examples/flipper/.gitignore @@ -0,0 +1,9 @@ +# Ignore build artifacts from the local tests sub-crate. +/target/ + +# Ignore backup files creates by cargo fmt. +**/*.rs.bk + +# Remove Cargo.lock when creating an executable, leave it for libraries +# More information here http://doc.crates.io/guide.html#cargotoml-vs-cargolock +Cargo.lock diff --git a/pop-sandbox/examples/flipper/Cargo.toml b/pop-sandbox/examples/flipper/Cargo.toml new file mode 100644 index 00000000..3ce7c90d --- /dev/null +++ b/pop-sandbox/examples/flipper/Cargo.toml @@ -0,0 +1,27 @@ +[package] +name = "api_example_flipper" +edition = "2021" +version = "0.1.0" +authors = ["R0GUE "] + +[dependencies] +ink = { version = "=5.0.0", default-features = false, features = ["ink-debug"] } + +scale = { package = "parity-scale-codec", version = "3", default-features = false, features = [ + "derive", +] } +scale-info = { version = "2.6", default-features = false, features = [ + "derive", +], optional = true } + +[dev-dependencies] +drink = { path = "../../../../pop-drink/drink" } +pop-sandbox = { path = "../../../pop-sandbox", default-features = false } + +[lib] +path = "lib.rs" + +[features] +default = ["std"] +std = ["ink/std", "scale/std", "scale-info/std", "pop-sandbox/std"] +ink-as-dependency = [] diff --git a/pop-sandbox/examples/flipper/lib.rs b/pop-sandbox/examples/flipper/lib.rs new file mode 100644 index 00000000..4efd4edf --- /dev/null +++ b/pop-sandbox/examples/flipper/lib.rs @@ -0,0 +1,167 @@ +#![cfg_attr(not(feature = "std"), no_std, no_main)] + +/// This is the classical flipper contract. It stores a single `bool` value in its storage. The +/// contract exposes: +/// - a constructor (`new`) that initializes the `bool` value to the given value, +/// - a message `flip` that flips the stored `bool` value from `true` to `false` or vice versa, +/// - a getter message `get` that returns the current `bool` value. +/// +/// Additionally, we use the `debug_println` macro from the `ink_env` crate to produce some debug +/// logs from the contract. +#[ink::contract] +mod flipper { + use ink::env::debug_println; + + #[ink(storage)] + pub struct Flipper { + value: bool, + } + + impl Flipper { + #[ink(constructor)] + pub fn new(init: bool) -> Self { + debug_println!("Initializing contract with: `{init}`"); + Self { value: init } + } + + #[ink(message)] + pub fn flip(&mut self) { + debug_println!("Previous value: `{}`", self.value); + self.value = !self.value; + debug_println!("Flipped to: `{}`", self.value); + } + + #[ink(message)] + pub fn get(&self) -> bool { + debug_println!("Reading value from storage"); + self.value + } + } +} + +/// We put `drink`-based tests as usual unit tests, into a test module. +#[cfg(test)] +mod tests { + use drink::{ + sandbox_api::contracts_api::decode_debug_buffer, + session::{Session, NO_ARGS, NO_SALT}, + }; + + /// `drink` automatically discovers all the contract projects that your tests will need. For + /// every such dependency (including the contract from the current crate), it will generate a + /// [`ContractBundle`](drink::session::ContractBundle) object that contains the compiled contract's code + /// and a special transcoder, which is used to encode and decode the contract's message + /// arguments. Such a bundle will be useful when deploying a contract. + /// + /// To get a convenient way for obtaining such bundles, we can define an empty enum and mark + /// it with the [`drink::contract_bundle_provider`](drink::contract_bundle_provider) attribute. + /// From now on, we can use it in all testcases in this module. + #[drink::contract_bundle_provider] + enum BundleProvider {} + + /// Now we write the simplest contract test, that will: + /// 1. Deploy the contract. + /// 2. Call its `flip` method. + /// 3. Call its `get` method and ensure that the stored value has been flipped. + /// + /// We can use the [`drink::test`](drink::test) attribute to mark a function as a `drink` test. + /// This way we ensure that all the required contracts are compiled and built, so that we don't + /// have to run `cargo contract build` manually for every contract dependency. + /// + /// For convenience of using `?` operator, we mark the test function as returning a `Result`. + /// + /// `drink::test` will already provide us with a `Session` object. It is a wrapper around a runtime and it exposes + /// a broad API for interacting with it. Session is generic over the runtime type, but usually and by default, we + /// use `MinimalSandbox`, which is a minimalistic runtime that allows using smart contracts. + #[drink::test(sandbox = pop_sandbox::PopSandbox)] + fn deploy_and_call_a_contract(mut session: Session) -> Result<(), Box> { + // Now we get the contract bundle from the `BundleProvider` enum. Since the current crate + // comes with a contract, we can use the `local` method to get the bundle for it. + let contract_bundle = BundleProvider::local()?; + + // We can now deploy the contract. + let _contract_address = session.deploy_bundle( + // The bundle that we want to deploy. + contract_bundle, + // The constructor that we want to call. + "new", + // The constructor arguments (as stringish objects). + &["true"], + // Salt for the contract address derivation. + NO_SALT, + // Initial endowment (the amount of tokens that we want to transfer to the contract). + None, + )?; + + // Once the contract is instantiated, we can call the `flip` method on the contract. + session.call( + // The message that we want to call. + "flip", + // The message arguments (as stringish objects). If none, then we can use the `NO_ARGS` + // constant, which spares us from typing `&[]`. + NO_ARGS, + // Endowment (the amount of tokens that we want to transfer to the contract). + None, + )??; + + // Finally, we can call the `get` method on the contract and ensure that the value has been + // flipped. + // + // `Session::call` returns a `Result, SessionError>`, where `T` is the + // type of the message result. In this case, the `get` message returns a `bool`, and we have + // to explicitly hint the compiler about it. + let result: bool = session.call("get", NO_ARGS, None)??; + assert_eq!(result, false); + + Ok(()) + } + + /// In this testcase we will see how to get and read debug logs from the contract. + #[drink::test(sandbox = pop_sandbox::PopSandbox)] + fn get_debug_logs(mut session: Session) -> Result<(), Box> { + session.deploy_bundle(BundleProvider::local()?, "new", &["true"], NO_SALT, None)?; + + // `deploy_bundle` returns just a contract address. If we are interested in more details + // about last operation (either deploy or call), we can get a `Record` object and use its + // `last_deploy_result` (or analogously `last_call_result`) method, which will provide us + // with a full report from the last contract interaction. + // + // In particular, we can get the decoded debug buffer from the contract. The buffer is + // just a vector of bytes, which we can decode using the `decode_debug_buffer` function. + let decoded_buffer = &session.record().last_deploy_result().debug_message; + let encoded_buffer = decode_debug_buffer(decoded_buffer); + + assert_eq!(encoded_buffer, vec!["Initializing contract with: `true`"]); + + Ok(()) + } + + /// In this testcase we will see how to work with multiple contracts. + #[drink::test(sandbox = pop_sandbox::PopSandbox)] + fn work_with_multiple_contracts( + mut session: Session, + ) -> Result<(), Box> { + let bundle = BundleProvider::local()?; + + // We can deploy the same contract multiple times. However, we have to ensure that the + // derived contract addresses are different. We can do this by providing using different + // arguments for the constructor or by providing a different salt. + let first_address = + session.deploy_bundle(bundle.clone(), "new", &["true"], NO_SALT, None)?; + let _second_address = + session.deploy_bundle(bundle.clone(), "new", &["true"], vec![0], None)?; + let _third_address = session.deploy_bundle(bundle, "new", &["false"], NO_SALT, None)?; + + // By default, when we run `session.call`, `drink` will interact with the last deployed + // contract. + let value_at_third_contract: bool = session.call("get", NO_ARGS, None)??; + assert_eq!(value_at_third_contract, false); + + // However, we can also call a specific contract by providing its address. + let value_at_first_contract: bool = + session.call_with_address(first_address, "get", NO_ARGS, None)??; + assert_eq!(value_at_first_contract, true); + + Ok(()) + } +} diff --git a/pop-sandbox/examples/fungibles/Cargo.toml b/pop-sandbox/examples/fungibles/Cargo.toml new file mode 100644 index 00000000..326a1755 --- /dev/null +++ b/pop-sandbox/examples/fungibles/Cargo.toml @@ -0,0 +1,36 @@ +[package] +name = "api_example_fungibles" +version = "0.1.0" +authors = ["[your_name] <[your_email]>"] +edition = "2021" + +[dependencies] +ink = { version = "=5.0.0", default-features = false, features = ["ink-debug"] } +pop-api = { path = "../../../pop-api", default-features = false, features = [ + "fungibles", +] } +scale = { package = "parity-scale-codec", version = "3", default-features = false, features = [ + "derive", +] } +scale-info = { version = "2.6", default-features = false, features = [ + "derive", +], optional = true } + +[dev-dependencies] +drink = { path = "../../../../pop-drink/drink" } +pop-sandbox = { path = "../../../pop-sandbox", default-features = false } + +[lib] +path = "lib.rs" + +[features] +default = ["std"] +e2e-tests = [] +ink-as-dependency = [] +std = [ + "ink/std", + "pop-api/std", + "pop-sandbox/std", + "scale/std", + "scale-info/std", +] diff --git a/pop-sandbox/examples/fungibles/lib.rs b/pop-sandbox/examples/fungibles/lib.rs new file mode 100644 index 00000000..59d0ea7e --- /dev/null +++ b/pop-sandbox/examples/fungibles/lib.rs @@ -0,0 +1,57 @@ +#![cfg_attr(not(feature = "std"), no_std, no_main)] + +#[ink::contract] +mod create_token_in_constructor { + use pop_api::{ + primitives::AssetId, + v0::assets::fungibles::{self as api}, + StatusCode, + }; + + pub type Result = core::result::Result; + + #[ink(storage)] + pub struct Fungible { + id: AssetId, + } + + impl Fungible { + #[ink(constructor)] + pub fn new(id: AssetId, min_balance: Balance) -> Result { + ink::env::debug_println!("Fungible::call() asset_id={id}, min_balance={min_balance}"); + let contract = Self { id }; + // AccountId of the contract which will be set to the owner of the fungible token. + let owner = contract.env().account_id(); + // TODO: Calling POP API caused DeploymentReverted + api::create(id, owner, min_balance)?; + Ok(contract) + } + + #[ink(message)] + pub fn asset_exists(&self) -> Result { + api::asset_exists(self.id) + } + } +} + +/// We put `drink`-based tests as usual unit tests, into a test module. +#[cfg(test)] +mod tests { + use drink::session::{Session, NO_ARGS, NO_SALT}; + + #[drink::contract_bundle_provider] + enum BundleProvider {} + + #[drink::test(sandbox = pop_sandbox::PopSandbox)] + fn deploy_and_call_a_contract(mut session: Session) -> Result<(), Box> { + let contract_bundle = BundleProvider::local()?; + let _contract_address = session.deploy_bundle( + contract_bundle, + "new", + &[1.to_string(), 1_000.to_string()], + NO_SALT, + None, + )?; + Ok(()) + } +} diff --git a/pop-sandbox/examples/proxy/Cargo.toml b/pop-sandbox/examples/proxy/Cargo.toml new file mode 100644 index 00000000..918de444 --- /dev/null +++ b/pop-sandbox/examples/proxy/Cargo.toml @@ -0,0 +1,38 @@ +[package] +name = "api_example_proxy" +version = "0.1.0" +authors = ["[your_name] <[your_email]>"] +edition = "2021" + +[dependencies] +ink = { version = "=5.0.0", default-features = false, features = ["ink-debug"] } +pop-api = { path = "../../../pop-api", default-features = false, features = [ + "fungibles", +] } +codec = { package = "parity-scale-codec", version = "3", default-features = false, features = [ + "derive", +] } +scale-info = { version = "2.6", default-features = false, features = [ + "derive", +], optional = true } +frame-system = { version = "29.0.0", default-features = false } + +[dev-dependencies] +drink = { path = "../../../../pop-drink/drink" } +pop-sandbox = { path = "../../../pop-sandbox", default-features = false } + +[lib] +path = "lib.rs" + +[features] +default = ["std"] +e2e-tests = [] +ink-as-dependency = [] +std = [ + "ink/std", + "pop-api/std", + "pop-sandbox/std", + "frame-system/std", + "codec/std", + "scale-info/std", +] diff --git a/pop-sandbox/examples/proxy/lib.rs b/pop-sandbox/examples/proxy/lib.rs new file mode 100644 index 00000000..b0116301 --- /dev/null +++ b/pop-sandbox/examples/proxy/lib.rs @@ -0,0 +1,76 @@ +#![cfg_attr(not(feature = "std"), no_std, no_main)] + +use ink::{ + env::chain_extension::{ChainExtensionMethod, FromStatusCode}, + prelude::vec::Vec, +}; + +#[ink::contract] +mod proxy_contract { + use super::*; + + // Simple contract for proxying a call to a chain extension. + #[ink(storage)] + #[derive(Default)] + pub struct Proxy; + + impl Proxy { + #[ink(constructor)] + pub fn new() -> Self { + ink::env::debug_println!("Proxy::new()"); + Default::default() + } + + #[ink(message)] + pub fn call(&self, func_id: u32, input: Vec) -> Result, StatusCode> { + ink::env::debug_println!("Proxy::call() func_id={func_id}, input={input:?}"); + ChainExtensionMethod::build(func_id) + .input::>() + .output::, StatusCode>, true>() + .handle_error_code::() + .call(&input) + } + } + + #[ink::scale_derive(Encode, Decode, TypeInfo)] + pub struct StatusCode(u32); + impl FromStatusCode for StatusCode { + fn from_status_code(status_code: u32) -> Result<(), Self> { + match status_code { + 0 => Ok(()), + _ => Err(StatusCode(status_code)), + } + } + } + + impl From for StatusCode { + fn from(_: ink::scale::Error) -> Self { + StatusCode(u32::MAX) + } + } +} + +/// We put `drink`-based tests as usual unit tests, into a test module. +#[cfg(test)] +mod tests { + use codec::Encode; + use core::fmt::Debug; + use drink::session::{Session, NO_ARGS, NO_SALT}; + + #[drink::contract_bundle_provider] + enum BundleProvider {} + + #[drink::test(sandbox = pop_sandbox::PopSandbox)] + fn deploy_contract_and_call(mut session: Session) -> Result<(), Box> { + let contract_bundle = BundleProvider::local()?; + let contract_address = + session.deploy_bundle(contract_bundle, "new", NO_ARGS, NO_SALT, None)?; + + let input : Vec = vec![0, 7, 112, 111, 112].encode(); + let converted_input : Vec = input.into_iter().map(|b| b.to_string()).collect::>(); + // DispatchCall::RuntimeSystem::Remark + session.call_with_address(contract_address, "call", &[vec![0u32.to_string()], converted_input].concat(), None)??; + + Ok(()) + } +} diff --git a/pop-sandbox/src/api/mod.rs b/pop-sandbox/src/api/mod.rs new file mode 100644 index 00000000..ad4f8491 --- /dev/null +++ b/pop-sandbox/src/api/mod.rs @@ -0,0 +1,159 @@ +use core::marker::PhantomData; + +use codec::Decode; +use cumulus_primitives_core::Weight; +use frame_support::traits::Contains; +pub(crate) use pallet_api::Extension; +use pallet_api::{extension::*, Read}; +use sp_core::ConstU8; +use sp_runtime::DispatchError; +use sp_std::vec::Vec; +use versioning::*; + +use crate::{fungibles, Runtime, RuntimeCall, RuntimeEvent}; + +mod versioning; + +type DecodingFailedError = DecodingFailed; +type DecodesAs = pallet_api::extension::DecodesAs< + Output, + ContractWeightsOf, + DecodingFailedError, + Logger, +>; + +/// A query of runtime state. +#[derive(Decode, Debug)] +#[repr(u8)] +pub enum RuntimeRead { + /// Fungible token queries. + #[codec(index = 150)] + Fungibles(fungibles::Read), +} + +impl Readable for RuntimeRead { + /// The corresponding type carrying the result of the query for runtime state. + type Result = RuntimeResult; + + /// Determines the weight of the read, used to charge the appropriate weight before the read is + /// performed. + fn weight(&self) -> Weight { + match self { + RuntimeRead::Fungibles(key) => fungibles::Pallet::weight(key), + } + } + + /// Performs the read and returns the result. + fn read(self) -> Self::Result { + match self { + RuntimeRead::Fungibles(key) => RuntimeResult::Fungibles(fungibles::Pallet::read(key)), + } + } +} + +/// The result of a runtime state read. +#[derive(Debug)] +pub enum RuntimeResult { + /// Fungible token read results. + Fungibles(fungibles::ReadResult), +} + +impl RuntimeResult { + /// Encodes the result. + fn encode(&self) -> Vec { + match self { + RuntimeResult::Fungibles(result) => result.encode(), + } + } +} + +impl fungibles::Config for Runtime { + type AssetsInstance = (); + type RuntimeEvent = RuntimeEvent; + type WeightInfo = fungibles::weights::SubstrateWeight; +} + +#[derive(Default)] +pub struct Config; +impl pallet_api::extension::Config for Config { + /// Functions used by the Pop API. + /// + /// Each function corresponds to specific functionality provided by the API, facilitating the + /// interaction between smart contracts and the runtime. + type Functions = ( + // Dispatching calls + DispatchCall< + // Function ID: 0. + IdentifiedByFirstByteOfFunctionId>, + // The runtime configuration. + Runtime, + // Decode as a versioned runtime call. + DecodesAs, + // Apply any filtering. + Filter, + // Ensure errors are versioned. + VersionedErrorConverter, + // Logging with a specific target. + DispatchCallLogTarget, + >, + // Reading state + ReadState< + // Function ID: 1. + IdentifiedByFirstByteOfFunctionId>, + // The runtime configuration. + Runtime, + // The runtime state reads available. + RuntimeRead, + // Decode as a versioned runtime read. + DecodesAs, + // Apply any filtering. + Filter, + // Convert the result of a read into the expected versioned result + VersionedResultConverter, + // Ensure errors are versioned. + VersionedErrorConverter, + // Logging with a specific target. + ReadStateLogTarget, + >, + ); + + /// The log target. + const LOG_TARGET: &'static str = LOG_TARGET; +} + +/// Filters used by the chain extension. +pub struct Filter(PhantomData); + +impl> Contains for Filter { + fn contains(c: &RuntimeCall) -> bool { + use fungibles::Call::*; + T::BaseCallFilter::contains(c) + && matches!( + c, + RuntimeCall::Fungibles( + transfer { .. } + | transfer_from { .. } | approve { .. } + | increase_allowance { .. } + | decrease_allowance { .. } + | create { .. } | set_metadata { .. } + | start_destroy { .. } | clear_metadata { .. } + | mint { .. } | burn { .. } + ) + ) + } +} + +impl Contains for Filter { + fn contains(r: &RuntimeRead) -> bool { + use fungibles::Read::*; + matches!( + r, + RuntimeRead::Fungibles( + TotalSupply(..) + | BalanceOf { .. } | Allowance { .. } + | TokenName(..) | TokenSymbol(..) + | TokenDecimals(..) | TokenExists(..) + ) + ) + } +} diff --git a/pop-sandbox/src/api/versioning.rs b/pop-sandbox/src/api/versioning.rs new file mode 100644 index 00000000..317496df --- /dev/null +++ b/pop-sandbox/src/api/versioning.rs @@ -0,0 +1,220 @@ +use sp_runtime::ModuleError; + +use super::*; + +type Version = u8; + +/// Versioned runtime calls. +#[derive(Decode, Debug)] +pub enum VersionedRuntimeCall { + /// Version zero of runtime calls. + #[codec(index = 0)] + V0(RuntimeCall), +} + +impl From for RuntimeCall { + fn from(value: VersionedRuntimeCall) -> Self { + // Allows mapping from some previous runtime call shape to a current valid runtime call + match value { + VersionedRuntimeCall::V0(call) => call, + } + } +} + +/// Versioned runtime state reads. +#[derive(Decode, Debug)] +pub enum VersionedRuntimeRead { + /// Version zero of runtime state reads. + #[codec(index = 0)] + V0(RuntimeRead), +} + +impl From for RuntimeRead { + fn from(value: VersionedRuntimeRead) -> Self { + // Allows mapping from some previous runtime read shape to a current valid runtime read + match value { + VersionedRuntimeRead::V0(read) => read, + } + } +} + +/// Versioned runtime state read results. +#[derive(Debug)] +pub enum VersionedRuntimeResult { + /// Version zero of runtime read results. + V0(RuntimeResult), +} + +impl From<(RuntimeResult, Version)> for VersionedRuntimeResult { + fn from(value: (RuntimeResult, Version)) -> Self { + let (result, version) = value; + match version { + // Allows mapping from current `RuntimeResult` to a specific/prior version + 0 => VersionedRuntimeResult::V0(result), + // TODO: should never occur due to version processing/validation when request received + _ => unimplemented!(), + } + } +} + +impl From for Vec { + fn from(result: VersionedRuntimeResult) -> Self { + match result { + // Simply unwrap and return the encoded result + VersionedRuntimeResult::V0(result) => result.encode(), + } + } +} + +/// Versioned errors. +#[derive(Debug)] +pub enum VersionedError { + /// Version zero of errors. + V0(pop_primitives::v0::Error), +} + +impl From<(DispatchError, Version)> for VersionedError { + fn from(value: (DispatchError, Version)) -> Self { + let (error, version) = value; + match version { + // Allows mapping from current `DispatchError` to a specific/prior version of `Error` + 0 => VersionedError::V0(V0Error::from(error).0), + // TODO: should never occur due to version processing/validation when request received + _ => unimplemented!(), + } + } +} + +impl From for u32 { + fn from(value: VersionedError) -> Self { + match value { + VersionedError::V0(error) => error.into(), + } + } +} + +struct V0Error(pop_primitives::v0::Error); +impl From for V0Error { + fn from(error: DispatchError) -> Self { + use pop_primitives::v0::*; + use sp_runtime::{ArithmeticError::*, TokenError::*, TransactionalError::*}; + use DispatchError::*; + // Mappings exist here to avoid taking a dependency of sp_runtime on pop-primitives + Self(match error { + Other(_message) => { + // Note: lossy conversion: message not used due to returned contract status code + // size limitation + Error::Other + }, + CannotLookup => Error::CannotLookup, + BadOrigin => Error::BadOrigin, + Module(error) => { + // Note: message not used + let ModuleError { index, error, message: _message } = error; + // Map `pallet-contracts::Error::DecodingFailed` to `Error::DecodingFailed` + if index as usize == + ::index() && + error == DECODING_FAILED_ERROR + { + Error::DecodingFailed + } else { + // Note: lossy conversion of error value due to returned contract status code + // size limitation + Error::Module { index, error: [error[0], error[1]] } + } + }, + ConsumerRemaining => Error::ConsumerRemaining, + NoProviders => Error::NoProviders, + TooManyConsumers => Error::TooManyConsumers, + Token(error) => Error::Token(match error { + FundsUnavailable => TokenError::FundsUnavailable, + OnlyProvider => TokenError::OnlyProvider, + BelowMinimum => TokenError::BelowMinimum, + CannotCreate => TokenError::CannotCreate, + UnknownAsset => TokenError::UnknownAsset, + Frozen => TokenError::Frozen, + Unsupported => TokenError::Unsupported, + CannotCreateHold => TokenError::CannotCreateHold, + NotExpendable => TokenError::NotExpendable, + Blocked => TokenError::Blocked, + }), + Arithmetic(error) => Error::Arithmetic(match error { + Underflow => ArithmeticError::Underflow, + Overflow => ArithmeticError::Overflow, + DivisionByZero => ArithmeticError::DivisionByZero, + }), + Transactional(error) => Error::Transactional(match error { + LimitReached => TransactionalError::LimitReached, + NoLayer => TransactionalError::NoLayer, + }), + Exhausted => Error::Exhausted, + Corruption => Error::Corruption, + Unavailable => Error::Unavailable, + RootNotAllowed => Error::RootNotAllowed, + }) + } +} + +#[cfg(test)] +mod tests { + use pop_primitives::{ArithmeticError::*, Error, TokenError::*, TransactionalError::*}; + use sp_runtime::ModuleError; + use DispatchError::*; + + use super::*; + + // Compare all the different `DispatchError` variants with the expected `Error`. + #[test] + fn dispatch_error_to_error() { + let test_cases = vec![ + (Other(""), (Error::Other)), + (Other("UnknownCall"), Error::Other), + (Other("DecodingFailed"), Error::Other), + (Other("Random"), (Error::Other)), + (CannotLookup, Error::CannotLookup), + (BadOrigin, Error::BadOrigin), + ( + Module(ModuleError { index: 1, error: [2, 0, 0, 0], message: Some("hallo") }), + Error::Module { index: 1, error: [2, 0] }, + ), + ( + Module(ModuleError { index: 1, error: [2, 2, 0, 0], message: Some("hallo") }), + Error::Module { index: 1, error: [2, 2] }, + ), + ( + Module(ModuleError { index: 1, error: [2, 2, 2, 0], message: Some("hallo") }), + Error::Module { index: 1, error: [2, 2] }, + ), + ( + Module(ModuleError { index: 1, error: [2, 2, 2, 4], message: Some("hallo") }), + Error::Module { index: 1, error: [2, 2] }, + ), + (pallet_contracts::Error::::DecodingFailed.into(), Error::DecodingFailed), + (ConsumerRemaining, Error::ConsumerRemaining), + (NoProviders, Error::NoProviders), + (TooManyConsumers, Error::TooManyConsumers), + (Token(sp_runtime::TokenError::BelowMinimum), Error::Token(BelowMinimum)), + (Arithmetic(sp_runtime::ArithmeticError::Overflow), Error::Arithmetic(Overflow)), + ( + Transactional(sp_runtime::TransactionalError::LimitReached), + Error::Transactional(LimitReached), + ), + (Exhausted, Error::Exhausted), + (Corruption, Error::Corruption), + (Unavailable, Error::Unavailable), + (RootNotAllowed, Error::RootNotAllowed), + ]; + for (dispatch_error, expected) in test_cases { + let error = V0Error::from(dispatch_error).0; + assert_eq!(error, expected); + } + } + + #[test] + fn decoding_failed_error_encoding_works() { + let Module(error) = pallet_contracts::Error::::DecodingFailed.into() else { + unreachable!() + }; + assert_eq!(error.error, DECODING_FAILED_ERROR) + } +} diff --git a/pop-sandbox/src/lib.rs b/pop-sandbox/src/lib.rs new file mode 100644 index 00000000..f2abacd3 --- /dev/null +++ b/pop-sandbox/src/lib.rs @@ -0,0 +1,158 @@ +use crate::api::Config; +use frame_support::{ + construct_runtime, derive_impl, parameter_types, + sp_runtime::{testing::H256, Perbill}, + traits::{AsEnsureOriginWithArg, ConstBool, ConstU128, ConstU32, Randomness}, + weights::Weight, +}; +use frame_system::{EnsureRoot, EnsureSigned}; +use pallet_api::fungibles; +use pallet_contracts::{DefaultAddressGenerator, Frame, Schedule}; +use sp_runtime::traits::{AccountIdLookup, Convert}; +use sp_std::vec::Vec; + +mod api; + +pub(crate) type AccountId = AccountId32; +pub(crate) type AssetId = u32; +pub(crate) type Balance = u128; + +// Define the runtime type as a collection of pallets +construct_runtime!( + pub enum Runtime { + System: frame_system, + Assets: pallet_assets, + Balances: pallet_balances, + Timestamp: pallet_timestamp, + Contracts: pallet_contracts, + Fungibles: fungibles = 150, + } +); + +parameter_types! { + pub const BlockHashCount: u64 = 250; + pub const SS58Prefix: u8 = 42; +} + +#[derive_impl(frame_system::config_preludes::TestDefaultConfig as frame_system::DefaultConfig)] +impl frame_system::Config for Runtime { + type AccountData = pallet_balances::AccountData<::Balance>; + type AccountId = AccountId; + type Block = frame_system::mocking::MockBlock; + type Lookup = AccountIdLookup; +} + +#[derive_impl(pallet_balances::config_preludes::TestDefaultConfig as pallet_balances::DefaultConfig)] +impl pallet_balances::Config for Runtime { + type AccountStore = System; + type Balance = Balance; + type ExistentialDeposit = ConstU128<1>; + type ReserveIdentifier = [u8; 8]; +} + +parameter_types! { + pub const AssetDeposit: u128 = 1; + pub const AssetAccountDeposit: u128 = 10; + pub const ApprovalDeposit: u128 = 1; + pub const AssetsStringLimit: u32 = 50; + pub const MetadataDepositBase: u128 = 1; + pub const MetadataDepositPerByte: u128 = 1; +} + +impl pallet_assets::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type Balance = Balance; + type RemoveItemsLimit = ConstU32<5>; + type AssetId = AssetId; + type AssetIdParameter = u32; + type Currency = Balances; + type CreateOrigin = AsEnsureOriginWithArg>; + type ForceOrigin = EnsureRoot; + type AssetDeposit = ConstU128<1>; + type AssetAccountDeposit = ConstU128<10>; + type MetadataDepositBase = ConstU128<1>; + type MetadataDepositPerByte = ConstU128<1>; + type ApprovalDeposit = ConstU128<1>; + type StringLimit = ConstU32<50>; + type Freezer = (); + type Extra = (); + type CallbackHandle = (); + type WeightInfo = (); + #[cfg(feature = "runtime-benchmarks")] + type BenchmarkHelper = (); +} + +#[derive_impl(pallet_timestamp::config_preludes::TestDefaultConfig as pallet_timestamp::DefaultConfig)] +impl pallet_timestamp::Config for Runtime {} + +// Configure pallet contracts +impl Randomness for Runtime { + fn random(_subject: &[u8]) -> (H256, u64) { + (Default::default(), Default::default()) + } +} + +// Configure pallet contracts +pub enum SandboxRandomness {} +impl Randomness for SandboxRandomness { + fn random(_subject: &[u8]) -> (H256, u64) { + unreachable!("No randomness") + } +} + +type BalanceOf = ::Balance; +impl Convert for Runtime { + fn convert(w: Weight) -> BalanceOf { + w.ref_time().into() + } +} + +parameter_types! { + pub SandboxSchedule: Schedule = { + let schedule = >::default(); + schedule + }; + pub DeletionWeightLimit: Weight = Weight::zero(); + pub DefaultDepositLimit: BalanceOf = 10_000_000; + pub CodeHashLockupDepositPercent: Perbill = Perbill::from_percent(0); + pub MaxDelegateDependencies: u32 = 32; +} + +impl pallet_contracts::Config for Runtime { + type AddressGenerator = DefaultAddressGenerator; + type ApiVersion = (); + type CallFilter = (); + // TestFilter; + type CallStack = [Frame; 5]; + type ChainExtension = api::Extension; + type CodeHashLockupDepositPercent = CodeHashLockupDepositPercent; + type Currency = Balances; + type Debug = drink::pallet_contracts_debugging::DrinkDebug; + // TestDebug; + type DefaultDepositLimit = DefaultDepositLimit; + type DepositPerByte = ConstU128<1>; + type DepositPerItem = ConstU128<1>; + type Environment = (); + type InstantiateOrigin = EnsureSigned; + type MaxCodeLen = ConstU32<{ 123 * 1024 }>; + type MaxDebugBufferLen = ConstU32<{ 2 * 1024 * 1024 }>; + type MaxDelegateDependencies = MaxDelegateDependencies; + type MaxStorageKeyLen = ConstU32<128>; + type Migrations = (); + // crate::migration::codegen::BenchMigrations; + type Randomness = SandboxRandomness; + type RuntimeCall = RuntimeCall; + type RuntimeEvent = RuntimeEvent; + type RuntimeHoldReason = RuntimeHoldReason; + type Schedule = SandboxSchedule; + type Time = Timestamp; + type UnsafeUnstableInterface = ConstBool; + // UnstableInterface; + type UploadOrigin = EnsureSigned; + type WeightInfo = (); + type WeightPrice = Self; + // Self; + type Xcm = (); +} + +drink::create_sandbox!(PopSandbox, Runtime); From 7f04779a0cac28dfa82a182c35c3b7c425883a97 Mon Sep 17 00:00:00 2001 From: chungquantin <56880684+chungquantin@users.noreply.github.com> Date: Wed, 11 Sep 2024 15:49:29 +0700 Subject: [PATCH 057/112] fix: taplo formatting --- pop-sandbox/examples/flipper/Cargo.toml | 16 +++++----- pop-sandbox/examples/fungibles/Cargo.toml | 28 +++++++++--------- pop-sandbox/examples/proxy/Cargo.toml | 36 +++++++++++------------ 3 files changed, 40 insertions(+), 40 deletions(-) diff --git a/pop-sandbox/examples/flipper/Cargo.toml b/pop-sandbox/examples/flipper/Cargo.toml index 3ce7c90d..c0694808 100644 --- a/pop-sandbox/examples/flipper/Cargo.toml +++ b/pop-sandbox/examples/flipper/Cargo.toml @@ -1,17 +1,17 @@ [package] -name = "api_example_flipper" +authors = [ "R0GUE " ] edition = "2021" +name = "api_example_flipper" version = "0.1.0" -authors = ["R0GUE "] [dependencies] -ink = { version = "=5.0.0", default-features = false, features = ["ink-debug"] } +ink = { version = "=5.0.0", default-features = false, features = [ "ink-debug" ] } scale = { package = "parity-scale-codec", version = "3", default-features = false, features = [ - "derive", + "derive", ] } scale-info = { version = "2.6", default-features = false, features = [ - "derive", + "derive", ], optional = true } [dev-dependencies] @@ -22,6 +22,6 @@ pop-sandbox = { path = "../../../pop-sandbox", default-features = false } path = "lib.rs" [features] -default = ["std"] -std = ["ink/std", "scale/std", "scale-info/std", "pop-sandbox/std"] -ink-as-dependency = [] +default = [ "std" ] +ink-as-dependency = [ ] +std = [ "ink/std", "pop-sandbox/std", "scale-info/std", "scale/std" ] diff --git a/pop-sandbox/examples/fungibles/Cargo.toml b/pop-sandbox/examples/fungibles/Cargo.toml index 326a1755..f151f376 100644 --- a/pop-sandbox/examples/fungibles/Cargo.toml +++ b/pop-sandbox/examples/fungibles/Cargo.toml @@ -1,19 +1,19 @@ [package] +authors = [ "[your_name] <[your_email]>" ] +edition = "2021" name = "api_example_fungibles" version = "0.1.0" -authors = ["[your_name] <[your_email]>"] -edition = "2021" [dependencies] -ink = { version = "=5.0.0", default-features = false, features = ["ink-debug"] } +ink = { version = "=5.0.0", default-features = false, features = [ "ink-debug" ] } pop-api = { path = "../../../pop-api", default-features = false, features = [ - "fungibles", + "fungibles", ] } scale = { package = "parity-scale-codec", version = "3", default-features = false, features = [ - "derive", + "derive", ] } scale-info = { version = "2.6", default-features = false, features = [ - "derive", + "derive", ], optional = true } [dev-dependencies] @@ -24,13 +24,13 @@ pop-sandbox = { path = "../../../pop-sandbox", default-features = false } path = "lib.rs" [features] -default = ["std"] -e2e-tests = [] -ink-as-dependency = [] +default = [ "std" ] +e2e-tests = [ ] +ink-as-dependency = [ ] std = [ - "ink/std", - "pop-api/std", - "pop-sandbox/std", - "scale/std", - "scale-info/std", + "ink/std", + "pop-api/std", + "pop-sandbox/std", + "scale-info/std", + "scale/std", ] diff --git a/pop-sandbox/examples/proxy/Cargo.toml b/pop-sandbox/examples/proxy/Cargo.toml index 918de444..0dd7b249 100644 --- a/pop-sandbox/examples/proxy/Cargo.toml +++ b/pop-sandbox/examples/proxy/Cargo.toml @@ -1,21 +1,21 @@ [package] +authors = [ "[your_name] <[your_email]>" ] +edition = "2021" name = "api_example_proxy" version = "0.1.0" -authors = ["[your_name] <[your_email]>"] -edition = "2021" [dependencies] -ink = { version = "=5.0.0", default-features = false, features = ["ink-debug"] } -pop-api = { path = "../../../pop-api", default-features = false, features = [ - "fungibles", -] } codec = { package = "parity-scale-codec", version = "3", default-features = false, features = [ - "derive", + "derive", +] } +frame-system = { version = "29.0.0", default-features = false } +ink = { version = "=5.0.0", default-features = false, features = [ "ink-debug" ] } +pop-api = { path = "../../../pop-api", default-features = false, features = [ + "fungibles", ] } scale-info = { version = "2.6", default-features = false, features = [ - "derive", + "derive", ], optional = true } -frame-system = { version = "29.0.0", default-features = false } [dev-dependencies] drink = { path = "../../../../pop-drink/drink" } @@ -25,14 +25,14 @@ pop-sandbox = { path = "../../../pop-sandbox", default-features = false } path = "lib.rs" [features] -default = ["std"] -e2e-tests = [] -ink-as-dependency = [] +default = [ "std" ] +e2e-tests = [ ] +ink-as-dependency = [ ] std = [ - "ink/std", - "pop-api/std", - "pop-sandbox/std", - "frame-system/std", - "codec/std", - "scale-info/std", + "codec/std", + "frame-system/std", + "ink/std", + "pop-api/std", + "pop-sandbox/std", + "scale-info/std", ] From 8a1095bb71df44d0a26b6d05355772ad205abb08 Mon Sep 17 00:00:00 2001 From: chungquantin <56880684+chungquantin@users.noreply.github.com> Date: Wed, 11 Sep 2024 17:28:36 +0700 Subject: [PATCH 058/112] fix: update tests --- pop-sandbox/examples/fungibles/lib.rs | 14 ++++---- pop-sandbox/examples/proxy/Cargo.toml | 3 +- pop-sandbox/examples/proxy/lib.rs | 25 ++++++++++---- pop-sandbox/src/lib.rs | 2 ++ pop-sandbox/src/utils.rs | 38 +++++++++++++++++++++ runtime/devnet/src/config/api/versioning.rs | 6 ++-- 6 files changed, 71 insertions(+), 17 deletions(-) create mode 100644 pop-sandbox/src/utils.rs diff --git a/pop-sandbox/examples/fungibles/lib.rs b/pop-sandbox/examples/fungibles/lib.rs index 59d0ea7e..d31786db 100644 --- a/pop-sandbox/examples/fungibles/lib.rs +++ b/pop-sandbox/examples/fungibles/lib.rs @@ -3,8 +3,8 @@ #[ink::contract] mod create_token_in_constructor { use pop_api::{ - primitives::AssetId, - v0::assets::fungibles::{self as api}, + primitives::TokenId, + v0::fungibles::{self as api}, StatusCode, }; @@ -12,13 +12,13 @@ mod create_token_in_constructor { #[ink(storage)] pub struct Fungible { - id: AssetId, + id: TokenId, } impl Fungible { #[ink(constructor)] - pub fn new(id: AssetId, min_balance: Balance) -> Result { - ink::env::debug_println!("Fungible::call() asset_id={id}, min_balance={min_balance}"); + pub fn new(id: TokenId, min_balance: Balance) -> Result { + ink::env::debug_println!("Fungible::call() asset_id={id}, min_balance={min_balance}"); let contract = Self { id }; // AccountId of the contract which will be set to the owner of the fungible token. let owner = contract.env().account_id(); @@ -28,8 +28,8 @@ mod create_token_in_constructor { } #[ink(message)] - pub fn asset_exists(&self) -> Result { - api::asset_exists(self.id) + pub fn token_exists(&self) -> Result { + api::token_exists(self.id) } } } diff --git a/pop-sandbox/examples/proxy/Cargo.toml b/pop-sandbox/examples/proxy/Cargo.toml index 0dd7b249..f937145a 100644 --- a/pop-sandbox/examples/proxy/Cargo.toml +++ b/pop-sandbox/examples/proxy/Cargo.toml @@ -8,7 +8,7 @@ version = "0.1.0" codec = { package = "parity-scale-codec", version = "3", default-features = false, features = [ "derive", ] } -frame-system = { version = "29.0.0", default-features = false } +frame-system = { version = "36.1.0", default-features = false } ink = { version = "=5.0.0", default-features = false, features = [ "ink-debug" ] } pop-api = { path = "../../../pop-api", default-features = false, features = [ "fungibles", @@ -20,6 +20,7 @@ scale-info = { version = "2.6", default-features = false, features = [ [dev-dependencies] drink = { path = "../../../../pop-drink/drink" } pop-sandbox = { path = "../../../pop-sandbox", default-features = false } +serde_json = "1.0.108" [lib] path = "lib.rs" diff --git a/pop-sandbox/examples/proxy/lib.rs b/pop-sandbox/examples/proxy/lib.rs index b0116301..e91ea6fe 100644 --- a/pop-sandbox/examples/proxy/lib.rs +++ b/pop-sandbox/examples/proxy/lib.rs @@ -55,21 +55,34 @@ mod proxy_contract { mod tests { use codec::Encode; use core::fmt::Debug; - use drink::session::{Session, NO_ARGS, NO_SALT}; + use drink::{ + session::{Session, NO_ARGS, NO_SALT}, + AccountId32, + }; + use frame_system::Call; + use pop_sandbox::{utils::call_function, PopSandbox, RuntimeCall}; #[drink::contract_bundle_provider] enum BundleProvider {} - #[drink::test(sandbox = pop_sandbox::PopSandbox)] + #[drink::test(sandbox = PopSandbox)] fn deploy_contract_and_call(mut session: Session) -> Result<(), Box> { let contract_bundle = BundleProvider::local()?; let contract_address = session.deploy_bundle(contract_bundle, "new", NO_ARGS, NO_SALT, None)?; - let input : Vec = vec![0, 7, 112, 111, 112].encode(); - let converted_input : Vec = input.into_iter().map(|b| b.to_string()).collect::>(); - // DispatchCall::RuntimeSystem::Remark - session.call_with_address(contract_address, "call", &[vec![0u32.to_string()], converted_input].concat(), None)??; + let alice = AccountId32::new([1u8; 32]); + let call = + RuntimeCall::System(Call::remark_with_event { remark: "pop".as_bytes().to_vec() }); + call_function( + session, + &contract_address, + &alice, + "call".to_string(), + // DispatchCall::System::Call::remark_with_event. + Some(vec![0.to_string(), serde_json::to_string(&call.encode()).unwrap()]), + None, + )?; Ok(()) } diff --git a/pop-sandbox/src/lib.rs b/pop-sandbox/src/lib.rs index f2abacd3..9d2d2cd8 100644 --- a/pop-sandbox/src/lib.rs +++ b/pop-sandbox/src/lib.rs @@ -12,6 +12,8 @@ use sp_runtime::traits::{AccountIdLookup, Convert}; use sp_std::vec::Vec; mod api; +// Provides utlity methods to interact with the sandbox. +pub mod utils; pub(crate) type AccountId = AccountId32; pub(crate) type AssetId = u32; diff --git a/pop-sandbox/src/utils.rs b/pop-sandbox/src/utils.rs new file mode 100644 index 00000000..f315897e --- /dev/null +++ b/pop-sandbox/src/utils.rs @@ -0,0 +1,38 @@ +use drink::{ + session::{Session, NO_ARGS}, + AccountId32, +}; +use std::error::Error; + +use super::*; + +// TODO: Convert this method to accept generic runtime instead of `PopSandbox`. +pub fn call_function( + mut sess: Session, + contract: &AccountId32, + sender: &AccountId32, + func_name: String, + args: Option>, + value: Option, +) -> Result, Box> { + sess.set_actor(sender.clone()); + if let Some(args) = args { + println!("Calling function: {}() | Input: {:?}", func_name, args); + sess.call_with_address(contract.clone(), &func_name, &args, value)??; + } else { + println!("Calling function: {}() | Input: None", func_name); + sess.call_with_address(contract.clone(), &func_name, NO_ARGS, value)??; + } + + let encoded = &sess.record().last_call_result().result.clone().unwrap().data; + let decoded = encoded.iter().map(|b| *b as char).collect::(); + let messages: Vec = decoded.split('\n').map(|s| s.to_string()).collect(); + // Print debug logs + for line in messages { + if line.len() > 0 { + println!("LOG: {}", line); + } + } + + Ok(sess) +} diff --git a/runtime/devnet/src/config/api/versioning.rs b/runtime/devnet/src/config/api/versioning.rs index 317496df..7c3d9ee5 100644 --- a/runtime/devnet/src/config/api/versioning.rs +++ b/runtime/devnet/src/config/api/versioning.rs @@ -112,9 +112,9 @@ impl From for V0Error { // Note: message not used let ModuleError { index, error, message: _message } = error; // Map `pallet-contracts::Error::DecodingFailed` to `Error::DecodingFailed` - if index as usize == - ::index() && - error == DECODING_FAILED_ERROR + if index as usize + == ::index() + && error == DECODING_FAILED_ERROR { Error::DecodingFailed } else { From d23c2b315e0d5469df9c95bfa248c29fb024a2ef Mon Sep 17 00:00:00 2001 From: chungquantin <56880684+chungquantin@users.noreply.github.com> Date: Thu, 12 Sep 2024 01:33:56 +0700 Subject: [PATCH 059/112] fix: test with logger --- pop-sandbox/examples/flipper/Cargo.toml | 1 + pop-sandbox/examples/flipper/lib.rs | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/pop-sandbox/examples/flipper/Cargo.toml b/pop-sandbox/examples/flipper/Cargo.toml index c0694808..1080f85e 100644 --- a/pop-sandbox/examples/flipper/Cargo.toml +++ b/pop-sandbox/examples/flipper/Cargo.toml @@ -16,6 +16,7 @@ scale-info = { version = "2.6", default-features = false, features = [ [dev-dependencies] drink = { path = "../../../../pop-drink/drink" } +env_logger = { version = "0.11.3" } pop-sandbox = { path = "../../../pop-sandbox", default-features = false } [lib] diff --git a/pop-sandbox/examples/flipper/lib.rs b/pop-sandbox/examples/flipper/lib.rs index 4efd4edf..3d72c2cb 100644 --- a/pop-sandbox/examples/flipper/lib.rs +++ b/pop-sandbox/examples/flipper/lib.rs @@ -75,6 +75,7 @@ mod tests { /// use `MinimalSandbox`, which is a minimalistic runtime that allows using smart contracts. #[drink::test(sandbox = pop_sandbox::PopSandbox)] fn deploy_and_call_a_contract(mut session: Session) -> Result<(), Box> { + let _ = env_logger::try_init(); // Now we get the contract bundle from the `BundleProvider` enum. Since the current crate // comes with a contract, we can use the `local` method to get the bundle for it. let contract_bundle = BundleProvider::local()?; @@ -90,7 +91,7 @@ mod tests { // Salt for the contract address derivation. NO_SALT, // Initial endowment (the amount of tokens that we want to transfer to the contract). - None, + Some(1000), )?; // Once the contract is instantiated, we can call the `flip` method on the contract. From 0ab510f3d366a379ead74c6fe6bcd3c6f72cedf6 Mon Sep 17 00:00:00 2001 From: chungquantin <56880684+chungquantin@users.noreply.github.com> Date: Thu, 12 Sep 2024 01:34:11 +0700 Subject: [PATCH 060/112] fix: test with logger --- pop-sandbox/examples/fungibles/Cargo.toml | 1 + pop-sandbox/examples/fungibles/lib.rs | 8 +-- pop-sandbox/examples/proxy/Cargo.toml | 1 + pop-sandbox/examples/proxy/lib.rs | 11 +++-- pop-sandbox/src/lib.rs | 59 +++++++++++++++-------- pop-sandbox/src/utils.rs | 2 + 6 files changed, 55 insertions(+), 27 deletions(-) diff --git a/pop-sandbox/examples/fungibles/Cargo.toml b/pop-sandbox/examples/fungibles/Cargo.toml index f151f376..075ea943 100644 --- a/pop-sandbox/examples/fungibles/Cargo.toml +++ b/pop-sandbox/examples/fungibles/Cargo.toml @@ -18,6 +18,7 @@ scale-info = { version = "2.6", default-features = false, features = [ [dev-dependencies] drink = { path = "../../../../pop-drink/drink" } +env_logger = { version = "0.11.3" } pop-sandbox = { path = "../../../pop-sandbox", default-features = false } [lib] diff --git a/pop-sandbox/examples/fungibles/lib.rs b/pop-sandbox/examples/fungibles/lib.rs index d31786db..f8328800 100644 --- a/pop-sandbox/examples/fungibles/lib.rs +++ b/pop-sandbox/examples/fungibles/lib.rs @@ -20,9 +20,7 @@ mod create_token_in_constructor { pub fn new(id: TokenId, min_balance: Balance) -> Result { ink::env::debug_println!("Fungible::call() asset_id={id}, min_balance={min_balance}"); let contract = Self { id }; - // AccountId of the contract which will be set to the owner of the fungible token. let owner = contract.env().account_id(); - // TODO: Calling POP API caused DeploymentReverted api::create(id, owner, min_balance)?; Ok(contract) } @@ -37,20 +35,22 @@ mod create_token_in_constructor { /// We put `drink`-based tests as usual unit tests, into a test module. #[cfg(test)] mod tests { - use drink::session::{Session, NO_ARGS, NO_SALT}; + use drink::session::{Session, NO_SALT}; #[drink::contract_bundle_provider] enum BundleProvider {} #[drink::test(sandbox = pop_sandbox::PopSandbox)] fn deploy_and_call_a_contract(mut session: Session) -> Result<(), Box> { + let _ = env_logger::try_init(); let contract_bundle = BundleProvider::local()?; + // TODO: utility method for deploy_contract let _contract_address = session.deploy_bundle( contract_bundle, "new", &[1.to_string(), 1_000.to_string()], NO_SALT, - None, + Some(100_000_000), )?; Ok(()) } diff --git a/pop-sandbox/examples/proxy/Cargo.toml b/pop-sandbox/examples/proxy/Cargo.toml index f937145a..95adf32c 100644 --- a/pop-sandbox/examples/proxy/Cargo.toml +++ b/pop-sandbox/examples/proxy/Cargo.toml @@ -19,6 +19,7 @@ scale-info = { version = "2.6", default-features = false, features = [ [dev-dependencies] drink = { path = "../../../../pop-drink/drink" } +env_logger = { version = "0.11.3" } pop-sandbox = { path = "../../../pop-sandbox", default-features = false } serde_json = "1.0.108" diff --git a/pop-sandbox/examples/proxy/lib.rs b/pop-sandbox/examples/proxy/lib.rs index e91ea6fe..d5299045 100644 --- a/pop-sandbox/examples/proxy/lib.rs +++ b/pop-sandbox/examples/proxy/lib.rs @@ -60,29 +60,34 @@ mod tests { AccountId32, }; use frame_system::Call; - use pop_sandbox::{utils::call_function, PopSandbox, RuntimeCall}; + use pop_sandbox::{ + utils::{call_function, ALICE}, + PopSandbox, RuntimeCall, + }; #[drink::contract_bundle_provider] enum BundleProvider {} #[drink::test(sandbox = PopSandbox)] fn deploy_contract_and_call(mut session: Session) -> Result<(), Box> { + let _ = env_logger::try_init(); + let contract_bundle = BundleProvider::local()?; let contract_address = session.deploy_bundle(contract_bundle, "new", NO_ARGS, NO_SALT, None)?; - let alice = AccountId32::new([1u8; 32]); let call = RuntimeCall::System(Call::remark_with_event { remark: "pop".as_bytes().to_vec() }); call_function( session, &contract_address, - &alice, + &ALICE, "call".to_string(), // DispatchCall::System::Call::remark_with_event. Some(vec![0.to_string(), serde_json::to_string(&call.encode()).unwrap()]), None, )?; + // TOOD: Return CallFiltered Ok(()) } diff --git a/pop-sandbox/src/lib.rs b/pop-sandbox/src/lib.rs index 9d2d2cd8..118ebaa6 100644 --- a/pop-sandbox/src/lib.rs +++ b/pop-sandbox/src/lib.rs @@ -7,7 +7,7 @@ use frame_support::{ }; use frame_system::{EnsureRoot, EnsureSigned}; use pallet_api::fungibles; -use pallet_contracts::{DefaultAddressGenerator, Frame, Schedule}; +use pallet_contracts::{DefaultAddressGenerator, Frame}; use sp_runtime::traits::{AccountIdLookup, Convert}; use sp_std::vec::Vec; @@ -19,6 +19,12 @@ pub(crate) type AccountId = AccountId32; pub(crate) type AssetId = u32; pub(crate) type Balance = u128; +pub const MILLIUNIT: Balance = UNIT / 1_000; // 10_000_000 + +pub const fn deposit(items: u32, bytes: u32) -> Balance { + (items as Balance * UNIT + (bytes as Balance) * (5 * MILLIUNIT / 100)) / 10 +} + // Define the runtime type as a collection of pallets construct_runtime!( pub enum Runtime { @@ -109,51 +115,64 @@ impl Convert for Runtime { } } +fn schedule() -> pallet_contracts::Schedule { + pallet_contracts::Schedule { + limits: pallet_contracts::Limits { + runtime_memory: 1024 * 1024 * 1024, + ..Default::default() + }, + ..Default::default() + } +} + parameter_types! { - pub SandboxSchedule: Schedule = { - let schedule = >::default(); - schedule - }; - pub DeletionWeightLimit: Weight = Weight::zero(); - pub DefaultDepositLimit: BalanceOf = 10_000_000; - pub CodeHashLockupDepositPercent: Perbill = Perbill::from_percent(0); - pub MaxDelegateDependencies: u32 = 32; + pub const DepositPerItem: Balance = deposit(1, 0); + pub const DepositPerByte: Balance = deposit(0, 1); + pub Schedule: pallet_contracts::Schedule = schedule::(); + pub const DefaultDepositLimit: Balance = deposit(1024, 1024 * 1024); + pub const CodeHashLockupDepositPercent: Perbill = Perbill::from_percent(0); } impl pallet_contracts::Config for Runtime { type AddressGenerator = DefaultAddressGenerator; type ApiVersion = (); + // C type CallFilter = (); - // TestFilter; - type CallStack = [Frame; 5]; + type CallStack = [Frame; 23]; type ChainExtension = api::Extension; type CodeHashLockupDepositPercent = CodeHashLockupDepositPercent; type Currency = Balances; + // D type Debug = drink::pallet_contracts_debugging::DrinkDebug; - // TestDebug; type DefaultDepositLimit = DefaultDepositLimit; - type DepositPerByte = ConstU128<1>; - type DepositPerItem = ConstU128<1>; + type DepositPerByte = DepositPerByte; + type DepositPerItem = DepositPerItem; + // E type Environment = (); + // I type InstantiateOrigin = EnsureSigned; - type MaxCodeLen = ConstU32<{ 123 * 1024 }>; + // M + type MaxCodeLen = ConstU32<{ 256 * 1024 }>; type MaxDebugBufferLen = ConstU32<{ 2 * 1024 * 1024 }>; - type MaxDelegateDependencies = MaxDelegateDependencies; + type MaxDelegateDependencies = ConstU32<32>; type MaxStorageKeyLen = ConstU32<128>; type Migrations = (); - // crate::migration::codegen::BenchMigrations; + // R type Randomness = SandboxRandomness; type RuntimeCall = RuntimeCall; type RuntimeEvent = RuntimeEvent; type RuntimeHoldReason = RuntimeHoldReason; - type Schedule = SandboxSchedule; + // S + type Schedule = Schedule; + // T type Time = Timestamp; + // U type UnsafeUnstableInterface = ConstBool; - // UnstableInterface; type UploadOrigin = EnsureSigned; + // W type WeightInfo = (); type WeightPrice = Self; - // Self; + // X type Xcm = (); } diff --git a/pop-sandbox/src/utils.rs b/pop-sandbox/src/utils.rs index f315897e..8a8085ac 100644 --- a/pop-sandbox/src/utils.rs +++ b/pop-sandbox/src/utils.rs @@ -6,6 +6,8 @@ use std::error::Error; use super::*; +pub const ALICE: AccountId32 = AccountId32::new([1_u8; 32]); + // TODO: Convert this method to accept generic runtime instead of `PopSandbox`. pub fn call_function( mut sess: Session, From 1c0604321e87af52a9dc17e83fd1088bd35ea142 Mon Sep 17 00:00:00 2001 From: chungquantin <56880684+chungquantin@users.noreply.github.com> Date: Thu, 12 Sep 2024 01:35:31 +0700 Subject: [PATCH 061/112] fix: revert flipper example changes --- pop-sandbox/examples/flipper/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pop-sandbox/examples/flipper/lib.rs b/pop-sandbox/examples/flipper/lib.rs index 3d72c2cb..9e97465a 100644 --- a/pop-sandbox/examples/flipper/lib.rs +++ b/pop-sandbox/examples/flipper/lib.rs @@ -91,7 +91,7 @@ mod tests { // Salt for the contract address derivation. NO_SALT, // Initial endowment (the amount of tokens that we want to transfer to the contract). - Some(1000), + None, )?; // Once the contract is instantiated, we can call the `flip` method on the contract. From f6976b082e9065bd933cf3093588c969ad402128 Mon Sep 17 00:00:00 2001 From: chungquantin <56880684+chungquantin@users.noreply.github.com> Date: Thu, 12 Sep 2024 10:13:39 +0700 Subject: [PATCH 062/112] fix: fungibles contract --- pop-sandbox/examples/fungibles/lib.rs | 44 +++++++++++++++++++-------- 1 file changed, 31 insertions(+), 13 deletions(-) diff --git a/pop-sandbox/examples/fungibles/lib.rs b/pop-sandbox/examples/fungibles/lib.rs index f8328800..2e976376 100644 --- a/pop-sandbox/examples/fungibles/lib.rs +++ b/pop-sandbox/examples/fungibles/lib.rs @@ -1,14 +1,16 @@ #![cfg_attr(not(feature = "std"), no_std, no_main)] +use pop_api::{ + primitives::TokenId, + v0::fungibles::{self as api}, + StatusCode, +}; + +type PopApiResult = core::result::Result; + #[ink::contract] mod create_token_in_constructor { - use pop_api::{ - primitives::TokenId, - v0::fungibles::{self as api}, - StatusCode, - }; - - pub type Result = core::result::Result; + use super::*; #[ink(storage)] pub struct Fungible { @@ -16,8 +18,8 @@ mod create_token_in_constructor { } impl Fungible { - #[ink(constructor)] - pub fn new(id: TokenId, min_balance: Balance) -> Result { + #[ink(constructor, payable)] + pub fn new(id: TokenId, min_balance: Balance) -> PopApiResult { ink::env::debug_println!("Fungible::call() asset_id={id}, min_balance={min_balance}"); let contract = Self { id }; let owner = contract.env().account_id(); @@ -26,8 +28,8 @@ mod create_token_in_constructor { } #[ink(message)] - pub fn token_exists(&self) -> Result { - api::token_exists(self.id) + pub fn token_exists(&self, id: TokenId) -> PopApiResult { + api::token_exists(id) } } } @@ -35,7 +37,9 @@ mod create_token_in_constructor { /// We put `drink`-based tests as usual unit tests, into a test module. #[cfg(test)] mod tests { + use super::*; use drink::session::{Session, NO_SALT}; + use pop_sandbox::utils::{call_function, ALICE}; #[drink::contract_bundle_provider] enum BundleProvider {} @@ -44,14 +48,28 @@ mod tests { fn deploy_and_call_a_contract(mut session: Session) -> Result<(), Box> { let _ = env_logger::try_init(); let contract_bundle = BundleProvider::local()?; - // TODO: utility method for deploy_contract - let _contract_address = session.deploy_bundle( + + const ASSET_ID: TokenId = 1; + // Deploy a contract and create a new token with ASSET_ID = 1 + let contract_address = session.deploy_bundle( contract_bundle, "new", &[1.to_string(), 1_000.to_string()], NO_SALT, Some(100_000_000), )?; + // Calling the method in the contract. + let session = call_function( + session, + &contract_address, + &ALICE, + "token_exists".to_string(), + Some(vec![ASSET_ID.to_string()]), + None, + )?; + // Check that the token is created successfully. + let result = session.record().last_call_return_decoded::>()??; + assert_eq!(result, Ok(true)); Ok(()) } } From d6408da5636bfbbf9a12ae975e67bab0c1160818 Mon Sep 17 00:00:00 2001 From: chungquantin <56880684+chungquantin@users.noreply.github.com> Date: Thu, 12 Sep 2024 13:14:49 +0700 Subject: [PATCH 063/112] refactor: create sandbox for devnet runtime --- pop-api/examples/balance-transfer/Cargo.toml | 28 -- pop-api/examples/balance-transfer/lib.rs | 135 --------- pop-api/examples/fungibles/Cargo.toml | 22 +- pop-api/examples/fungibles/lib.rs | 180 ++++++------ pop-api/examples/nfts/Cargo.toml | 25 -- pop-api/examples/nfts/lib.rs | 117 -------- pop-api/examples/place-spot-order/Cargo.toml | 25 -- pop-api/examples/place-spot-order/lib.rs | 43 --- .../examples/read-runtime-state/Cargo.toml | 25 -- pop-api/examples/read-runtime-state/lib.rs | 36 --- pop-sandbox/Cargo.toml | 38 +-- pop-sandbox/examples/flipper/lib.rs | 15 +- pop-sandbox/examples/fungibles/Cargo.toml | 37 --- pop-sandbox/examples/fungibles/lib.rs | 75 ----- pop-sandbox/examples/proxy/Cargo.toml | 40 --- pop-sandbox/examples/proxy/lib.rs | 94 ------- pop-sandbox/src/api/mod.rs | 159 ----------- pop-sandbox/src/api/versioning.rs | 220 --------------- pop-sandbox/src/lib.rs | 261 ++++++++---------- pop-sandbox/src/utils.rs | 5 +- runtime/devnet/src/config/api/versioning.rs | 6 +- 21 files changed, 242 insertions(+), 1344 deletions(-) delete mode 100755 pop-api/examples/balance-transfer/Cargo.toml delete mode 100755 pop-api/examples/balance-transfer/lib.rs mode change 100755 => 100644 pop-api/examples/fungibles/Cargo.toml mode change 100755 => 100644 pop-api/examples/fungibles/lib.rs delete mode 100755 pop-api/examples/nfts/Cargo.toml delete mode 100755 pop-api/examples/nfts/lib.rs delete mode 100755 pop-api/examples/place-spot-order/Cargo.toml delete mode 100755 pop-api/examples/place-spot-order/lib.rs delete mode 100755 pop-api/examples/read-runtime-state/Cargo.toml delete mode 100755 pop-api/examples/read-runtime-state/lib.rs delete mode 100644 pop-sandbox/examples/fungibles/Cargo.toml delete mode 100644 pop-sandbox/examples/fungibles/lib.rs delete mode 100644 pop-sandbox/examples/proxy/Cargo.toml delete mode 100644 pop-sandbox/examples/proxy/lib.rs delete mode 100644 pop-sandbox/src/api/mod.rs delete mode 100644 pop-sandbox/src/api/versioning.rs diff --git a/pop-api/examples/balance-transfer/Cargo.toml b/pop-api/examples/balance-transfer/Cargo.toml deleted file mode 100755 index 2a12e532..00000000 --- a/pop-api/examples/balance-transfer/Cargo.toml +++ /dev/null @@ -1,28 +0,0 @@ -[package] -authors = [ "[your_name] <[your_email]>" ] -edition = "2021" -name = "balance_transfer" -version = "0.1.0" - -[dependencies] -ink = { version = "5.0.0", default-features = false } -pop-api = { path = "../../../pop-api", default-features = false } -scale = { package = "parity-scale-codec", version = "3", default-features = false, features = [ "derive" ] } -scale-info = { version = "2.6", default-features = false, features = [ "derive" ], optional = true } - -[dev-dependencies] -ink_e2e = "5.0.0" - -[lib] -path = "lib.rs" - -[features] -default = [ "std" ] -e2e-tests = [ ] -ink-as-dependency = [ ] -std = [ - "ink/std", - "pop-api/std", - "scale-info/std", - "scale/std", -] diff --git a/pop-api/examples/balance-transfer/lib.rs b/pop-api/examples/balance-transfer/lib.rs deleted file mode 100755 index e75c15b9..00000000 --- a/pop-api/examples/balance-transfer/lib.rs +++ /dev/null @@ -1,135 +0,0 @@ -// DEPRECATED -#![cfg_attr(not(feature = "std"), no_std, no_main)] - -use pop_api::balances::*; - -#[derive(Debug, Copy, Clone, PartialEq, Eq, scale::Encode, scale::Decode)] -#[cfg_attr(feature = "std", derive(scale_info::TypeInfo))] -pub enum ContractError { - BalancesError(Error), -} - -impl From for ContractError { - fn from(value: Error) -> Self { - ContractError::BalancesError(value) - } -} - -#[ink::contract] -mod balance_transfer { - use super::*; - - #[ink(storage)] - #[derive(Default)] - pub struct BalanceTransfer; - - impl BalanceTransfer { - #[ink(constructor, payable)] - pub fn new() -> Self { - ink::env::debug_println!("BalanceTransfer::new"); - Default::default() - } - - #[ink(message)] - pub fn transfer( - &mut self, - receiver: AccountId, - value: Balance, - ) -> Result<(), ContractError> { - ink::env::debug_println!( - "BalanceTransfer::transfer: \nreceiver: {:?}, \nvalue: {:?}", - receiver, - value - ); - - transfer_keep_alive(receiver, value)?; - - ink::env::debug_println!("BalanceTransfer::transfer end"); - Ok(()) - } - } - - #[cfg(all(test, feature = "e2e-tests"))] - mod e2e_tests { - use super::*; - use ink_e2e::{ChainBackend, ContractsBackend}; - - use ink::{ - env::{test::default_accounts, DefaultEnvironment}, - primitives::AccountId, - }; - - type E2EResult = Result>; - - /// The base number of indivisible units for balances on the - /// `substrate-contracts-node`. - const UNIT: Balance = 1_000_000_000_000; - - /// The contract will be given 1000 tokens during instantiation. - const CONTRACT_BALANCE: Balance = 1_000 * UNIT; - - /// The receiver will get enough funds to have the required existential deposit. - /// - /// If your chain has this threshold higher, increase the transfer value. - const TRANSFER_VALUE: Balance = 1 / 10 * UNIT; - - /// An amount that is below the existential deposit, so that a transfer to an - /// empty account fails. - /// - /// Must not be zero, because such an operation would be a successful no-op. - const INSUFFICIENT_TRANSFER_VALUE: Balance = 1; - - /// Positive case scenario: - /// - the call is valid - /// - the call execution succeeds - #[ink_e2e::test] - async fn transfer_with_call_runtime_works( - mut client: Client, - ) -> E2EResult<()> { - // given - let mut constructor = RuntimeCallerRef::new(); - let contract = client - .instantiate("call-runtime", &ink_e2e::alice(), &mut constructor) - .value(CONTRACT_BALANCE) - .submit() - .await - .expect("instantiate failed"); - let mut call_builder = contract.call_builder::(); - - let accounts = default_accounts::(); - - let receiver: AccountId = accounts.bob; - - let sender_balance_before = client - .free_balance(accounts.alice) - .await - .expect("Failed to get account balance"); - let receiver_balance_before = - client.free_balance(receiver).await.expect("Failed to get account balance"); - - // when - let transfer_message = call_builder.transfer(receiver, TRANSFER_VALUE); - - let call_res = client - .call(&ink_e2e::alice(), &transfer_message) - .submit() - .await - .expect("call failed"); - - assert!(call_res.return_value().is_ok()); - - // then - let sender_balance_after = client - .free_balance(accounts.alice) - .await - .expect("Failed to get account balance"); - let receiver_balance_after = - client.free_balance(receiver).await.expect("Failed to get account balance"); - - assert_eq!(contract_balance_before, contract_balance_after + TRANSFER_VALUE); - assert_eq!(receiver_balance_before, receiver_balance_after - TRANSFER_VALUE); - - Ok(()) - } - } -} diff --git a/pop-api/examples/fungibles/Cargo.toml b/pop-api/examples/fungibles/Cargo.toml old mode 100755 new mode 100644 index 0b79e1b2..075ea943 --- a/pop-api/examples/fungibles/Cargo.toml +++ b/pop-api/examples/fungibles/Cargo.toml @@ -1,12 +1,25 @@ [package] authors = [ "[your_name] <[your_email]>" ] edition = "2021" -name = "fungibles" +name = "api_example_fungibles" version = "0.1.0" [dependencies] -ink = { version = "5.0.0", default-features = false } -pop-api = { path = "../../../pop-api", default-features = false, features = [ "fungibles" ] } +ink = { version = "=5.0.0", default-features = false, features = [ "ink-debug" ] } +pop-api = { path = "../../../pop-api", default-features = false, features = [ + "fungibles", +] } +scale = { package = "parity-scale-codec", version = "3", default-features = false, features = [ + "derive", +] } +scale-info = { version = "2.6", default-features = false, features = [ + "derive", +], optional = true } + +[dev-dependencies] +drink = { path = "../../../../pop-drink/drink" } +env_logger = { version = "0.11.3" } +pop-sandbox = { path = "../../../pop-sandbox", default-features = false } [lib] path = "lib.rs" @@ -18,4 +31,7 @@ ink-as-dependency = [ ] std = [ "ink/std", "pop-api/std", + "pop-sandbox/std", + "scale-info/std", + "scale/std", ] diff --git a/pop-api/examples/fungibles/lib.rs b/pop-api/examples/fungibles/lib.rs old mode 100755 new mode 100644 index 1ad36de0..00f02914 --- a/pop-api/examples/fungibles/lib.rs +++ b/pop-api/examples/fungibles/lib.rs @@ -1,185 +1,161 @@ #![cfg_attr(not(feature = "std"), no_std, no_main)] -/// Local Fungibles: -/// 1. PSP-22 Interface -/// 2. PSP-22 Metadata Interface -/// 3. Asset Management -/// use ink::prelude::vec::Vec; use pop_api::{ - assets::fungibles::{self as api}, - primitives::AssetId, + primitives::TokenId, + v0::fungibles::{self as api}, StatusCode, }; -pub type Result = core::result::Result; +type PopApiResult = core::result::Result; #[ink::contract] -mod fungibles { +mod create_token_in_constructor { use super::*; #[ink(storage)] - #[derive(Default)] - pub struct Fungibles; + pub struct Fungible { + id: TokenId, + } - impl Fungibles { + impl Fungible { #[ink(constructor, payable)] - pub fn new() -> Self { - ink::env::debug_println!("PopApiFungiblesExample::new"); - Default::default() + pub fn new(id: TokenId, min_balance: Balance) -> PopApiResult { + ink::env::debug_println!("Fungible::call() asset_id={id}, min_balance={min_balance}"); + let contract = Self { id }; + let owner = contract.env().account_id(); + api::create(id, owner, min_balance)?; + Ok(contract) } - /// 1. PSP-22 Interface: - /// - total_supply - /// - balance_of - /// - allowance - /// - transfer - /// - transfer_from - /// - approve - /// - increase_allowance - /// - decrease_allowance + #[ink(message)] + pub fn token_exists(&self, id: TokenId) -> PopApiResult { + api::token_exists(id) + } #[ink(message)] - pub fn total_supply(&self, id: AssetId) -> Result { + pub fn total_supply(&self, id: TokenId) -> PopApiResult { api::total_supply(id) } #[ink(message)] - pub fn balance_of(&self, id: AssetId, owner: AccountId) -> Result { + pub fn balance_of(&self, id: TokenId, owner: AccountId) -> PopApiResult { api::balance_of(id, owner) } #[ink(message)] pub fn allowance( &self, - id: AssetId, + id: TokenId, owner: AccountId, spender: AccountId, - ) -> Result { + ) -> PopApiResult { api::allowance(id, owner, spender) } #[ink(message)] - pub fn transfer(&mut self, id: AssetId, to: AccountId, value: Balance) -> Result<()> { + pub fn transfer(&mut self, id: TokenId, to: AccountId, value: Balance) -> PopApiResult<()> { api::transfer(id, to, value) } #[ink(message)] pub fn transfer_from( &mut self, - id: AssetId, + id: TokenId, from: AccountId, to: AccountId, value: Balance, // In the PSP-22 standard a `[u8]`, but the size needs to be known at compile time. _data: Vec, - ) -> Result<()> { + ) -> PopApiResult<()> { api::transfer_from(id, from, to, value) } #[ink(message)] - pub fn approve(&mut self, id: AssetId, spender: AccountId, value: Balance) -> Result<()> { + pub fn approve( + &mut self, + id: TokenId, + spender: AccountId, + value: Balance, + ) -> PopApiResult<()> { api::approve(id, spender, value) } #[ink(message)] pub fn increase_allowance( &mut self, - id: AssetId, + id: TokenId, spender: AccountId, value: Balance, - ) -> Result<()> { + ) -> PopApiResult<()> { api::increase_allowance(id, spender, value) } #[ink(message)] pub fn decrease_allowance( &mut self, - id: AssetId, + id: TokenId, spender: AccountId, value: Balance, - ) -> Result<()> { + ) -> PopApiResult<()> { api::decrease_allowance(id, spender, value) } - /// 2. PSP-22 Metadata Interface: - /// - token_name - /// - token_symbol - /// - token_decimals - #[ink(message)] - pub fn token_name(&self, id: AssetId) -> Result> { + pub fn token_name(&self, id: TokenId) -> PopApiResult> { api::token_name(id) } #[ink(message)] - pub fn token_symbol(&self, id: AssetId) -> Result> { + pub fn token_symbol(&self, id: TokenId) -> PopApiResult> { api::token_symbol(id) } #[ink(message)] - pub fn token_decimals(&self, id: AssetId) -> Result { + pub fn token_decimals(&self, id: TokenId) -> PopApiResult { api::token_decimals(id) } - - // 3. Asset Management: - // - create - // - start_destroy - // - destroy_accounts - // - destroy_approvals - // - finish_destroy - // - set_metadata - // - clear_metadata - - // #[ink(message)] - // pub fn create(&self, id: AssetId, admin: AccountId, min_balance: Balance) -> Result<()> { - // ink::env::debug_println!( - // "PopApiFungiblesExample::create: id: {:?} admin: {:?} min_balance: {:?}", - // id, - // admin, - // min_balance, - // ); - // let result = api::create(id, admin, min_balance); - // ink::env::debug_println!("Result: {:?}", result); - // result.map_err(|e| e.into()) - // result - // } - - // #[ink(message)] - // pub fn set_metadata( - // &self, - // id: AssetId, - // name: Vec, - // symbol: Vec, - // decimals: u8, - // ) -> Result<()> { - // ink::env::debug_println!( - // "PopApiFungiblesExample::set_metadata: id: {:?} name: {:?} symbol: {:?}, decimals: {:?}", - // id, - // name, - // symbol, - // decimals, - // ); - // let result = api::set_metadata(id, name, symbol, decimals); - // ink::env::debug_println!("Result: {:?}", result); - // // result.map_err(|e| e.into()) - // result - // } - // - // #[ink(message)] - // pub fn asset_exists(&self, id: AssetId) -> Result { - // // api::asset_exists(id).map_err(|e| e.into()) - // api::asset_exists(id) - // } } +} - #[cfg(test)] - mod tests { - use super::*; +/// We put `drink`-based tests as usual unit tests, into a test module. +#[cfg(test)] +mod tests { + use drink::session::{Session, NO_SALT}; + use pop_sandbox::{utils::call_function, ALICE, INIT_VALUE}; - #[ink::test] - fn default_works() { - PopApiFungiblesExample::new(); - } + use super::*; + + #[drink::contract_bundle_provider] + enum BundleProvider {} + + #[drink::test(sandbox = pop_sandbox::PopSandbox)] + fn deploy_and_call_a_contract(mut session: Session) -> Result<(), Box> { + let _ = env_logger::try_init(); + let contract_bundle = BundleProvider::local()?; + + const ASSET_ID: TokenId = 1; + + // Deploy a contract and create a new token with ASSET_ID = 1 + let contract_address = session.deploy_bundle( + contract_bundle, + "new", + &[ASSET_ID.to_string(), 1.to_string()], + NO_SALT, + Some(INIT_VALUE), + )?; + // Calling the method in the contract. + let session = call_function( + session, + &contract_address, + &ALICE, + "token_exists".to_string(), + Some(vec![ASSET_ID.to_string()]), + None, + )?; + // Check that the token is created successfully. + let result = session.record().last_call_return_decoded::>()??; + assert_eq!(result, Ok(true)); + Ok(()) } -} \ No newline at end of file +} diff --git a/pop-api/examples/nfts/Cargo.toml b/pop-api/examples/nfts/Cargo.toml deleted file mode 100755 index ef50b7ec..00000000 --- a/pop-api/examples/nfts/Cargo.toml +++ /dev/null @@ -1,25 +0,0 @@ -[package] -authors = [ "[your_name] <[your_email]>" ] -edition = "2021" -name = "nfts" -version = "0.1.0" - -[dependencies] -ink = { version = "5.0.0", default-features = false } -pop-api = { path = "../../../pop-api", default-features = false } -scale = { package = "parity-scale-codec", version = "3", default-features = false, features = [ "derive" ] } -scale-info = { version = "2.6", default-features = false, features = [ "derive" ], optional = true } - -[lib] -path = "lib.rs" - -[features] -default = [ "std" ] -e2e-tests = [ ] -ink-as-dependency = [ ] -std = [ - "ink/std", - "pop-api/std", - "scale-info/std", - "scale/std", -] diff --git a/pop-api/examples/nfts/lib.rs b/pop-api/examples/nfts/lib.rs deleted file mode 100755 index 0cd0f313..00000000 --- a/pop-api/examples/nfts/lib.rs +++ /dev/null @@ -1,117 +0,0 @@ -// DEPRECATED -#![cfg_attr(not(feature = "std"), no_std, no_main)] - -use pop_api::nfts::*; - -#[derive(Debug, Copy, Clone, PartialEq, Eq, scale::Encode, scale::Decode)] -#[cfg_attr(feature = "std", derive(scale_info::TypeInfo))] -pub enum ContractError { - InvalidCollection, - ItemAlreadyExists, - NftsError(Error), - NotOwner, -} - -impl From for ContractError { - fn from(value: Error) -> Self { - ContractError::NftsError(value) - } -} - -#[ink::contract] -mod nfts { - use super::*; - - #[ink(storage)] - #[derive(Default)] - pub struct Nfts; - - impl Nfts { - #[ink(constructor, payable)] - pub fn new() -> Self { - ink::env::debug_println!("Nfts::new"); - Default::default() - } - - #[ink(message)] - pub fn create_nft_collection(&self) -> Result<(), ContractError> { - ink::env::debug_println!("Nfts::create_nft_collection: collection creation started."); - let admin = Self::env().caller(); - let item_settings = ItemSettings(BitFlags::from(ItemSetting::Transferable)); - - let mint_settings = MintSettings { - mint_type: MintType::Issuer, - price: Some(0), - start_block: Some(0), - end_block: Some(0), - default_item_settings: item_settings, - }; - - let config = CollectionConfig { - settings: CollectionSettings(BitFlags::from(CollectionSetting::TransferableItems)), - max_supply: None, - mint_settings, - }; - pop_api::nfts::create(admin, config)?; - ink::env::debug_println!( - "Nfts::create_nft_collection: collection created successfully." - ); - Ok(()) - } - - #[ink(message)] - pub fn mint_nft( - &mut self, - collection_id: u32, - item_id: u32, - receiver: AccountId, - ) -> Result<(), ContractError> { - ink::env::debug_println!( - "Nfts::mint: collection_id: {:?} item_id {:?} receiver: {:?}", - collection_id, - item_id, - receiver - ); - - // Check if item already exists (demo purposes only, unnecessary as would expect check in mint call) - if item(collection_id, item_id)?.is_some() { - return Err(ContractError::ItemAlreadyExists); - } - - // mint api - mint(collection_id, item_id, receiver)?; - ink::env::debug_println!("Nfts::mint: item minted successfully"); - - // check owner - match owner(collection_id, item_id)? { - Some(owner) if owner == receiver => { - ink::env::debug_println!("Nfts::mint success: minted item belongs to receiver"); - }, - _ => { - return Err(ContractError::NotOwner); - }, - } - - ink::env::debug_println!("Nfts::mint end"); - Ok(()) - } - - #[ink(message)] - pub fn read_collection(&self, collection_id: u32) -> Result<(), ContractError> { - ink::env::debug_println!("Nfts::read_collection: collection_id: {:?}", collection_id); - let collection = pop_api::nfts::collection(collection_id)?; - ink::env::debug_println!("Nfts::read_collection: collection: {:?}", collection); - Ok(()) - } - } - - #[cfg(test)] - mod tests { - use super::*; - - #[ink::test] - fn default_works() { - Nfts::new(); - } - } -} diff --git a/pop-api/examples/place-spot-order/Cargo.toml b/pop-api/examples/place-spot-order/Cargo.toml deleted file mode 100755 index f523bea7..00000000 --- a/pop-api/examples/place-spot-order/Cargo.toml +++ /dev/null @@ -1,25 +0,0 @@ -[package] -authors = [ "[your_name] <[your_email]>" ] -edition = "2021" -name = "spot_order" -version = "0.1.0" - -[dependencies] -ink = { version = "5.0.0", default-features = false } -pop-api = { path = "../../../pop-api", default-features = false } -scale = { package = "parity-scale-codec", version = "3", default-features = false, features = [ "derive" ] } -scale-info = { version = "2.6", default-features = false, features = [ "derive" ], optional = true } - -[lib] -path = "lib.rs" - -[features] -default = [ "std" ] -e2e-tests = [ ] -ink-as-dependency = [ ] -std = [ - "ink/std", - "pop-api/std", - "scale-info/std", - "scale/std", -] diff --git a/pop-api/examples/place-spot-order/lib.rs b/pop-api/examples/place-spot-order/lib.rs deleted file mode 100755 index 965917d1..00000000 --- a/pop-api/examples/place-spot-order/lib.rs +++ /dev/null @@ -1,43 +0,0 @@ -// DEPRECATED -#![cfg_attr(not(feature = "std"), no_std, no_main)] - -#[ink::contract] -mod spot_order { - - #[ink(storage)] - #[derive(Default)] - pub struct SpotOrder; - - impl SpotOrder { - #[ink(constructor, payable)] - pub fn new() -> Self { - ink::env::debug_println!("SpotOrder::new"); - Default::default() - } - - #[ink(message)] - pub fn place_spot_order(&mut self, max_amount: Balance, para_id: u32) { - ink::env::debug_println!( - "SpotOrder::place_spot_order: max_amount {:?} para_id: {:?} ", - max_amount, - para_id, - ); - - #[allow(unused_variables)] - let res = pop_api::cross_chain::coretime::place_spot_order(max_amount, para_id); - ink::env::debug_println!("SpotOrder::place_spot_order: res {:?} ", res,); - - ink::env::debug_println!("SpotOrder::place_spot_order end"); - } - } - - #[cfg(test)] - mod tests { - use super::*; - - #[ink::test] - fn default_works() { - SpotOrder::new(); - } - } -} diff --git a/pop-api/examples/read-runtime-state/Cargo.toml b/pop-api/examples/read-runtime-state/Cargo.toml deleted file mode 100755 index f5464730..00000000 --- a/pop-api/examples/read-runtime-state/Cargo.toml +++ /dev/null @@ -1,25 +0,0 @@ -[package] -authors = [ "[your_name] <[your_email]>" ] -edition = "2021" -name = "read_relay_blocknumber" -version = "0.1.0" - -[dependencies] -ink = { version = "5.0.0", default-features = false } -pop-api = { path = "../../../pop-api", default-features = false } -scale = { package = "parity-scale-codec", version = "3", default-features = false, features = [ "derive" ] } -scale-info = { version = "2.6", default-features = false, features = [ "derive" ], optional = true } - -[lib] -path = "lib.rs" - -[features] -default = [ "std" ] -e2e-tests = [ ] -ink-as-dependency = [ ] -std = [ - "ink/std", - "pop-api/std", - "scale-info/std", - "scale/std", -] diff --git a/pop-api/examples/read-runtime-state/lib.rs b/pop-api/examples/read-runtime-state/lib.rs deleted file mode 100755 index 092e9f2f..00000000 --- a/pop-api/examples/read-runtime-state/lib.rs +++ /dev/null @@ -1,36 +0,0 @@ -// DEPRECATED -#![cfg_attr(not(feature = "std"), no_std, no_main)] - -#[ink::contract] -mod read_relay_blocknumber { - use pop_api::primitives::storage_keys::{ - ParachainSystemKeys::LastRelayChainBlockNumber, RuntimeStateKeys::ParachainSystem, - }; - - #[ink(event)] - pub struct RelayBlockNumberRead { - value: BlockNumber, - } - - #[ink(storage)] - #[derive(Default)] - pub struct ReadRelayBlockNumber; - - impl ReadRelayBlockNumber { - #[ink(constructor, payable)] - pub fn new() -> Self { - ink::env::debug_println!("ReadRelayBlockNumber::new"); - Default::default() - } - - #[ink(message)] - pub fn read_relay_block_number(&self) { - let result = - pop_api::state::read::(ParachainSystem(LastRelayChainBlockNumber)); - ink::env::debug_println!("Last relay block number read by contract: {:?}", result); - self.env().emit_event(RelayBlockNumberRead { - value: result.expect("Failed to read relay block number."), - }); - } - } -} diff --git a/pop-sandbox/Cargo.toml b/pop-sandbox/Cargo.toml index 6debda40..d2309173 100644 --- a/pop-sandbox/Cargo.toml +++ b/pop-sandbox/Cargo.toml @@ -9,25 +9,28 @@ version = "0.0.0" codec = { package = "parity-scale-codec", version = "3", default-features = false, features = [ "derive", ] } +log = { version = "0.4.21", default-features = false } scale-info = { version = "2.11", default-features = false } -# Local -drink = { path = "../../pop-drink/drink", default-features = false } -pallet-api = { path = "../pallets/api", default-features = false } -pop-chain-extension = { path = "../extension", default-features = false } -pop-primitives = { path = "../primitives", default-features = false } +drink = { path = "../../pop-drink/drink", default-features = true } -# Substrate -cumulus-primitives-core = { version = "0.14.0", default-features = false } +# Substrate +frame-metadata = { version = "16.0.0", default-features = false } frame-support = { version = "36.0.0", default-features = false } +frame-support-procedural = { version = "=30.0.1", default-features = false } frame-system = { version = "36.1.0", default-features = false } pallet-assets = { version = "37.0.0", default-features = false } +pallet-aura = { version = "35.0.0", default-features = false } +pallet-authorship = { version = "36.0.0", default-features = false } pallet-balances = { version = "37.0.0", default-features = false } pallet-contracts = { version = "35.0.0", default-features = false } +pallet-scheduler = { version = "37.0.0", default-features = false } +pallet-session = { version = "36.0.0", default-features = false } pallet-timestamp = { version = "35.0.0", default-features = false } -sp-core = { version = "34.0.0", default-features = false } -sp-runtime = { version = "38.0.0", default-features = false } -sp-std = { version = "14.0.0", default-features = false } +pallet-transaction-payment = { version = "36.0.0", default-features = false } +pop-runtime-devnet = { path = "../runtime/devnet", default-features = false } +sp-io = { version = "37.0.0", default-features = false } +sp-runtime = { version = "=38.0.0", default-features = false } [lib] crate-type = [ "rlib" ] @@ -38,20 +41,19 @@ path = "src/lib.rs" default = [ "std" ] std = [ "codec/std", - "cumulus-primitives-core/std", - "drink/std", "frame-support/std", "frame-system/std", - "pallet-api/std", - "pallet-api/std", "pallet-assets/std", + "pallet-aura/std", + "pallet-authorship/std", "pallet-balances/std", "pallet-contracts/std", + "pallet-scheduler/std", + "pallet-session/std", "pallet-timestamp/std", - "pop-chain-extension/std", - "pop-primitives/std", + "pallet-transaction-payment/std", + "pop-runtime-devnet/std", "scale-info/std", - "sp-core/std", + "sp-io/std", "sp-runtime/std", - "sp-std/std", ] diff --git a/pop-sandbox/examples/flipper/lib.rs b/pop-sandbox/examples/flipper/lib.rs index 9e97465a..cf0352a9 100644 --- a/pop-sandbox/examples/flipper/lib.rs +++ b/pop-sandbox/examples/flipper/lib.rs @@ -18,7 +18,7 @@ mod flipper { } impl Flipper { - #[ink(constructor)] + #[ink(constructor, payable)] pub fn new(init: bool) -> Self { debug_println!("Initializing contract with: `{init}`"); Self { value: init } @@ -49,9 +49,9 @@ mod tests { /// `drink` automatically discovers all the contract projects that your tests will need. For /// every such dependency (including the contract from the current crate), it will generate a - /// [`ContractBundle`](drink::session::ContractBundle) object that contains the compiled contract's code - /// and a special transcoder, which is used to encode and decode the contract's message - /// arguments. Such a bundle will be useful when deploying a contract. + /// [`ContractBundle`](drink::session::ContractBundle) object that contains the compiled + /// contract's code and a special transcoder, which is used to encode and decode the contract's + /// message arguments. Such a bundle will be useful when deploying a contract. /// /// To get a convenient way for obtaining such bundles, we can define an empty enum and mark /// it with the [`drink::contract_bundle_provider`](drink::contract_bundle_provider) attribute. @@ -70,9 +70,10 @@ mod tests { /// /// For convenience of using `?` operator, we mark the test function as returning a `Result`. /// - /// `drink::test` will already provide us with a `Session` object. It is a wrapper around a runtime and it exposes - /// a broad API for interacting with it. Session is generic over the runtime type, but usually and by default, we - /// use `MinimalSandbox`, which is a minimalistic runtime that allows using smart contracts. + /// `drink::test` will already provide us with a `Session` object. It is a wrapper around a + /// runtime and it exposes a broad API for interacting with it. Session is generic over the + /// runtime type, but usually and by default, we use `MinimalSandbox`, which is a minimalistic + /// runtime that allows using smart contracts. #[drink::test(sandbox = pop_sandbox::PopSandbox)] fn deploy_and_call_a_contract(mut session: Session) -> Result<(), Box> { let _ = env_logger::try_init(); diff --git a/pop-sandbox/examples/fungibles/Cargo.toml b/pop-sandbox/examples/fungibles/Cargo.toml deleted file mode 100644 index 075ea943..00000000 --- a/pop-sandbox/examples/fungibles/Cargo.toml +++ /dev/null @@ -1,37 +0,0 @@ -[package] -authors = [ "[your_name] <[your_email]>" ] -edition = "2021" -name = "api_example_fungibles" -version = "0.1.0" - -[dependencies] -ink = { version = "=5.0.0", default-features = false, features = [ "ink-debug" ] } -pop-api = { path = "../../../pop-api", default-features = false, features = [ - "fungibles", -] } -scale = { package = "parity-scale-codec", version = "3", default-features = false, features = [ - "derive", -] } -scale-info = { version = "2.6", default-features = false, features = [ - "derive", -], optional = true } - -[dev-dependencies] -drink = { path = "../../../../pop-drink/drink" } -env_logger = { version = "0.11.3" } -pop-sandbox = { path = "../../../pop-sandbox", default-features = false } - -[lib] -path = "lib.rs" - -[features] -default = [ "std" ] -e2e-tests = [ ] -ink-as-dependency = [ ] -std = [ - "ink/std", - "pop-api/std", - "pop-sandbox/std", - "scale-info/std", - "scale/std", -] diff --git a/pop-sandbox/examples/fungibles/lib.rs b/pop-sandbox/examples/fungibles/lib.rs deleted file mode 100644 index 2e976376..00000000 --- a/pop-sandbox/examples/fungibles/lib.rs +++ /dev/null @@ -1,75 +0,0 @@ -#![cfg_attr(not(feature = "std"), no_std, no_main)] - -use pop_api::{ - primitives::TokenId, - v0::fungibles::{self as api}, - StatusCode, -}; - -type PopApiResult = core::result::Result; - -#[ink::contract] -mod create_token_in_constructor { - use super::*; - - #[ink(storage)] - pub struct Fungible { - id: TokenId, - } - - impl Fungible { - #[ink(constructor, payable)] - pub fn new(id: TokenId, min_balance: Balance) -> PopApiResult { - ink::env::debug_println!("Fungible::call() asset_id={id}, min_balance={min_balance}"); - let contract = Self { id }; - let owner = contract.env().account_id(); - api::create(id, owner, min_balance)?; - Ok(contract) - } - - #[ink(message)] - pub fn token_exists(&self, id: TokenId) -> PopApiResult { - api::token_exists(id) - } - } -} - -/// We put `drink`-based tests as usual unit tests, into a test module. -#[cfg(test)] -mod tests { - use super::*; - use drink::session::{Session, NO_SALT}; - use pop_sandbox::utils::{call_function, ALICE}; - - #[drink::contract_bundle_provider] - enum BundleProvider {} - - #[drink::test(sandbox = pop_sandbox::PopSandbox)] - fn deploy_and_call_a_contract(mut session: Session) -> Result<(), Box> { - let _ = env_logger::try_init(); - let contract_bundle = BundleProvider::local()?; - - const ASSET_ID: TokenId = 1; - // Deploy a contract and create a new token with ASSET_ID = 1 - let contract_address = session.deploy_bundle( - contract_bundle, - "new", - &[1.to_string(), 1_000.to_string()], - NO_SALT, - Some(100_000_000), - )?; - // Calling the method in the contract. - let session = call_function( - session, - &contract_address, - &ALICE, - "token_exists".to_string(), - Some(vec![ASSET_ID.to_string()]), - None, - )?; - // Check that the token is created successfully. - let result = session.record().last_call_return_decoded::>()??; - assert_eq!(result, Ok(true)); - Ok(()) - } -} diff --git a/pop-sandbox/examples/proxy/Cargo.toml b/pop-sandbox/examples/proxy/Cargo.toml deleted file mode 100644 index 95adf32c..00000000 --- a/pop-sandbox/examples/proxy/Cargo.toml +++ /dev/null @@ -1,40 +0,0 @@ -[package] -authors = [ "[your_name] <[your_email]>" ] -edition = "2021" -name = "api_example_proxy" -version = "0.1.0" - -[dependencies] -codec = { package = "parity-scale-codec", version = "3", default-features = false, features = [ - "derive", -] } -frame-system = { version = "36.1.0", default-features = false } -ink = { version = "=5.0.0", default-features = false, features = [ "ink-debug" ] } -pop-api = { path = "../../../pop-api", default-features = false, features = [ - "fungibles", -] } -scale-info = { version = "2.6", default-features = false, features = [ - "derive", -], optional = true } - -[dev-dependencies] -drink = { path = "../../../../pop-drink/drink" } -env_logger = { version = "0.11.3" } -pop-sandbox = { path = "../../../pop-sandbox", default-features = false } -serde_json = "1.0.108" - -[lib] -path = "lib.rs" - -[features] -default = [ "std" ] -e2e-tests = [ ] -ink-as-dependency = [ ] -std = [ - "codec/std", - "frame-system/std", - "ink/std", - "pop-api/std", - "pop-sandbox/std", - "scale-info/std", -] diff --git a/pop-sandbox/examples/proxy/lib.rs b/pop-sandbox/examples/proxy/lib.rs deleted file mode 100644 index d5299045..00000000 --- a/pop-sandbox/examples/proxy/lib.rs +++ /dev/null @@ -1,94 +0,0 @@ -#![cfg_attr(not(feature = "std"), no_std, no_main)] - -use ink::{ - env::chain_extension::{ChainExtensionMethod, FromStatusCode}, - prelude::vec::Vec, -}; - -#[ink::contract] -mod proxy_contract { - use super::*; - - // Simple contract for proxying a call to a chain extension. - #[ink(storage)] - #[derive(Default)] - pub struct Proxy; - - impl Proxy { - #[ink(constructor)] - pub fn new() -> Self { - ink::env::debug_println!("Proxy::new()"); - Default::default() - } - - #[ink(message)] - pub fn call(&self, func_id: u32, input: Vec) -> Result, StatusCode> { - ink::env::debug_println!("Proxy::call() func_id={func_id}, input={input:?}"); - ChainExtensionMethod::build(func_id) - .input::>() - .output::, StatusCode>, true>() - .handle_error_code::() - .call(&input) - } - } - - #[ink::scale_derive(Encode, Decode, TypeInfo)] - pub struct StatusCode(u32); - impl FromStatusCode for StatusCode { - fn from_status_code(status_code: u32) -> Result<(), Self> { - match status_code { - 0 => Ok(()), - _ => Err(StatusCode(status_code)), - } - } - } - - impl From for StatusCode { - fn from(_: ink::scale::Error) -> Self { - StatusCode(u32::MAX) - } - } -} - -/// We put `drink`-based tests as usual unit tests, into a test module. -#[cfg(test)] -mod tests { - use codec::Encode; - use core::fmt::Debug; - use drink::{ - session::{Session, NO_ARGS, NO_SALT}, - AccountId32, - }; - use frame_system::Call; - use pop_sandbox::{ - utils::{call_function, ALICE}, - PopSandbox, RuntimeCall, - }; - - #[drink::contract_bundle_provider] - enum BundleProvider {} - - #[drink::test(sandbox = PopSandbox)] - fn deploy_contract_and_call(mut session: Session) -> Result<(), Box> { - let _ = env_logger::try_init(); - - let contract_bundle = BundleProvider::local()?; - let contract_address = - session.deploy_bundle(contract_bundle, "new", NO_ARGS, NO_SALT, None)?; - - let call = - RuntimeCall::System(Call::remark_with_event { remark: "pop".as_bytes().to_vec() }); - call_function( - session, - &contract_address, - &ALICE, - "call".to_string(), - // DispatchCall::System::Call::remark_with_event. - Some(vec![0.to_string(), serde_json::to_string(&call.encode()).unwrap()]), - None, - )?; - // TOOD: Return CallFiltered - - Ok(()) - } -} diff --git a/pop-sandbox/src/api/mod.rs b/pop-sandbox/src/api/mod.rs deleted file mode 100644 index ad4f8491..00000000 --- a/pop-sandbox/src/api/mod.rs +++ /dev/null @@ -1,159 +0,0 @@ -use core::marker::PhantomData; - -use codec::Decode; -use cumulus_primitives_core::Weight; -use frame_support::traits::Contains; -pub(crate) use pallet_api::Extension; -use pallet_api::{extension::*, Read}; -use sp_core::ConstU8; -use sp_runtime::DispatchError; -use sp_std::vec::Vec; -use versioning::*; - -use crate::{fungibles, Runtime, RuntimeCall, RuntimeEvent}; - -mod versioning; - -type DecodingFailedError = DecodingFailed; -type DecodesAs = pallet_api::extension::DecodesAs< - Output, - ContractWeightsOf, - DecodingFailedError, - Logger, ->; - -/// A query of runtime state. -#[derive(Decode, Debug)] -#[repr(u8)] -pub enum RuntimeRead { - /// Fungible token queries. - #[codec(index = 150)] - Fungibles(fungibles::Read), -} - -impl Readable for RuntimeRead { - /// The corresponding type carrying the result of the query for runtime state. - type Result = RuntimeResult; - - /// Determines the weight of the read, used to charge the appropriate weight before the read is - /// performed. - fn weight(&self) -> Weight { - match self { - RuntimeRead::Fungibles(key) => fungibles::Pallet::weight(key), - } - } - - /// Performs the read and returns the result. - fn read(self) -> Self::Result { - match self { - RuntimeRead::Fungibles(key) => RuntimeResult::Fungibles(fungibles::Pallet::read(key)), - } - } -} - -/// The result of a runtime state read. -#[derive(Debug)] -pub enum RuntimeResult { - /// Fungible token read results. - Fungibles(fungibles::ReadResult), -} - -impl RuntimeResult { - /// Encodes the result. - fn encode(&self) -> Vec { - match self { - RuntimeResult::Fungibles(result) => result.encode(), - } - } -} - -impl fungibles::Config for Runtime { - type AssetsInstance = (); - type RuntimeEvent = RuntimeEvent; - type WeightInfo = fungibles::weights::SubstrateWeight; -} - -#[derive(Default)] -pub struct Config; -impl pallet_api::extension::Config for Config { - /// Functions used by the Pop API. - /// - /// Each function corresponds to specific functionality provided by the API, facilitating the - /// interaction between smart contracts and the runtime. - type Functions = ( - // Dispatching calls - DispatchCall< - // Function ID: 0. - IdentifiedByFirstByteOfFunctionId>, - // The runtime configuration. - Runtime, - // Decode as a versioned runtime call. - DecodesAs, - // Apply any filtering. - Filter, - // Ensure errors are versioned. - VersionedErrorConverter, - // Logging with a specific target. - DispatchCallLogTarget, - >, - // Reading state - ReadState< - // Function ID: 1. - IdentifiedByFirstByteOfFunctionId>, - // The runtime configuration. - Runtime, - // The runtime state reads available. - RuntimeRead, - // Decode as a versioned runtime read. - DecodesAs, - // Apply any filtering. - Filter, - // Convert the result of a read into the expected versioned result - VersionedResultConverter, - // Ensure errors are versioned. - VersionedErrorConverter, - // Logging with a specific target. - ReadStateLogTarget, - >, - ); - - /// The log target. - const LOG_TARGET: &'static str = LOG_TARGET; -} - -/// Filters used by the chain extension. -pub struct Filter(PhantomData); - -impl> Contains for Filter { - fn contains(c: &RuntimeCall) -> bool { - use fungibles::Call::*; - T::BaseCallFilter::contains(c) - && matches!( - c, - RuntimeCall::Fungibles( - transfer { .. } - | transfer_from { .. } | approve { .. } - | increase_allowance { .. } - | decrease_allowance { .. } - | create { .. } | set_metadata { .. } - | start_destroy { .. } | clear_metadata { .. } - | mint { .. } | burn { .. } - ) - ) - } -} - -impl Contains for Filter { - fn contains(r: &RuntimeRead) -> bool { - use fungibles::Read::*; - matches!( - r, - RuntimeRead::Fungibles( - TotalSupply(..) - | BalanceOf { .. } | Allowance { .. } - | TokenName(..) | TokenSymbol(..) - | TokenDecimals(..) | TokenExists(..) - ) - ) - } -} diff --git a/pop-sandbox/src/api/versioning.rs b/pop-sandbox/src/api/versioning.rs deleted file mode 100644 index 317496df..00000000 --- a/pop-sandbox/src/api/versioning.rs +++ /dev/null @@ -1,220 +0,0 @@ -use sp_runtime::ModuleError; - -use super::*; - -type Version = u8; - -/// Versioned runtime calls. -#[derive(Decode, Debug)] -pub enum VersionedRuntimeCall { - /// Version zero of runtime calls. - #[codec(index = 0)] - V0(RuntimeCall), -} - -impl From for RuntimeCall { - fn from(value: VersionedRuntimeCall) -> Self { - // Allows mapping from some previous runtime call shape to a current valid runtime call - match value { - VersionedRuntimeCall::V0(call) => call, - } - } -} - -/// Versioned runtime state reads. -#[derive(Decode, Debug)] -pub enum VersionedRuntimeRead { - /// Version zero of runtime state reads. - #[codec(index = 0)] - V0(RuntimeRead), -} - -impl From for RuntimeRead { - fn from(value: VersionedRuntimeRead) -> Self { - // Allows mapping from some previous runtime read shape to a current valid runtime read - match value { - VersionedRuntimeRead::V0(read) => read, - } - } -} - -/// Versioned runtime state read results. -#[derive(Debug)] -pub enum VersionedRuntimeResult { - /// Version zero of runtime read results. - V0(RuntimeResult), -} - -impl From<(RuntimeResult, Version)> for VersionedRuntimeResult { - fn from(value: (RuntimeResult, Version)) -> Self { - let (result, version) = value; - match version { - // Allows mapping from current `RuntimeResult` to a specific/prior version - 0 => VersionedRuntimeResult::V0(result), - // TODO: should never occur due to version processing/validation when request received - _ => unimplemented!(), - } - } -} - -impl From for Vec { - fn from(result: VersionedRuntimeResult) -> Self { - match result { - // Simply unwrap and return the encoded result - VersionedRuntimeResult::V0(result) => result.encode(), - } - } -} - -/// Versioned errors. -#[derive(Debug)] -pub enum VersionedError { - /// Version zero of errors. - V0(pop_primitives::v0::Error), -} - -impl From<(DispatchError, Version)> for VersionedError { - fn from(value: (DispatchError, Version)) -> Self { - let (error, version) = value; - match version { - // Allows mapping from current `DispatchError` to a specific/prior version of `Error` - 0 => VersionedError::V0(V0Error::from(error).0), - // TODO: should never occur due to version processing/validation when request received - _ => unimplemented!(), - } - } -} - -impl From for u32 { - fn from(value: VersionedError) -> Self { - match value { - VersionedError::V0(error) => error.into(), - } - } -} - -struct V0Error(pop_primitives::v0::Error); -impl From for V0Error { - fn from(error: DispatchError) -> Self { - use pop_primitives::v0::*; - use sp_runtime::{ArithmeticError::*, TokenError::*, TransactionalError::*}; - use DispatchError::*; - // Mappings exist here to avoid taking a dependency of sp_runtime on pop-primitives - Self(match error { - Other(_message) => { - // Note: lossy conversion: message not used due to returned contract status code - // size limitation - Error::Other - }, - CannotLookup => Error::CannotLookup, - BadOrigin => Error::BadOrigin, - Module(error) => { - // Note: message not used - let ModuleError { index, error, message: _message } = error; - // Map `pallet-contracts::Error::DecodingFailed` to `Error::DecodingFailed` - if index as usize == - ::index() && - error == DECODING_FAILED_ERROR - { - Error::DecodingFailed - } else { - // Note: lossy conversion of error value due to returned contract status code - // size limitation - Error::Module { index, error: [error[0], error[1]] } - } - }, - ConsumerRemaining => Error::ConsumerRemaining, - NoProviders => Error::NoProviders, - TooManyConsumers => Error::TooManyConsumers, - Token(error) => Error::Token(match error { - FundsUnavailable => TokenError::FundsUnavailable, - OnlyProvider => TokenError::OnlyProvider, - BelowMinimum => TokenError::BelowMinimum, - CannotCreate => TokenError::CannotCreate, - UnknownAsset => TokenError::UnknownAsset, - Frozen => TokenError::Frozen, - Unsupported => TokenError::Unsupported, - CannotCreateHold => TokenError::CannotCreateHold, - NotExpendable => TokenError::NotExpendable, - Blocked => TokenError::Blocked, - }), - Arithmetic(error) => Error::Arithmetic(match error { - Underflow => ArithmeticError::Underflow, - Overflow => ArithmeticError::Overflow, - DivisionByZero => ArithmeticError::DivisionByZero, - }), - Transactional(error) => Error::Transactional(match error { - LimitReached => TransactionalError::LimitReached, - NoLayer => TransactionalError::NoLayer, - }), - Exhausted => Error::Exhausted, - Corruption => Error::Corruption, - Unavailable => Error::Unavailable, - RootNotAllowed => Error::RootNotAllowed, - }) - } -} - -#[cfg(test)] -mod tests { - use pop_primitives::{ArithmeticError::*, Error, TokenError::*, TransactionalError::*}; - use sp_runtime::ModuleError; - use DispatchError::*; - - use super::*; - - // Compare all the different `DispatchError` variants with the expected `Error`. - #[test] - fn dispatch_error_to_error() { - let test_cases = vec![ - (Other(""), (Error::Other)), - (Other("UnknownCall"), Error::Other), - (Other("DecodingFailed"), Error::Other), - (Other("Random"), (Error::Other)), - (CannotLookup, Error::CannotLookup), - (BadOrigin, Error::BadOrigin), - ( - Module(ModuleError { index: 1, error: [2, 0, 0, 0], message: Some("hallo") }), - Error::Module { index: 1, error: [2, 0] }, - ), - ( - Module(ModuleError { index: 1, error: [2, 2, 0, 0], message: Some("hallo") }), - Error::Module { index: 1, error: [2, 2] }, - ), - ( - Module(ModuleError { index: 1, error: [2, 2, 2, 0], message: Some("hallo") }), - Error::Module { index: 1, error: [2, 2] }, - ), - ( - Module(ModuleError { index: 1, error: [2, 2, 2, 4], message: Some("hallo") }), - Error::Module { index: 1, error: [2, 2] }, - ), - (pallet_contracts::Error::::DecodingFailed.into(), Error::DecodingFailed), - (ConsumerRemaining, Error::ConsumerRemaining), - (NoProviders, Error::NoProviders), - (TooManyConsumers, Error::TooManyConsumers), - (Token(sp_runtime::TokenError::BelowMinimum), Error::Token(BelowMinimum)), - (Arithmetic(sp_runtime::ArithmeticError::Overflow), Error::Arithmetic(Overflow)), - ( - Transactional(sp_runtime::TransactionalError::LimitReached), - Error::Transactional(LimitReached), - ), - (Exhausted, Error::Exhausted), - (Corruption, Error::Corruption), - (Unavailable, Error::Unavailable), - (RootNotAllowed, Error::RootNotAllowed), - ]; - for (dispatch_error, expected) in test_cases { - let error = V0Error::from(dispatch_error).0; - assert_eq!(error, expected); - } - } - - #[test] - fn decoding_failed_error_encoding_works() { - let Module(error) = pallet_contracts::Error::::DecodingFailed.into() else { - unreachable!() - }; - assert_eq!(error.error, DECODING_FAILED_ERROR) - } -} diff --git a/pop-sandbox/src/lib.rs b/pop-sandbox/src/lib.rs index 118ebaa6..5a083c4a 100644 --- a/pop-sandbox/src/lib.rs +++ b/pop-sandbox/src/lib.rs @@ -1,179 +1,142 @@ -use crate::api::Config; +use core::any::Any; + +use frame_metadata::RuntimeMetadataPrefixed; use frame_support::{ - construct_runtime, derive_impl, parameter_types, - sp_runtime::{testing::H256, Perbill}, - traits::{AsEnsureOriginWithArg, ConstBool, ConstU128, ConstU32, Randomness}, - weights::Weight, + sp_runtime::{traits::Header, AccountId32}, + traits::Hooks, }; -use frame_system::{EnsureRoot, EnsureSigned}; -use pallet_api::fungibles; -use pallet_contracts::{DefaultAddressGenerator, Frame}; -use sp_runtime::traits::{AccountIdLookup, Convert}; -use sp_std::vec::Vec; +use frame_system::pallet_prelude::BlockNumberFor; +use pop_runtime_devnet::{BuildStorage, Runtime}; +use sp_io::TestExternalities; +use frame_support::sp_runtime::traits::One; +use pop_runtime_devnet::Balance; -mod api; // Provides utlity methods to interact with the sandbox. pub mod utils; -pub(crate) type AccountId = AccountId32; -pub(crate) type AssetId = u32; -pub(crate) type Balance = u128; +/// Alias for the account ID type. +pub type AccountIdFor = ::AccountId; -pub const MILLIUNIT: Balance = UNIT / 1_000; // 10_000_000 +/// Default initial balance for the default account. +pub const UNIT: Balance = 10_000_000_000; +pub const INIT_AMOUNT: Balance = 100_000_000 * UNIT; +pub const INIT_VALUE: Balance = 100 * UNIT; +pub const ALICE: AccountId32 = AccountId32::new([1u8; 32]); -pub const fn deposit(items: u32, bytes: u32) -> Balance { - (items as Balance * UNIT + (bytes as Balance) * (5 * MILLIUNIT / 100)) / 10 -} +/// A helper struct for initializing and finalizing blocks. +pub struct BlockBuilder(std::marker::PhantomData); + +impl< + T: pallet_balances::Config + pallet_timestamp::Config + pallet_contracts::Config + pallet_aura::Config, + > BlockBuilder +{ + /// Create a new externalities with the given balances. + pub fn new_ext(balances: Vec<(T::AccountId, T::Balance)>) -> TestExternalities { + log::debug!("new externalities: balances={:?}", balances); + let mut storage = frame_system::GenesisConfig::::default().build_storage().unwrap(); -// Define the runtime type as a collection of pallets -construct_runtime!( - pub enum Runtime { - System: frame_system, - Assets: pallet_assets, - Balances: pallet_balances, - Timestamp: pallet_timestamp, - Contracts: pallet_contracts, - Fungibles: fungibles = 150, + pallet_balances::GenesisConfig:: { balances } + .assimilate_storage(&mut storage) + .unwrap(); + + let mut ext = TestExternalities::new(storage); + + ext.execute_with(|| Self::initialize_block(BlockNumberFor::::one(), Default::default())); + ext } -); -parameter_types! { - pub const BlockHashCount: u64 = 250; - pub const SS58Prefix: u8 = 42; -} + /// Initialize a new block at particular height. + pub fn initialize_block( + height: frame_system::pallet_prelude::BlockNumberFor, + parent_hash: ::Hash, + ) { + frame_system::Pallet::::reset_events(); + frame_system::Pallet::::initialize(&height, &parent_hash, &Default::default()); + pallet_balances::Pallet::::on_initialize(height); + pallet_aura::Pallet::::on_initialize(height); + // TODO: Resolve an issue with pallet-aura to simulate the time. + // pallet_timestamp::Pallet::::set_timestamp( + // SystemTime::now() + // .duration_since(SystemTime::UNIX_EPOCH) + // .expect("Time went backwards") + // .as_secs(), + // ); + pallet_timestamp::Pallet::::on_initialize(height); + pallet_contracts::Pallet::::on_initialize(height); + frame_system::Pallet::::note_finished_initialize(); + } -#[derive_impl(frame_system::config_preludes::TestDefaultConfig as frame_system::DefaultConfig)] -impl frame_system::Config for Runtime { - type AccountData = pallet_balances::AccountData<::Balance>; - type AccountId = AccountId; - type Block = frame_system::mocking::MockBlock; - type Lookup = AccountIdLookup; + /// Finalize a block at particular height. + pub fn finalize_block( + height: frame_system::pallet_prelude::BlockNumberFor, + ) -> ::Hash { + pallet_contracts::Pallet::::on_finalize(height); + pallet_timestamp::Pallet::::on_finalize(height); + pallet_balances::Pallet::::on_finalize(height); + frame_system::Pallet::::finalize().hash() + } } -#[derive_impl(pallet_balances::config_preludes::TestDefaultConfig as pallet_balances::DefaultConfig)] -impl pallet_balances::Config for Runtime { - type AccountStore = System; - type Balance = Balance; - type ExistentialDeposit = ConstU128<1>; - type ReserveIdentifier = [u8; 8]; +pub struct PopSandbox { + ext: TestExternalities, } -parameter_types! { - pub const AssetDeposit: u128 = 1; - pub const AssetAccountDeposit: u128 = 10; - pub const ApprovalDeposit: u128 = 1; - pub const AssetsStringLimit: u32 = 50; - pub const MetadataDepositBase: u128 = 1; - pub const MetadataDepositPerByte: u128 = 1; +impl Default for PopSandbox { + fn default() -> Self { + let balances : Vec<(AccountId32, u128)> = vec![(ALICE, INIT_AMOUNT)]; + let ext = BlockBuilder::::new_ext(balances); + Self { ext } + } } -impl pallet_assets::Config for Runtime { - type RuntimeEvent = RuntimeEvent; - type Balance = Balance; - type RemoveItemsLimit = ConstU32<5>; - type AssetId = AssetId; - type AssetIdParameter = u32; - type Currency = Balances; - type CreateOrigin = AsEnsureOriginWithArg>; - type ForceOrigin = EnsureRoot; - type AssetDeposit = ConstU128<1>; - type AssetAccountDeposit = ConstU128<10>; - type MetadataDepositBase = ConstU128<1>; - type MetadataDepositPerByte = ConstU128<1>; - type ApprovalDeposit = ConstU128<1>; - type StringLimit = ConstU32<50>; - type Freezer = (); - type Extra = (); - type CallbackHandle = (); - type WeightInfo = (); - #[cfg(feature = "runtime-benchmarks")] - type BenchmarkHelper = (); -} +impl drink::Sandbox for PopSandbox { + type Runtime = Runtime; -#[derive_impl(pallet_timestamp::config_preludes::TestDefaultConfig as pallet_timestamp::DefaultConfig)] -impl pallet_timestamp::Config for Runtime {} + fn execute_with(&mut self, execute: impl FnOnce() -> T) -> T { + self.ext.execute_with(execute) + } -// Configure pallet contracts -impl Randomness for Runtime { - fn random(_subject: &[u8]) -> (H256, u64) { - (Default::default(), Default::default()) + fn dry_run(&mut self, action: impl FnOnce(&mut Self) -> T) -> T { + // Make a backup of the backend. + let backend_backup = self.ext.as_backend(); + // Run the action, potentially modifying storage. Ensure, that there are no pending changes + // that would affect the reverted backend. + let result = action(self); + self.ext.commit_all().expect("Failed to commit changes"); + + // Restore the backend. + self.ext.backend = backend_backup; + result } -} -// Configure pallet contracts -pub enum SandboxRandomness {} -impl Randomness for SandboxRandomness { - fn random(_subject: &[u8]) -> (H256, u64) { - unreachable!("No randomness") + fn register_extension(&mut self, ext: E) { + self.ext.register_extension(ext); } -} -type BalanceOf = ::Balance; -impl Convert for Runtime { - fn convert(w: Weight) -> BalanceOf { - w.ref_time().into() + fn initialize_block( + height: frame_system::pallet_prelude::BlockNumberFor, + parent_hash: ::Hash, + ) { + BlockBuilder::::initialize_block(height, parent_hash) } -} -fn schedule() -> pallet_contracts::Schedule { - pallet_contracts::Schedule { - limits: pallet_contracts::Limits { - runtime_memory: 1024 * 1024 * 1024, - ..Default::default() - }, - ..Default::default() + fn finalize_block( + height: frame_system::pallet_prelude::BlockNumberFor, + ) -> ::Hash { + BlockBuilder::::finalize_block(height) } -} -parameter_types! { - pub const DepositPerItem: Balance = deposit(1, 0); - pub const DepositPerByte: Balance = deposit(0, 1); - pub Schedule: pallet_contracts::Schedule = schedule::(); - pub const DefaultDepositLimit: Balance = deposit(1024, 1024 * 1024); - pub const CodeHashLockupDepositPercent: Perbill = Perbill::from_percent(0); -} + fn default_actor() -> AccountIdFor { + ALICE + } -impl pallet_contracts::Config for Runtime { - type AddressGenerator = DefaultAddressGenerator; - type ApiVersion = (); - // C - type CallFilter = (); - type CallStack = [Frame; 23]; - type ChainExtension = api::Extension; - type CodeHashLockupDepositPercent = CodeHashLockupDepositPercent; - type Currency = Balances; - // D - type Debug = drink::pallet_contracts_debugging::DrinkDebug; - type DefaultDepositLimit = DefaultDepositLimit; - type DepositPerByte = DepositPerByte; - type DepositPerItem = DepositPerItem; - // E - type Environment = (); - // I - type InstantiateOrigin = EnsureSigned; - // M - type MaxCodeLen = ConstU32<{ 256 * 1024 }>; - type MaxDebugBufferLen = ConstU32<{ 2 * 1024 * 1024 }>; - type MaxDelegateDependencies = ConstU32<32>; - type MaxStorageKeyLen = ConstU32<128>; - type Migrations = (); - // R - type Randomness = SandboxRandomness; - type RuntimeCall = RuntimeCall; - type RuntimeEvent = RuntimeEvent; - type RuntimeHoldReason = RuntimeHoldReason; - // S - type Schedule = Schedule; - // T - type Time = Timestamp; - // U - type UnsafeUnstableInterface = ConstBool; - type UploadOrigin = EnsureSigned; - // W - type WeightInfo = (); - type WeightPrice = Self; - // X - type Xcm = (); -} + fn get_metadata() -> RuntimeMetadataPrefixed { + Self::Runtime::metadata() + } -drink::create_sandbox!(PopSandbox, Runtime); + fn convert_account_to_origin( + account: AccountIdFor, + ) -> <::RuntimeCall as frame_support::sp_runtime::traits::Dispatchable>::RuntimeOrigin{ + Some(account).into() + } +} diff --git a/pop-sandbox/src/utils.rs b/pop-sandbox/src/utils.rs index 8a8085ac..3d67da8b 100644 --- a/pop-sandbox/src/utils.rs +++ b/pop-sandbox/src/utils.rs @@ -1,13 +1,12 @@ +use std::error::Error; + use drink::{ session::{Session, NO_ARGS}, AccountId32, }; -use std::error::Error; use super::*; -pub const ALICE: AccountId32 = AccountId32::new([1_u8; 32]); - // TODO: Convert this method to accept generic runtime instead of `PopSandbox`. pub fn call_function( mut sess: Session, diff --git a/runtime/devnet/src/config/api/versioning.rs b/runtime/devnet/src/config/api/versioning.rs index 7c3d9ee5..317496df 100644 --- a/runtime/devnet/src/config/api/versioning.rs +++ b/runtime/devnet/src/config/api/versioning.rs @@ -112,9 +112,9 @@ impl From for V0Error { // Note: message not used let ModuleError { index, error, message: _message } = error; // Map `pallet-contracts::Error::DecodingFailed` to `Error::DecodingFailed` - if index as usize - == ::index() - && error == DECODING_FAILED_ERROR + if index as usize == + ::index() && + error == DECODING_FAILED_ERROR { Error::DecodingFailed } else { From 0399d46429d99a3c3aa6debefee82db165832ba5 Mon Sep 17 00:00:00 2001 From: chungquantin <56880684+chungquantin@users.noreply.github.com> Date: Thu, 12 Sep 2024 13:18:08 +0700 Subject: [PATCH 064/112] refactor: fungible example contract --- pop-api/examples/fungibles/lib.rs | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/pop-api/examples/fungibles/lib.rs b/pop-api/examples/fungibles/lib.rs index 00f02914..f1171ffe 100644 --- a/pop-api/examples/fungibles/lib.rs +++ b/pop-api/examples/fungibles/lib.rs @@ -10,22 +10,20 @@ use pop_api::{ type PopApiResult = core::result::Result; #[ink::contract] -mod create_token_in_constructor { +mod fungibles { use super::*; #[ink(storage)] - pub struct Fungible { - id: TokenId, - } + #[derive(Default)] + pub struct Fungibles; - impl Fungible { + impl Fungibles { #[ink(constructor, payable)] pub fn new(id: TokenId, min_balance: Balance) -> PopApiResult { ink::env::debug_println!("Fungible::call() asset_id={id}, min_balance={min_balance}"); - let contract = Self { id }; - let owner = contract.env().account_id(); + let owner = Self::env().account_id(); api::create(id, owner, min_balance)?; - Ok(contract) + Ok(Default::default()) } #[ink(message)] From 5fdf406e7e056b8a3ac2b94033147b3a451f1409 Mon Sep 17 00:00:00 2001 From: chungquantin <56880684+chungquantin@users.noreply.github.com> Date: Thu, 12 Sep 2024 13:35:14 +0700 Subject: [PATCH 065/112] refactor: fungible test --- pop-api/examples/fungibles/lib.rs | 72 +++++++++++++++++++------------ pop-sandbox/src/lib.rs | 3 -- pop-sandbox/src/utils.rs | 39 ----------------- 3 files changed, 45 insertions(+), 69 deletions(-) delete mode 100644 pop-sandbox/src/utils.rs diff --git a/pop-api/examples/fungibles/lib.rs b/pop-api/examples/fungibles/lib.rs index f1171ffe..7977e58d 100644 --- a/pop-api/examples/fungibles/lib.rs +++ b/pop-api/examples/fungibles/lib.rs @@ -19,16 +19,8 @@ mod fungibles { impl Fungibles { #[ink(constructor, payable)] - pub fn new(id: TokenId, min_balance: Balance) -> PopApiResult { - ink::env::debug_println!("Fungible::call() asset_id={id}, min_balance={min_balance}"); - let owner = Self::env().account_id(); - api::create(id, owner, min_balance)?; - Ok(Default::default()) - } - - #[ink(message)] - pub fn token_exists(&self, id: TokenId) -> PopApiResult { - api::token_exists(id) + pub fn new() -> Self { + Default::default() } #[ink(message)] @@ -113,14 +105,40 @@ mod fungibles { pub fn token_decimals(&self, id: TokenId) -> PopApiResult { api::token_decimals(id) } + + #[ink(message, payable)] + pub fn create( + &self, + id: TokenId, + admin: AccountId, + min_balance: Balance, + ) -> PopApiResult<()> { + api::create(id, admin, min_balance) + } + + #[ink(message)] + pub fn set_metadata( + &self, + id: TokenId, + name: Vec, + symbol: Vec, + decimals: u8, + ) -> PopApiResult<()> { + api::set_metadata(id, name, symbol, decimals) + } + + #[ink(message)] + pub fn token_exists(&self, id: TokenId) -> PopApiResult { + api::token_exists(id) + } } } /// We put `drink`-based tests as usual unit tests, into a test module. #[cfg(test)] mod tests { - use drink::session::{Session, NO_SALT}; - use pop_sandbox::{utils::call_function, ALICE, INIT_VALUE}; + use drink::session::{Session, NO_ARGS, NO_SALT}; + use pop_sandbox::{ALICE, INIT_VALUE}; use super::*; @@ -134,23 +152,23 @@ mod tests { const ASSET_ID: TokenId = 1; - // Deploy a contract and create a new token with ASSET_ID = 1 - let contract_address = session.deploy_bundle( - contract_bundle, - "new", - &[ASSET_ID.to_string(), 1.to_string()], - NO_SALT, - Some(INIT_VALUE), - )?; + // Deploy a contract. + let contract_address = + session.deploy_bundle(contract_bundle, "new", NO_ARGS, NO_SALT, Some(INIT_VALUE))?; + // Calling the method in the contract. + session.call_with_address( + contract_address.clone(), + "create", + &vec![ASSET_ID.to_string(), ALICE.to_string(), 10_000.to_string()], + None, + )??; // Calling the method in the contract. - let session = call_function( - session, - &contract_address, - &ALICE, - "token_exists".to_string(), - Some(vec![ASSET_ID.to_string()]), + session.call_with_address( + contract_address.clone(), + "token_exists", + &vec![ASSET_ID.to_string()], None, - )?; + )??; // Check that the token is created successfully. let result = session.record().last_call_return_decoded::>()??; assert_eq!(result, Ok(true)); diff --git a/pop-sandbox/src/lib.rs b/pop-sandbox/src/lib.rs index 5a083c4a..4b7e47f5 100644 --- a/pop-sandbox/src/lib.rs +++ b/pop-sandbox/src/lib.rs @@ -11,9 +11,6 @@ use sp_io::TestExternalities; use frame_support::sp_runtime::traits::One; use pop_runtime_devnet::Balance; -// Provides utlity methods to interact with the sandbox. -pub mod utils; - /// Alias for the account ID type. pub type AccountIdFor = ::AccountId; diff --git a/pop-sandbox/src/utils.rs b/pop-sandbox/src/utils.rs deleted file mode 100644 index 3d67da8b..00000000 --- a/pop-sandbox/src/utils.rs +++ /dev/null @@ -1,39 +0,0 @@ -use std::error::Error; - -use drink::{ - session::{Session, NO_ARGS}, - AccountId32, -}; - -use super::*; - -// TODO: Convert this method to accept generic runtime instead of `PopSandbox`. -pub fn call_function( - mut sess: Session, - contract: &AccountId32, - sender: &AccountId32, - func_name: String, - args: Option>, - value: Option, -) -> Result, Box> { - sess.set_actor(sender.clone()); - if let Some(args) = args { - println!("Calling function: {}() | Input: {:?}", func_name, args); - sess.call_with_address(contract.clone(), &func_name, &args, value)??; - } else { - println!("Calling function: {}() | Input: None", func_name); - sess.call_with_address(contract.clone(), &func_name, NO_ARGS, value)??; - } - - let encoded = &sess.record().last_call_result().result.clone().unwrap().data; - let decoded = encoded.iter().map(|b| *b as char).collect::(); - let messages: Vec = decoded.split('\n').map(|s| s.to_string()).collect(); - // Print debug logs - for line in messages { - if line.len() > 0 { - println!("LOG: {}", line); - } - } - - Ok(sess) -} From ed7146bc56d9a9173e8d8e28a9e2bf6afd4fb0fa Mon Sep 17 00:00:00 2001 From: chungquantin <56880684+chungquantin@users.noreply.github.com> Date: Thu, 12 Sep 2024 17:41:50 +0700 Subject: [PATCH 066/112] fix: fungible contract --- pop-api/examples/fungibles/lib.rs | 47 +++++++++++-------- pop-sandbox/Cargo.toml | 11 +---- pop-sandbox/src/lib.rs | 76 +++++-------------------------- 3 files changed, 40 insertions(+), 94 deletions(-) diff --git a/pop-api/examples/fungibles/lib.rs b/pop-api/examples/fungibles/lib.rs index 7977e58d..6ba396f4 100644 --- a/pop-api/examples/fungibles/lib.rs +++ b/pop-api/examples/fungibles/lib.rs @@ -138,39 +138,48 @@ mod fungibles { #[cfg(test)] mod tests { use drink::session::{Session, NO_ARGS, NO_SALT}; - use pop_sandbox::{ALICE, INIT_VALUE}; + use pop_sandbox::{Balance, PopSandbox, ALICE, INIT_VALUE}; + use scale::Decode; use super::*; #[drink::contract_bundle_provider] enum BundleProvider {} - #[drink::test(sandbox = pop_sandbox::PopSandbox)] - fn deploy_and_call_a_contract(mut session: Session) -> Result<(), Box> { + fn decoded_call( + session: &mut Session, + func_name: &str, + input: Vec, + endowment: Option, + ) -> Result> { + session.call(func_name, &input, endowment)??; + Ok(session.record().last_call_return_decoded::()??) + } + + #[drink::test(sandbox = PopSandbox)] + fn test_create_token_works(mut session: Session) -> Result<(), Box> { let _ = env_logger::try_init(); let contract_bundle = BundleProvider::local()?; - const ASSET_ID: TokenId = 1; - // Deploy a contract. - let contract_address = - session.deploy_bundle(contract_bundle, "new", NO_ARGS, NO_SALT, Some(INIT_VALUE))?; - // Calling the method in the contract. - session.call_with_address( - contract_address.clone(), + session.deploy_bundle(contract_bundle, "new", NO_ARGS, NO_SALT, Some(INIT_VALUE))?; + + const TOKEN_ID: TokenId = 1; + // Create a new token. + let _ = decoded_call::>( + &mut session, "create", - &vec![ASSET_ID.to_string(), ALICE.to_string(), 10_000.to_string()], + vec![TOKEN_ID.to_string(), ALICE.to_string(), 10_000.to_string()], None, - )??; - // Calling the method in the contract. - session.call_with_address( - contract_address.clone(), + )?; + + // Check that the token is created successfully. + let result = decoded_call::>( + &mut session, "token_exists", - &vec![ASSET_ID.to_string()], + vec![TOKEN_ID.to_string()], None, - )??; - // Check that the token is created successfully. - let result = session.record().last_call_return_decoded::>()??; + )?; assert_eq!(result, Ok(true)); Ok(()) } diff --git a/pop-sandbox/Cargo.toml b/pop-sandbox/Cargo.toml index d2309173..7a65f593 100644 --- a/pop-sandbox/Cargo.toml +++ b/pop-sandbox/Cargo.toml @@ -1,4 +1,5 @@ [package] +authors = [ "[your_name] <[your_email]>" ] description = "Sandboxing environment for contract quasi testing with Pop Network runtimes." edition = "2021" license = "GPL-3.0-only" @@ -20,14 +21,9 @@ frame-support = { version = "36.0.0", default-features = false } frame-support-procedural = { version = "=30.0.1", default-features = false } frame-system = { version = "36.1.0", default-features = false } pallet-assets = { version = "37.0.0", default-features = false } -pallet-aura = { version = "35.0.0", default-features = false } -pallet-authorship = { version = "36.0.0", default-features = false } pallet-balances = { version = "37.0.0", default-features = false } pallet-contracts = { version = "35.0.0", default-features = false } -pallet-scheduler = { version = "37.0.0", default-features = false } -pallet-session = { version = "36.0.0", default-features = false } pallet-timestamp = { version = "35.0.0", default-features = false } -pallet-transaction-payment = { version = "36.0.0", default-features = false } pop-runtime-devnet = { path = "../runtime/devnet", default-features = false } sp-io = { version = "37.0.0", default-features = false } sp-runtime = { version = "=38.0.0", default-features = false } @@ -44,14 +40,9 @@ std = [ "frame-support/std", "frame-system/std", "pallet-assets/std", - "pallet-aura/std", - "pallet-authorship/std", "pallet-balances/std", "pallet-contracts/std", - "pallet-scheduler/std", - "pallet-session/std", "pallet-timestamp/std", - "pallet-transaction-payment/std", "pop-runtime-devnet/std", "scale-info/std", "sp-io/std", diff --git a/pop-sandbox/src/lib.rs b/pop-sandbox/src/lib.rs index 4b7e47f5..285c5774 100644 --- a/pop-sandbox/src/lib.rs +++ b/pop-sandbox/src/lib.rs @@ -1,15 +1,13 @@ -use core::any::Any; - -use frame_metadata::RuntimeMetadataPrefixed; use frame_support::{ - sp_runtime::{traits::Header, AccountId32}, + sp_runtime::{ + traits::{Header, One}, + AccountId32, + }, traits::Hooks, }; use frame_system::pallet_prelude::BlockNumberFor; +pub use pop_runtime_devnet::Balance; use pop_runtime_devnet::{BuildStorage, Runtime}; -use sp_io::TestExternalities; -use frame_support::sp_runtime::traits::One; -use pop_runtime_devnet::Balance; /// Alias for the account ID type. pub type AccountIdFor = ::AccountId; @@ -24,19 +22,18 @@ pub const ALICE: AccountId32 = AccountId32::new([1u8; 32]); pub struct BlockBuilder(std::marker::PhantomData); impl< - T: pallet_balances::Config + pallet_timestamp::Config + pallet_contracts::Config + pallet_aura::Config, + T: pallet_balances::Config + pallet_timestamp::Config + pallet_contracts::Config, > BlockBuilder { /// Create a new externalities with the given balances. - pub fn new_ext(balances: Vec<(T::AccountId, T::Balance)>) -> TestExternalities { - log::debug!("new externalities: balances={:?}", balances); + pub fn new_ext(balances: Vec<(T::AccountId, T::Balance)>) -> sp_io::TestExternalities { let mut storage = frame_system::GenesisConfig::::default().build_storage().unwrap(); pallet_balances::GenesisConfig:: { balances } .assimilate_storage(&mut storage) .unwrap(); - let mut ext = TestExternalities::new(storage); + let mut ext = sp_io::TestExternalities::new(storage); ext.execute_with(|| Self::initialize_block(BlockNumberFor::::one(), Default::default())); ext @@ -50,7 +47,6 @@ impl< frame_system::Pallet::::reset_events(); frame_system::Pallet::::initialize(&height, &parent_hash, &Default::default()); pallet_balances::Pallet::::on_initialize(height); - pallet_aura::Pallet::::on_initialize(height); // TODO: Resolve an issue with pallet-aura to simulate the time. // pallet_timestamp::Pallet::::set_timestamp( // SystemTime::now() @@ -75,65 +71,15 @@ impl< } pub struct PopSandbox { - ext: TestExternalities, + ext: sp_io::TestExternalities, } impl Default for PopSandbox { fn default() -> Self { - let balances : Vec<(AccountId32, u128)> = vec![(ALICE, INIT_AMOUNT)]; + let balances: Vec<(AccountId32, u128)> = vec![(ALICE, INIT_AMOUNT)]; let ext = BlockBuilder::::new_ext(balances); Self { ext } } } -impl drink::Sandbox for PopSandbox { - type Runtime = Runtime; - - fn execute_with(&mut self, execute: impl FnOnce() -> T) -> T { - self.ext.execute_with(execute) - } - - fn dry_run(&mut self, action: impl FnOnce(&mut Self) -> T) -> T { - // Make a backup of the backend. - let backend_backup = self.ext.as_backend(); - // Run the action, potentially modifying storage. Ensure, that there are no pending changes - // that would affect the reverted backend. - let result = action(self); - self.ext.commit_all().expect("Failed to commit changes"); - - // Restore the backend. - self.ext.backend = backend_backup; - result - } - - fn register_extension(&mut self, ext: E) { - self.ext.register_extension(ext); - } - - fn initialize_block( - height: frame_system::pallet_prelude::BlockNumberFor, - parent_hash: ::Hash, - ) { - BlockBuilder::::initialize_block(height, parent_hash) - } - - fn finalize_block( - height: frame_system::pallet_prelude::BlockNumberFor, - ) -> ::Hash { - BlockBuilder::::finalize_block(height) - } - - fn default_actor() -> AccountIdFor { - ALICE - } - - fn get_metadata() -> RuntimeMetadataPrefixed { - Self::Runtime::metadata() - } - - fn convert_account_to_origin( - account: AccountIdFor, - ) -> <::RuntimeCall as frame_support::sp_runtime::traits::Dispatchable>::RuntimeOrigin{ - Some(account).into() - } -} +drink::impl_sandbox!(PopSandbox, Runtime, BlockBuilder, ALICE); From 7ce06746b468ddf2ed667f6bb45d28b6cdc063be Mon Sep 17 00:00:00 2001 From: chungquantin <56880684+chungquantin@users.noreply.github.com> Date: Thu, 12 Sep 2024 23:22:23 +0700 Subject: [PATCH 067/112] test: drink tests for fungible use case --- pop-api/examples/fungibles/lib.rs | 132 +++++++---------- pop-api/examples/fungibles/tests.rs | 211 ++++++++++++++++++++++++++++ pop-api/src/primitives.rs | 6 + pop-sandbox/README.md | 46 ++++++ pop-sandbox/src/lib.rs | 14 +- 5 files changed, 324 insertions(+), 85 deletions(-) create mode 100644 pop-api/examples/fungibles/tests.rs create mode 100644 pop-sandbox/README.md diff --git a/pop-api/examples/fungibles/lib.rs b/pop-api/examples/fungibles/lib.rs index 6ba396f4..649a8b64 100644 --- a/pop-api/examples/fungibles/lib.rs +++ b/pop-api/examples/fungibles/lib.rs @@ -7,6 +7,9 @@ use pop_api::{ StatusCode, }; +#[cfg(test)] +mod tests; + type PopApiResult = core::result::Result; #[ink::contract] @@ -24,23 +27,23 @@ mod fungibles { } #[ink(message)] - pub fn total_supply(&self, id: TokenId) -> PopApiResult { - api::total_supply(id) - } - - #[ink(message)] - pub fn balance_of(&self, id: TokenId, owner: AccountId) -> PopApiResult { - api::balance_of(id, owner) + pub fn mint( + &mut self, + token: TokenId, + account: AccountId, + amount: Balance, + ) -> PopApiResult<()> { + api::mint(token, account, amount) } #[ink(message)] - pub fn allowance( - &self, - id: TokenId, - owner: AccountId, - spender: AccountId, - ) -> PopApiResult { - api::allowance(id, owner, spender) + pub fn burn( + &mut self, + token: TokenId, + account: AccountId, + amount: Balance, + ) -> PopApiResult<()> { + api::burn(token, account, amount) } #[ink(message)] @@ -91,21 +94,6 @@ mod fungibles { api::decrease_allowance(id, spender, value) } - #[ink(message)] - pub fn token_name(&self, id: TokenId) -> PopApiResult> { - api::token_name(id) - } - - #[ink(message)] - pub fn token_symbol(&self, id: TokenId) -> PopApiResult> { - api::token_symbol(id) - } - - #[ink(message)] - pub fn token_decimals(&self, id: TokenId) -> PopApiResult { - api::token_decimals(id) - } - #[ink(message, payable)] pub fn create( &self, @@ -113,7 +101,9 @@ mod fungibles { admin: AccountId, min_balance: Balance, ) -> PopApiResult<()> { - api::create(id, admin, min_balance) + api::create(id, admin, min_balance)?; + self.env().emit_event(api::events::Create { id, creator: admin, admin }); + Ok(()) } #[ink(message)] @@ -128,59 +118,43 @@ mod fungibles { } #[ink(message)] - pub fn token_exists(&self, id: TokenId) -> PopApiResult { - api::token_exists(id) + pub fn total_supply(&self, id: TokenId) -> PopApiResult { + api::total_supply(id) } - } -} -/// We put `drink`-based tests as usual unit tests, into a test module. -#[cfg(test)] -mod tests { - use drink::session::{Session, NO_ARGS, NO_SALT}; - use pop_sandbox::{Balance, PopSandbox, ALICE, INIT_VALUE}; - use scale::Decode; + #[ink(message)] + pub fn balance_of(&self, id: TokenId, owner: AccountId) -> PopApiResult { + api::balance_of(id, owner) + } - use super::*; + #[ink(message)] + pub fn allowance( + &self, + id: TokenId, + owner: AccountId, + spender: AccountId, + ) -> PopApiResult { + api::allowance(id, owner, spender) + } - #[drink::contract_bundle_provider] - enum BundleProvider {} - - fn decoded_call( - session: &mut Session, - func_name: &str, - input: Vec, - endowment: Option, - ) -> Result> { - session.call(func_name, &input, endowment)??; - Ok(session.record().last_call_return_decoded::()??) - } + #[ink(message)] + pub fn token_name(&self, id: TokenId) -> PopApiResult> { + api::token_name(id) + } + + #[ink(message)] + pub fn token_symbol(&self, id: TokenId) -> PopApiResult> { + api::token_symbol(id) + } - #[drink::test(sandbox = PopSandbox)] - fn test_create_token_works(mut session: Session) -> Result<(), Box> { - let _ = env_logger::try_init(); - let contract_bundle = BundleProvider::local()?; - - // Deploy a contract. - session.deploy_bundle(contract_bundle, "new", NO_ARGS, NO_SALT, Some(INIT_VALUE))?; - - const TOKEN_ID: TokenId = 1; - // Create a new token. - let _ = decoded_call::>( - &mut session, - "create", - vec![TOKEN_ID.to_string(), ALICE.to_string(), 10_000.to_string()], - None, - )?; - - // Check that the token is created successfully. - let result = decoded_call::>( - &mut session, - "token_exists", - vec![TOKEN_ID.to_string()], - None, - )?; - assert_eq!(result, Ok(true)); - Ok(()) + #[ink(message)] + pub fn token_decimals(&self, id: TokenId) -> PopApiResult { + api::token_decimals(id) + } + + #[ink(message)] + pub fn token_exists(&self, id: TokenId) -> PopApiResult { + api::token_exists(id) + } } } diff --git a/pop-api/examples/fungibles/tests.rs b/pop-api/examples/fungibles/tests.rs new file mode 100644 index 00000000..bca7b64f --- /dev/null +++ b/pop-api/examples/fungibles/tests.rs @@ -0,0 +1,211 @@ +use drink::session::{Session, NO_ARGS, NO_SALT}; +use pop_api::{ + primitives::{account_id_from_slice, TokenId}, + v0::fungibles::{self as api}, +}; +use pop_sandbox::{AccountId32, Balance, Sandbox, ALICE, BOB, INIT_VALUE}; +use scale::{Decode, Encode}; + +use super::*; + +const TOKEN_A_ID: TokenId = 1; +const TOKEN_B_ID: TokenId = 2; + +#[drink::contract_bundle_provider] +enum BundleProvider {} + +use test_methods::*; +// Utility methods to test the contract calls. +mod test_methods { + use super::*; + + // Call a contract method and decode the returned data. + pub(super) fn decoded_call( + session: &mut Session, + func_name: &str, + input: Vec, + endowment: Option, + ) -> Result> { + session.call(func_name, &input, endowment)??; + Ok(session.record().last_call_return_decoded::()??) + } + + // Check if the event emitted correctly. + pub(super) fn assert_event(session: &mut Session, event: Vec) { + let contract_events = session.record().last_event_batch().contract_events(); + let last_event = contract_events.last().unwrap().to_vec(); + assert_eq!(last_event, event.as_slice()); + } + + pub(super) fn mint( + session: &mut Session, + token: TokenId, + account: AccountId32, + amount: Balance, + ) -> Result<(), Box> { + Ok(session.call( + "mint", + &vec![token.to_string(), account.to_string(), amount.to_string()], + None, + )??) + } + + pub(super) fn burn( + session: &mut Session, + token: TokenId, + account: AccountId32, + amount: Balance, + ) -> Result<(), Box> { + Ok(session.call( + "burn", + &vec![token.to_string(), account.to_string(), amount.to_string()], + None, + )??) + } + + pub(super) fn transfer( + session: &mut Session, + token: TokenId, + to: AccountId32, + amount: Balance, + ) -> Result<(), Box> { + Ok(session.call( + "transfer", + &vec![token.to_string(), to.to_string(), amount.to_string()], + None, + )??) + } + + pub(super) fn create( + session: &mut Session, + id: TokenId, + admin: AccountId32, + min_balance: Balance, + ) -> Result<(), Box> { + Ok(session.call( + "create", + &vec![id.to_string(), admin.to_string(), min_balance.to_string()], + None, + )??) + } + + pub(super) fn token_exist( + session: &mut Session, + id: TokenId, + ) -> Result, Box> { + Ok(decoded_call::>(session, "token_exists", vec![id.to_string()], None)?) + } + + pub(super) fn total_supply( + session: &mut Session, + id: TokenId, + ) -> Result, Box> { + Ok(decoded_call::>( + session, + "total_supply", + vec![id.to_string()], + None, + )?) + } + + pub(super) fn balance_of( + session: &mut Session, + id: TokenId, + owner: AccountId32, + ) -> Result, Box> { + Ok(decoded_call::>( + session, + "balance_of", + vec![id.to_string(), owner.to_string()], + None, + )?) + } +} + +#[drink::test(sandbox = Sandbox)] +fn test_create_multiple_token_works( + mut session: Session, +) -> Result<(), Box> { + let _ = env_logger::try_init(); + let contract_bundle = BundleProvider::local()?; + // Deploy a contract. + session.deploy_bundle(contract_bundle, "new", NO_ARGS, NO_SALT, Some(INIT_VALUE))?; + // Create new tokens. + create(&mut session, TOKEN_A_ID, ALICE, 1_000)?; + + assert_event( + &mut session, + api::events::Create { + id: TOKEN_A_ID, + admin: account_id_from_slice(ALICE.as_ref()), + creator: account_id_from_slice(ALICE.as_ref()), + } + .encode(), + ); + + create(&mut session, TOKEN_B_ID, ALICE, 2_000)?; + // Check that the token is created successfully. + assert_eq!(token_exist(&mut session, TOKEN_A_ID)?, Ok(true)); + assert_eq!(token_exist(&mut session, TOKEN_B_ID)?, Ok(true)); + Ok(()) +} + +#[drink::test(sandbox = Sandbox)] +fn test_mint_token_works(mut session: Session) -> Result<(), Box> { + let _ = env_logger::try_init(); + let contract_bundle = BundleProvider::local()?; + // Deploy a contract. + let contract_address = + session.deploy_bundle(contract_bundle, "new", NO_ARGS, NO_SALT, Some(INIT_VALUE))?; + // Create a new token. + create(&mut session, TOKEN_A_ID, contract_address, 10_000)?; + // Mint tokens. + const AMOUNT: Balance = 12_000; + mint(&mut session, TOKEN_A_ID, ALICE, AMOUNT)?; + mint(&mut session, TOKEN_A_ID, BOB, AMOUNT)?; + // Check if the tokens were minted with the right amount. + assert_eq!(total_supply(&mut session, TOKEN_A_ID)?, Ok(AMOUNT * 2)); + assert_eq!(balance_of(&mut session, TOKEN_A_ID, ALICE)?, Ok(AMOUNT)); + assert_eq!(balance_of(&mut session, TOKEN_A_ID, BOB)?, Ok(AMOUNT)); + Ok(()) +} + +#[drink::test(sandbox = Sandbox)] +fn test_burn_token_works(mut session: Session) -> Result<(), Box> { + let _ = env_logger::try_init(); + let contract_bundle = BundleProvider::local()?; + // Deploy a contract. + let contract_address = + session.deploy_bundle(contract_bundle, "new", NO_ARGS, NO_SALT, Some(INIT_VALUE))?; + // Create a new token. + create(&mut session, TOKEN_A_ID, contract_address, 10_000)?; + // Mint tokens. + const AMOUNT: Balance = 12_000; + mint(&mut session, TOKEN_A_ID, ALICE, AMOUNT)?; + // Burn tokens. + burn(&mut session, TOKEN_A_ID, ALICE, 1)?; + assert_eq!(total_supply(&mut session, TOKEN_A_ID)?, Ok(AMOUNT - 1)); + assert_eq!(balance_of(&mut session, TOKEN_A_ID, ALICE)?, Ok(AMOUNT - 1)); + Ok(()) +} + +#[drink::test(sandbox = Sandbox)] +fn test_transfer_token_works(mut session: Session) -> Result<(), Box> { + let _ = env_logger::try_init(); + let contract_bundle = BundleProvider::local()?; + // Deploy a contract. + let contract_address = + session.deploy_bundle(contract_bundle, "new", NO_ARGS, NO_SALT, Some(INIT_VALUE))?; + // Create a new token. + create(&mut session, TOKEN_A_ID, contract_address.clone(), 10_000)?; + // Mint tokens. + const AMOUNT: Balance = 12_000; + const TRANSFERED: Balance = 500; + mint(&mut session, TOKEN_A_ID, contract_address.clone(), AMOUNT)?; + mint(&mut session, TOKEN_A_ID, BOB, AMOUNT)?; + // Transfer tokens. + transfer(&mut session, TOKEN_A_ID, BOB, TRANSFERED)?; + assert_eq!(balance_of(&mut session, TOKEN_A_ID, contract_address)?, Ok(AMOUNT - TRANSFERED)); + assert_eq!(balance_of(&mut session, TOKEN_A_ID, BOB)?, Ok(AMOUNT + TRANSFERED)); + Ok(()) +} diff --git a/pop-api/src/primitives.rs b/pop-api/src/primitives.rs index a3d596a5..9fec4dd3 100644 --- a/pop-api/src/primitives.rs +++ b/pop-api/src/primitives.rs @@ -1,5 +1,11 @@ use ink::env::{DefaultEnvironment, Environment}; +use ink::scale::Decode; pub use pop_primitives::*; pub(crate) type AccountId = ::AccountId; pub(crate) type Balance = ::Balance; + +/// Decode slice of bytes to environment associated type AccountId. +pub fn account_id_from_slice(s: &[u8; 32]) -> AccountId { + AccountId::decode(&mut &s[..]).expect("Should be decoded to AccountId") +} diff --git a/pop-sandbox/README.md b/pop-sandbox/README.md new file mode 100644 index 00000000..b911cd17 --- /dev/null +++ b/pop-sandbox/README.md @@ -0,0 +1,46 @@ +# Pop Sandbox + +Implementation of the `pop_drink::Sandbox` struct for the Pop Network runtimes required for the quasi testing with `drink`. + +## Getting Started + +### Installation + +```toml +pop_drink = { version = "1.0.0", package = "pop-drink" } +``` + +### Import Sandbox for the specific runtime + +For mainnet + +```rs +use pop_sandbox::MainnetSandbox; +``` + +For devnet + +```rs +use pop_sandbox::DevnetSandbox; +``` + +For testnet + +```rs +use pop_sandbox::TestnetSandbox; +``` + +### Setup test environment for your contract + +```rs +use drink::session::Session; +use pop_sandbox::DevnetSandbox as Sandbox; + +#[drink::contract_bundle_provider] +enum BundleProvider {} + +#[drink::test(sandbox = Sandbox)] +fn test(mut session: Session) { + // Your test case +} +``` diff --git a/pop-sandbox/src/lib.rs b/pop-sandbox/src/lib.rs index 285c5774..dbdb9a06 100644 --- a/pop-sandbox/src/lib.rs +++ b/pop-sandbox/src/lib.rs @@ -1,13 +1,13 @@ use frame_support::{ sp_runtime::{ traits::{Header, One}, - AccountId32, }, traits::Hooks, }; use frame_system::pallet_prelude::BlockNumberFor; -pub use pop_runtime_devnet::Balance; use pop_runtime_devnet::{BuildStorage, Runtime}; +pub use pop_runtime_devnet::Balance; +pub use frame_support::sp_runtime::AccountId32; /// Alias for the account ID type. pub type AccountIdFor = ::AccountId; @@ -17,6 +17,8 @@ pub const UNIT: Balance = 10_000_000_000; pub const INIT_AMOUNT: Balance = 100_000_000 * UNIT; pub const INIT_VALUE: Balance = 100 * UNIT; pub const ALICE: AccountId32 = AccountId32::new([1u8; 32]); +pub const BOB: AccountId32 = AccountId32::new([2_u8; 32]); +pub const CHARLIE: AccountId32 = AccountId32::new([3_u8; 32]); /// A helper struct for initializing and finalizing blocks. pub struct BlockBuilder(std::marker::PhantomData); @@ -70,16 +72,16 @@ impl< } } -pub struct PopSandbox { +pub struct Sandbox { ext: sp_io::TestExternalities, } -impl Default for PopSandbox { +impl Default for Sandbox { fn default() -> Self { - let balances: Vec<(AccountId32, u128)> = vec![(ALICE, INIT_AMOUNT)]; + let balances: Vec<(AccountId32, u128)> = vec![(ALICE, INIT_AMOUNT), (BOB, INIT_AMOUNT), (CHARLIE, INIT_AMOUNT)]; let ext = BlockBuilder::::new_ext(balances); Self { ext } } } -drink::impl_sandbox!(PopSandbox, Runtime, BlockBuilder, ALICE); +drink::impl_sandbox!(Sandbox, Runtime, BlockBuilder, ALICE); From 7c4c470851c7e47a60ea06a03425d9c748dd5b7b Mon Sep 17 00:00:00 2001 From: Daanvdplas Date: Mon, 16 Sep 2024 15:43:13 +0200 Subject: [PATCH 068/112] style: token terminology --- pop-api/examples/fungibles/lib.rs | 52 ++++++++++++++--------------- pop-api/examples/fungibles/tests.rs | 12 +++---- 2 files changed, 32 insertions(+), 32 deletions(-) diff --git a/pop-api/examples/fungibles/lib.rs b/pop-api/examples/fungibles/lib.rs index e99bfd60..2148e967 100644 --- a/pop-api/examples/fungibles/lib.rs +++ b/pop-api/examples/fungibles/lib.rs @@ -47,50 +47,50 @@ mod fungibles { } #[ink(message)] - pub fn transfer(&mut self, id: TokenId, to: AccountId, value: Balance) -> PopApiResult<()> { - api::transfer(id, to, value) + pub fn transfer(&mut self, token: TokenId, to: AccountId, value: Balance) -> PopApiResult<()> { + api::transfer(token, to, value) } #[ink(message)] pub fn transfer_from( &mut self, - id: TokenId, + token: TokenId, from: AccountId, to: AccountId, value: Balance, _data: Vec, ) -> PopApiResult<()> { - api::transfer_from(id, from, to, value) + api::transfer_from(token, from, to, value) } #[ink(message)] pub fn approve( &mut self, - id: TokenId, + token: TokenId, spender: AccountId, value: Balance, ) -> PopApiResult<()> { - api::approve(id, spender, value) + api::approve(token, spender, value) } #[ink(message)] pub fn increase_allowance( &mut self, - id: TokenId, + token: TokenId, spender: AccountId, value: Balance, ) -> PopApiResult<()> { - api::increase_allowance(id, spender, value) + api::increase_allowance(token, spender, value) } #[ink(message)] pub fn decrease_allowance( &mut self, - id: TokenId, + token: TokenId, spender: AccountId, value: Balance, ) -> PopApiResult<()> { - api::decrease_allowance(id, spender, value) + api::decrease_allowance(token, spender, value) } #[ink(message, payable)] @@ -108,52 +108,52 @@ mod fungibles { #[ink(message)] pub fn set_metadata( &self, - id: TokenId, + token: TokenId, name: Vec, symbol: Vec, decimals: u8, ) -> PopApiResult<()> { - api::set_metadata(id, name, symbol, decimals) + api::set_metadata(token, name, symbol, decimals) } #[ink(message)] - pub fn total_supply(&self, id: TokenId) -> PopApiResult { - api::total_supply(id) + pub fn total_supply(&self, token: TokenId) -> PopApiResult { + api::total_supply(token) } #[ink(message)] - pub fn balance_of(&self, id: TokenId, owner: AccountId) -> PopApiResult { - api::balance_of(id, owner) + pub fn balance_of(&self, token: TokenId, owner: AccountId) -> PopApiResult { + api::balance_of(token, owner) } #[ink(message)] pub fn allowance( &self, - id: TokenId, + token: TokenId, owner: AccountId, spender: AccountId, ) -> PopApiResult { - api::allowance(id, owner, spender) + api::allowance(token, owner, spender) } #[ink(message)] - pub fn token_name(&self, id: TokenId) -> PopApiResult> { - api::token_name(id) + pub fn token_name(&self, token: TokenId) -> PopApiResult> { + api::token_name(token) } #[ink(message)] - pub fn token_symbol(&self, id: TokenId) -> PopApiResult> { - api::token_symbol(id) + pub fn token_symbol(&self, token: TokenId) -> PopApiResult> { + api::token_symbol(token) } #[ink(message)] - pub fn token_decimals(&self, id: TokenId) -> PopApiResult { - api::token_decimals(id) + pub fn token_decimals(&self, token: TokenId) -> PopApiResult { + api::token_decimals(token) } #[ink(message)] - pub fn token_exists(&self, id: TokenId) -> PopApiResult { - api::token_exists(id) + pub fn token_exists(&self, token: TokenId) -> PopApiResult { + api::token_exists(token) } } } diff --git a/pop-api/examples/fungibles/tests.rs b/pop-api/examples/fungibles/tests.rs index 4284f733..216b9de3 100644 --- a/pop-api/examples/fungibles/tests.rs +++ b/pop-api/examples/fungibles/tests.rs @@ -96,32 +96,32 @@ mod test_methods { pub(super) fn token_exist( session: &mut Session, - id: TokenId, + token: TokenId, ) -> Result, Box> { - Ok(decoded_call::>(session, "token_exists", vec![id.to_string()], None)?) + Ok(decoded_call::>(session, "token_exists", vec![token.to_string()], None)?) } pub(super) fn total_supply( session: &mut Session, - id: TokenId, + token: TokenId, ) -> Result, Box> { Ok(decoded_call::>( session, "total_supply", - vec![id.to_string()], + vec![token.to_string()], None, )?) } pub(super) fn balance_of( session: &mut Session, - id: TokenId, + token: TokenId, owner: AccountId32, ) -> Result, Box> { Ok(decoded_call::>( session, "balance_of", - vec![id.to_string(), owner.to_string()], + vec![token.to_string(), owner.to_string()], None, )?) } From 4e44fba9d662535fb568ef8ea00cd57ead2747f6 Mon Sep 17 00:00:00 2001 From: chungquantin <56880684+chungquantin@users.noreply.github.com> Date: Wed, 18 Sep 2024 12:48:36 +0800 Subject: [PATCH 069/112] feat: add interfaces for psp22 --- pop-api/src/v0/fungibles.rs | 87 +++++++++++++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) diff --git a/pop-api/src/v0/fungibles.rs b/pop-api/src/v0/fungibles.rs index 99c1261a..9ab53957 100644 --- a/pop-api/src/v0/fungibles.rs +++ b/pop-api/src/v0/fungibles.rs @@ -420,6 +420,93 @@ pub mod management { } } +pub mod interfaces { + use super::*; + + pub type Result = core::result::Result; + + #[ink::trait_definition] + pub trait Psp22Impl { + #[ink(message)] + fn total_supply(&self) -> Balance; + + #[ink(message)] + fn balance_of(&self, owner: AccountId) -> Balance; + + #[ink(message)] + fn allowance(&self, owner: AccountId, spender: AccountId) -> Balance; + + #[ink(message)] + fn transfer(&mut self, to: AccountId, value: Balance, data: Vec) -> Result<()>; + + #[ink(message)] + fn transfer_from( + &mut self, + from: AccountId, + to: AccountId, + value: Balance, + data: Vec, + ) -> Result<()>; + + #[ink(message)] + fn approve(&mut self, spender: AccountId, value: Balance) -> Result<()>; + + #[ink(message)] + fn increase_allowance(&mut self, spender: AccountId, value: Balance) -> Result<()>; + + #[ink(message)] + fn decrease_allowance(&mut self, spender: AccountId, value: Balance) -> Result<()>; + } + + #[ink::trait_definition] + pub trait Psp2ManagableImpl { + #[ink(message)] + fn create(&mut self, id: TokenId, admin: AccountId, min_balance: Balance) -> Result<()>; + + #[ink(message)] + fn start_destroy(&mut self, token: TokenId) -> Result<()>; + + #[ink(message)] + fn set_metadata( + &mut self, + token: TokenId, + name: Vec, + symbol: Vec, + decimals: u8, + ) -> Result<()>; + + #[ink(message)] + fn clear_metadata(&mut self, token: TokenId) -> Result<()>; + + #[ink(message)] + fn token_exists(&self, token: TokenId) -> Result; + } + + #[ink::trait_definition] + pub trait Psp22MetadataImpl { + #[ink(message)] + fn token_name(&self) -> Option>; + + #[ink(message)] + fn token_symbol(&self) -> Option>; + + #[ink(message)] + fn token_decimals(&self, id: TokenId) -> u8; + } + + #[ink::trait_definition] + pub trait Psp22MintableImpl { + #[ink(message)] + fn mint(&mut self, account: AccountId, amount: Balance) -> Result<()>; + } + + #[ink::trait_definition] + pub trait Psp22BurnableImpl { + #[ink(message)] + fn burn(&mut self, account: AccountId, amount: Balance) -> Result<()>; + } +} + /// Represents various errors related to fungible tokens. /// /// The `FungiblesError` provides a detailed and specific set of error types that can occur when From a32f0021b95555607db113dd4cd3fa5f4292d2a0 Mon Sep 17 00:00:00 2001 From: chungquantin <56880684+chungquantin@users.noreply.github.com> Date: Wed, 18 Sep 2024 16:03:39 +0800 Subject: [PATCH 070/112] chore: add comments --- pop-api/src/v0/fungibles.rs | 143 ++++++++++++++++++++++++++++++++++-- 1 file changed, 137 insertions(+), 6 deletions(-) diff --git a/pop-api/src/v0/fungibles.rs b/pop-api/src/v0/fungibles.rs index 9ab53957..096017c6 100644 --- a/pop-api/src/v0/fungibles.rs +++ b/pop-api/src/v0/fungibles.rs @@ -426,19 +426,78 @@ pub mod interfaces { pub type Result = core::result::Result; #[ink::trait_definition] - pub trait Psp22Impl { + pub trait Psp22 { + /// Returns the total token supply. #[ink(message)] fn total_supply(&self) -> Balance; + /// Returns the account balance for the specified `owner`. + /// + /// # Parameters + /// - `owner` - The account whose balance is being queried. + /// + /// Returns `0` if the account is non-existent. #[ink(message)] fn balance_of(&self, owner: AccountId) -> Balance; + /// Returns the allowance for a `spender` approved by an `owner`. + /// + /// # Parameters + /// - `owner` - The account that owns the tokens. + /// - `spender` - The account that is allowed to spend the tokens. + /// + /// Returns `0` if no allowance has been set. #[ink(message)] fn allowance(&self, owner: AccountId, spender: AccountId) -> Balance; + /// Transfers `value` amount of tokens from the caller's account to account `to` + /// with additional `data` in unspecified format. + /// + /// # Parameters + /// - `to` - The recipient account. + /// - `value` - The number of tokens to transfer. + /// - `data` - Additional data in unspecified format. + /// + /// # Events + /// On success a `Transfer` event is emitted. + /// + /// No-op if the caller and `to` is the same address or `value` is zero, returns success + /// and no events are emitted. + /// + /// # Errors + /// Reverts with `InsufficientBalance` if the `value` exceeds the caller's balance. #[ink(message)] fn transfer(&mut self, to: AccountId, value: Balance, data: Vec) -> Result<()>; + /// Transfers `value` tokens on behalf of `from` to the account `to` + /// with additional `data` in unspecified format. + /// + /// # Parameters + /// - `from` - The account from which the token balance will be withdrawn. + /// - `to` - The recipient account. + /// - `value` - The number of tokens to transfer. + /// + /// If `from` and the caller are different addresses, the caller must be allowed + /// by `from` to spend at least `value` tokens. + /// + /// # Events + /// On success a `Transfer` event is emitted. + /// + /// No-op if `from` and `to` is the same address or `value` is zero, returns success + /// and no events are emitted. + /// + /// If `from` and the caller are different addresses, a successful transfer results + /// in decreased allowance by `from` to the caller and an `Approval` event with + /// the new allowance amount is emitted. + /// + /// # Errors + /// Reverts with `InsufficientBalance` if the `value` exceeds the balance of the account `from`. + /// + /// Reverts with `InsufficientAllowance` if `from` and the caller are different addresses and + /// the `value` exceeds the allowance granted by `from` to the caller. + /// + /// If conditions for both `InsufficientBalance` and `InsufficientAllowance` errors are met, + /// reverts with `InsufficientAllowance`. #[ink(message)] fn transfer_from( &mut self, @@ -448,18 +507,57 @@ pub mod interfaces { data: Vec, ) -> Result<()>; + /// Approves `spender` to spend `value` amount of tokens on behalf of the caller. + /// + /// Successive calls of this method overwrite previous values. + /// + /// # Parameters + /// - `spender` - The account that is allowed to spend the tokens. + /// - `value` - The number of tokens to approve. + /// + /// # Events + /// An `Approval` event is emitted. + /// + /// No-op if the caller and `spender` is the same address, returns success and no events are emitted. #[ink(message)] fn approve(&mut self, spender: AccountId, value: Balance) -> Result<()>; + /// Increases the allowance of `spender` by `value` amount of tokens. + /// + /// # Parameters + /// - `spender` - The account that is allowed to spend the tokens. + /// - `value` - The number of tokens to increase the allowance by. + /// + /// # Events + /// An `Approval` event with the new allowance amount is emitted. + /// + /// No-op if the caller and `spender` is the same address or `value` is zero, returns success + /// and no events are emitted. #[ink(message)] fn increase_allowance(&mut self, spender: AccountId, value: Balance) -> Result<()>; + /// Decreases the allowance of `spender` by `value` amount of tokens. + /// + /// # Parameters + /// - `spender` - The account that is allowed to spend the tokens. + /// - `value` - The number of tokens to decrease the allowance by. + /// + /// # Events + /// An `Approval` event with the new allowance amount is emitted. + /// + /// No-op if the caller and `spender` is the same address or `value` is zero, returns success + /// and no events are emitted. + /// + /// # Errors + /// Reverts with `InsufficientAllowance` if `spender` and the caller are different addresses and + /// the `value` exceeds the allowance granted by the caller to `spender`. #[ink(message)] fn decrease_allowance(&mut self, spender: AccountId, value: Balance) -> Result<()>; } + /// The PSP22 Metadata trait. #[ink::trait_definition] - pub trait Psp2ManagableImpl { + pub trait Psp22Managable { #[ink(message)] fn create(&mut self, id: TokenId, admin: AccountId, min_balance: Balance) -> Result<()>; @@ -482,26 +580,59 @@ pub mod interfaces { fn token_exists(&self, token: TokenId) -> Result; } + /// The PSP22 Metadata trait. #[ink::trait_definition] - pub trait Psp22MetadataImpl { + pub trait Psp22Metadata { + /// Returns the token name. #[ink(message)] fn token_name(&self) -> Option>; + /// Returns the token symbol. #[ink(message)] fn token_symbol(&self) -> Option>; + /// Returns the token decimals. #[ink(message)] - fn token_decimals(&self, id: TokenId) -> u8; + fn token_decimals(&self) -> u8; } + /// The PSP22 Mintable trait. #[ink::trait_definition] - pub trait Psp22MintableImpl { + pub trait Psp22Mintable { + /// Creates `value` amount of tokens and assigns them to `account`, increasing the total supply. + /// + /// # Parameters + /// - `account` - The account to be credited with the created tokens. + /// - `value` - The number of tokens to mint. + /// + /// # Events + /// On success a `Transfer` event is emitted with `None` sender. + /// + /// No-op if `value` is zero, returns success and no events are emitted. + /// + /// # Errors + /// Reverts with `Custom (max supply exceeded)` if the total supply increased by + /// `value` exceeds maximal value of `u128` type. #[ink(message)] fn mint(&mut self, account: AccountId, amount: Balance) -> Result<()>; } + /// The PSP22 Burnable trait. #[ink::trait_definition] - pub trait Psp22BurnableImpl { + pub trait Psp22Burnable { + /// Destroys `value` amount of tokens from `account`, reducing the total supply. + /// + /// # Parameters + /// - `account` - The account from which the tokens will be destroyed. + /// - `value` - The number of tokens to destroy. + /// + /// # Events + /// On success a `Transfer` event is emitted with `None` recipient. + /// + /// No-op if `value` is zero, returns success and no events are emitted. + /// + /// # Errors + /// Reverts with `InsufficientBalance` if the `value` exceeds the caller's balance. #[ink(message)] fn burn(&mut self, account: AccountId, amount: Balance) -> Result<()>; } From bf4062d6d4e4b97165ecb134259cb00d8698aebd Mon Sep 17 00:00:00 2001 From: chungquantin <56880684+chungquantin@users.noreply.github.com> Date: Wed, 18 Sep 2024 16:30:18 +0800 Subject: [PATCH 071/112] refactor: separate modules into files --- pop-api/src/v0/fungibles.rs | 806 ------------------------- pop-api/src/v0/fungibles/errors.rs | 63 ++ pop-api/src/v0/fungibles/events.rs | 82 +++ pop-api/src/v0/fungibles/interfaces.rs | 215 +++++++ pop-api/src/v0/fungibles/mod.rs | 343 +++++++++++ pop-api/src/v0/fungibles/tests.rs | 99 +++ 6 files changed, 802 insertions(+), 806 deletions(-) delete mode 100644 pop-api/src/v0/fungibles.rs create mode 100644 pop-api/src/v0/fungibles/errors.rs create mode 100644 pop-api/src/v0/fungibles/events.rs create mode 100644 pop-api/src/v0/fungibles/interfaces.rs create mode 100644 pop-api/src/v0/fungibles/mod.rs create mode 100644 pop-api/src/v0/fungibles/tests.rs diff --git a/pop-api/src/v0/fungibles.rs b/pop-api/src/v0/fungibles.rs deleted file mode 100644 index 096017c6..00000000 --- a/pop-api/src/v0/fungibles.rs +++ /dev/null @@ -1,806 +0,0 @@ -//! The `fungibles` module provides an API for interacting and managing fungible tokens. -//! -//! The API includes the following interfaces: -//! 1. PSP-22 -//! 2. PSP-22 Metadata -//! 3. Management -//! 4. PSP-22 Mintable & Burnable - -use constants::*; -use ink::prelude::vec::Vec; -pub use management::*; -pub use metadata::*; - -use crate::{ - constants::{ASSETS, BALANCES, FUNGIBLES}, - primitives::{AccountId, Balance, TokenId}, - ChainExtensionMethodApi, Result, StatusCode, -}; - -// Helper method to build a dispatch call. -// -// Parameters: -// - 'dispatchable': The index of the dispatchable function within the module. -fn build_dispatch(dispatchable: u8) -> ChainExtensionMethodApi { - crate::v0::build_dispatch(FUNGIBLES, dispatchable) -} - -// Helper method to build a call to read state. -// -// Parameters: -// - 'state_query': The index of the runtime state query. -fn build_read_state(state_query: u8) -> ChainExtensionMethodApi { - crate::v0::build_read_state(FUNGIBLES, state_query) -} - -mod constants { - /// 1. PSP-22 Interface: - pub(super) const TOTAL_SUPPLY: u8 = 0; - pub(super) const BALANCE_OF: u8 = 1; - pub(super) const ALLOWANCE: u8 = 2; - pub(super) const TRANSFER: u8 = 3; - pub(super) const TRANSFER_FROM: u8 = 4; - pub(super) const APPROVE: u8 = 5; - pub(super) const INCREASE_ALLOWANCE: u8 = 6; - pub(super) const DECREASE_ALLOWANCE: u8 = 7; - - /// 2. PSP-22 Metadata Interface: - pub(super) const TOKEN_NAME: u8 = 8; - pub(super) const TOKEN_SYMBOL: u8 = 9; - pub(super) const TOKEN_DECIMALS: u8 = 10; - - /// 3. Asset Management: - pub(super) const CREATE: u8 = 11; - pub(super) const START_DESTROY: u8 = 12; - pub(super) const SET_METADATA: u8 = 16; - pub(super) const CLEAR_METADATA: u8 = 17; - pub(super) const TOKEN_EXISTS: u8 = 18; - - /// 4. PSP-22 Mintable & Burnable interface: - pub(super) const MINT: u8 = 19; - pub(super) const BURN: u8 = 20; -} - -/// A set of events for use in smart contracts interacting with the fungibles API. -/// -/// The `Transfer` and `Approval` events conform to the PSP-22 standard. The other events -/// (`Create`, `StartDestroy`, `SetMetadata`, `ClearMetadata`) are provided for convenience. -/// -/// These events are not emitted by the API itself but can be used in your contracts to -/// track token operations. Be mindful of the costs associated with emitting events. -/// -/// For more details, refer to [ink! events](https://use.ink/basics/events). -pub mod events { - use super::*; - - /// Event emitted when allowance by `owner` to `spender` changes. - #[ink::event] - pub struct Approval { - /// The owner providing the allowance. - #[ink(topic)] - pub owner: AccountId, - /// The beneficiary of the allowance. - #[ink(topic)] - pub spender: AccountId, - /// The new allowance amount. - pub value: u128, - } - - /// Event emitted when transfer of tokens occurs. - #[ink::event] - pub struct Transfer { - /// The source of the transfer. `None` when minting. - #[ink(topic)] - pub from: Option, - /// The recipient of the transfer. `None` when burning. - #[ink(topic)] - pub to: Option, - /// The amount transferred (or minted/burned). - pub value: u128, - } - - /// Event emitted when a token is created. - #[ink::event] - pub struct Created { - /// The token identifier. - #[ink(topic)] - pub id: TokenId, - /// The creator of the token. - #[ink(topic)] - pub creator: AccountId, - /// The administrator of the token. - #[ink(topic)] - pub admin: AccountId, - } - - /// Event emitted when a token is in the process of being destroyed. - #[ink::event] - pub struct DestroyStarted { - /// The token. - #[ink(topic)] - pub token: TokenId, - } - - /// Event emitted when new metadata is set for a token. - #[ink::event] - pub struct MetadataSet { - /// The token. - #[ink(topic)] - pub token: TokenId, - /// The name of the token. - #[ink(topic)] - pub name: Vec, - /// The symbol of the token. - #[ink(topic)] - pub symbol: Vec, - /// The decimals of the token. - pub decimals: u8, - } - - /// Event emitted when metadata is cleared for a token. - #[ink::event] - pub struct MetadataCleared { - /// The token. - #[ink(topic)] - pub token: TokenId, - } -} - -/// Returns the total token supply for a specified token. -/// -/// # Parameters -/// - `token` - The token. -#[inline] -pub fn total_supply(token: TokenId) -> Result { - build_read_state(TOTAL_SUPPLY) - .input::() - .output::, true>() - .handle_error_code::() - .call(&(token)) -} - -/// Returns the account balance for a specified `token` and `owner`. Returns `0` if -/// the account is non-existent. -/// -/// # Parameters -/// - `token` - The token. -/// - `owner` - The account whose balance is being queried. -#[inline] -pub fn balance_of(token: TokenId, owner: AccountId) -> Result { - build_read_state(BALANCE_OF) - .input::<(TokenId, AccountId)>() - .output::, true>() - .handle_error_code::() - .call(&(token, owner)) -} - -/// Returns the allowance for a `spender` approved by an `owner`, for a specified `token`. Returns -/// `0` if no allowance has been set. -/// -/// # Parameters -/// - `token` - The token. -/// - `owner` - The account that owns the tokens. -/// - `spender` - The account that is allowed to spend the tokens. -#[inline] -pub fn allowance(token: TokenId, owner: AccountId, spender: AccountId) -> Result { - build_read_state(ALLOWANCE) - .input::<(TokenId, AccountId, AccountId)>() - .output::, true>() - .handle_error_code::() - .call(&(token, owner, spender)) -} - -/// Transfers `value` amount of tokens from the caller's account to account `to`. -/// -/// # Parameters -/// - `token` - The token to transfer. -/// - `to` - The recipient account. -/// - `value` - The number of tokens to transfer. -#[inline] -pub fn transfer(token: TokenId, to: AccountId, value: Balance) -> Result<()> { - build_dispatch(TRANSFER) - .input::<(TokenId, AccountId, Balance)>() - .output::, true>() - .handle_error_code::() - .call(&(token, to, value)) -} - -/// Transfers `value` amount tokens on behalf of `from` to account `to`. -/// -/// # Parameters -/// - `token` - The token to transfer. -/// - `from` - The account from which the token balance will be withdrawn. -/// - `to` - The recipient account. -/// - `value` - The number of tokens to transfer. -#[inline] -pub fn transfer_from(token: TokenId, from: AccountId, to: AccountId, value: Balance) -> Result<()> { - build_dispatch(TRANSFER_FROM) - .input::<(TokenId, AccountId, AccountId, Balance)>() - .output::, true>() - .handle_error_code::() - .call(&(token, from, to, value)) -} - -/// Approves `spender` to spend `value` amount of tokens on behalf of the caller. -/// -/// # Parameters -/// - `token` - The token to approve. -/// - `spender` - The account that is allowed to spend the tokens. -/// - `value` - The number of tokens to approve. -#[inline] -pub fn approve(token: TokenId, spender: AccountId, value: Balance) -> Result<()> { - build_dispatch(APPROVE) - .input::<(TokenId, AccountId, Balance)>() - .output::, true>() - .handle_error_code::() - .call(&(token, spender, value)) -} - -/// Increases the allowance of `spender` by `value` amount of tokens. -/// -/// # Parameters -/// - `token` - The token to have an allowance increased. -/// - `spender` - The account that is allowed to spend the tokens. -/// - `value` - The number of tokens to increase the allowance by. -#[inline] -pub fn increase_allowance(token: TokenId, spender: AccountId, value: Balance) -> Result<()> { - build_dispatch(INCREASE_ALLOWANCE) - .input::<(TokenId, AccountId, Balance)>() - .output::, true>() - .handle_error_code::() - .call(&(token, spender, value)) -} - -/// Decreases the allowance of `spender` by `value` amount of tokens. -/// -/// # Parameters -/// - `token` - The token to have an allowance decreased. -/// - `spender` - The account that is allowed to spend the tokens. -/// - `value` - The number of tokens to decrease the allowance by. -#[inline] -pub fn decrease_allowance(token: TokenId, spender: AccountId, value: Balance) -> Result<()> { - build_dispatch(DECREASE_ALLOWANCE) - .input::<(TokenId, AccountId, Balance)>() - .output::, true>() - .handle_error_code::() - .call(&(token, spender, value)) -} - -/// Creates `value` amount of tokens and assigns them to `account`, increasing the total supply. -/// -/// # Parameters -/// - `token` - The token to mint. -/// - `account` - The account to be credited with the created tokens. -/// - `value` - The number of tokens to mint. -#[inline] -pub fn mint(token: TokenId, account: AccountId, value: Balance) -> Result<()> { - build_dispatch(MINT) - .input::<(TokenId, AccountId, Balance)>() - .output::, true>() - .handle_error_code::() - .call(&(token, account, value)) -} - -/// Destroys `value` amount of tokens from `account`, reducing the total supply. -/// -/// # Parameters -/// - `token` - the token to burn. -/// - `account` - The account from which the tokens will be destroyed. -/// - `value` - The number of tokens to destroy. -#[inline] -pub fn burn(token: TokenId, account: AccountId, value: Balance) -> Result<()> { - build_dispatch(BURN) - .input::<(TokenId, AccountId, Balance)>() - .output::, true>() - .handle_error_code::() - .call(&(token, account, value)) -} - -/// The PSP-22 compliant interface for querying metadata. -pub mod metadata { - use super::*; - - /// Returns the name of the specified token. - /// - /// # Parameters - /// - `token` - The token. - #[inline] - pub fn token_name(token: TokenId) -> Result> { - build_read_state(TOKEN_NAME) - .input::() - .output::>, true>() - .handle_error_code::() - .call(&(token)) - } - - /// Returns the symbol for the specified token. - /// - /// # Parameters - /// - `token` - The token. - #[inline] - pub fn token_symbol(token: TokenId) -> Result> { - build_read_state(TOKEN_SYMBOL) - .input::() - .output::>, true>() - .handle_error_code::() - .call(&(token)) - } - - /// Returns the decimals for the specified token. - /// - /// # Parameters - /// - `token` - The token. - #[inline] - pub fn token_decimals(token: TokenId) -> Result { - build_read_state(TOKEN_DECIMALS) - .input::() - .output::, true>() - .handle_error_code::() - .call(&(token)) - } -} - -/// The interface for creating, managing and destroying fungible tokens. -pub mod management { - use super::*; - - /// Create a new token with a given identifier. - /// - /// # Parameters - /// - `id` - The identifier of the token. - /// - `admin` - The account that will administer the token. - /// - `min_balance` - The minimum balance required for accounts holding this token. - #[inline] - pub fn create(id: TokenId, admin: AccountId, min_balance: Balance) -> Result<()> { - build_dispatch(CREATE) - .input::<(TokenId, AccountId, Balance)>() - .output::, true>() - .handle_error_code::() - .call(&(id, admin, min_balance)) - } - - /// Start the process of destroying a token. - /// - /// # Parameters - /// - `token` - The token to be destroyed. - #[inline] - pub fn start_destroy(token: TokenId) -> Result<()> { - build_dispatch(START_DESTROY) - .input::() - .output::, true>() - .handle_error_code::() - .call(&(token)) - } - - /// Set the metadata for a token. - /// - /// # Parameters - /// - `token`: The token to update. - /// - `name`: The user friendly name of this token. - /// - `symbol`: The exchange symbol for this token. - /// - `decimals`: The number of decimals this token uses to represent one unit. - #[inline] - pub fn set_metadata( - token: TokenId, - name: Vec, - symbol: Vec, - decimals: u8, - ) -> Result<()> { - build_dispatch(SET_METADATA) - .input::<(TokenId, Vec, Vec, u8)>() - .output::, true>() - .handle_error_code::() - .call(&(token, name, symbol, decimals)) - } - - /// Clear the metadata for a token. - /// - /// # Parameters - /// - `token` - The token to update - #[inline] - pub fn clear_metadata(token: TokenId) -> Result<()> { - build_dispatch(CLEAR_METADATA) - .input::() - .output::, true>() - .handle_error_code::() - .call(&(token)) - } - - /// Checks if a specified token exists. - /// - /// # Parameters - /// - `token` - The token. - #[inline] - pub fn token_exists(token: TokenId) -> Result { - build_read_state(TOKEN_EXISTS) - .input::() - .output::, true>() - .handle_error_code::() - .call(&(token)) - } -} - -pub mod interfaces { - use super::*; - - pub type Result = core::result::Result; - - #[ink::trait_definition] - pub trait Psp22 { - /// Returns the total token supply. - #[ink(message)] - fn total_supply(&self) -> Balance; - - /// Returns the account balance for the specified `owner`. - /// - /// # Parameters - /// - `owner` - The account whose balance is being queried. - /// - /// Returns `0` if the account is non-existent. - #[ink(message)] - fn balance_of(&self, owner: AccountId) -> Balance; - - /// Returns the allowance for a `spender` approved by an `owner`. - /// - /// # Parameters - /// - `owner` - The account that owns the tokens. - /// - `spender` - The account that is allowed to spend the tokens. - /// - /// Returns `0` if no allowance has been set. - #[ink(message)] - fn allowance(&self, owner: AccountId, spender: AccountId) -> Balance; - - /// Transfers `value` amount of tokens from the caller's account to account `to` - /// with additional `data` in unspecified format. - /// - /// # Parameters - /// - `to` - The recipient account. - /// - `value` - The number of tokens to transfer. - /// - `data` - Additional data in unspecified format. - /// - /// # Events - /// On success a `Transfer` event is emitted. - /// - /// No-op if the caller and `to` is the same address or `value` is zero, returns success - /// and no events are emitted. - /// - /// # Errors - /// Reverts with `InsufficientBalance` if the `value` exceeds the caller's balance. - #[ink(message)] - fn transfer(&mut self, to: AccountId, value: Balance, data: Vec) -> Result<()>; - - /// Transfers `value` tokens on behalf of `from` to the account `to` - /// with additional `data` in unspecified format. - /// - /// # Parameters - /// - `from` - The account from which the token balance will be withdrawn. - /// - `to` - The recipient account. - /// - `value` - The number of tokens to transfer. - /// - /// If `from` and the caller are different addresses, the caller must be allowed - /// by `from` to spend at least `value` tokens. - /// - /// # Events - /// On success a `Transfer` event is emitted. - /// - /// No-op if `from` and `to` is the same address or `value` is zero, returns success - /// and no events are emitted. - /// - /// If `from` and the caller are different addresses, a successful transfer results - /// in decreased allowance by `from` to the caller and an `Approval` event with - /// the new allowance amount is emitted. - /// - /// # Errors - /// Reverts with `InsufficientBalance` if the `value` exceeds the balance of the account `from`. - /// - /// Reverts with `InsufficientAllowance` if `from` and the caller are different addresses and - /// the `value` exceeds the allowance granted by `from` to the caller. - /// - /// If conditions for both `InsufficientBalance` and `InsufficientAllowance` errors are met, - /// reverts with `InsufficientAllowance`. - #[ink(message)] - fn transfer_from( - &mut self, - from: AccountId, - to: AccountId, - value: Balance, - data: Vec, - ) -> Result<()>; - - /// Approves `spender` to spend `value` amount of tokens on behalf of the caller. - /// - /// Successive calls of this method overwrite previous values. - /// - /// # Parameters - /// - `spender` - The account that is allowed to spend the tokens. - /// - `value` - The number of tokens to approve. - /// - /// # Events - /// An `Approval` event is emitted. - /// - /// No-op if the caller and `spender` is the same address, returns success and no events are emitted. - #[ink(message)] - fn approve(&mut self, spender: AccountId, value: Balance) -> Result<()>; - - /// Increases the allowance of `spender` by `value` amount of tokens. - /// - /// # Parameters - /// - `spender` - The account that is allowed to spend the tokens. - /// - `value` - The number of tokens to increase the allowance by. - /// - /// # Events - /// An `Approval` event with the new allowance amount is emitted. - /// - /// No-op if the caller and `spender` is the same address or `value` is zero, returns success - /// and no events are emitted. - #[ink(message)] - fn increase_allowance(&mut self, spender: AccountId, value: Balance) -> Result<()>; - - /// Decreases the allowance of `spender` by `value` amount of tokens. - /// - /// # Parameters - /// - `spender` - The account that is allowed to spend the tokens. - /// - `value` - The number of tokens to decrease the allowance by. - /// - /// # Events - /// An `Approval` event with the new allowance amount is emitted. - /// - /// No-op if the caller and `spender` is the same address or `value` is zero, returns success - /// and no events are emitted. - /// - /// # Errors - /// Reverts with `InsufficientAllowance` if `spender` and the caller are different addresses and - /// the `value` exceeds the allowance granted by the caller to `spender`. - #[ink(message)] - fn decrease_allowance(&mut self, spender: AccountId, value: Balance) -> Result<()>; - } - - /// The PSP22 Metadata trait. - #[ink::trait_definition] - pub trait Psp22Managable { - #[ink(message)] - fn create(&mut self, id: TokenId, admin: AccountId, min_balance: Balance) -> Result<()>; - - #[ink(message)] - fn start_destroy(&mut self, token: TokenId) -> Result<()>; - - #[ink(message)] - fn set_metadata( - &mut self, - token: TokenId, - name: Vec, - symbol: Vec, - decimals: u8, - ) -> Result<()>; - - #[ink(message)] - fn clear_metadata(&mut self, token: TokenId) -> Result<()>; - - #[ink(message)] - fn token_exists(&self, token: TokenId) -> Result; - } - - /// The PSP22 Metadata trait. - #[ink::trait_definition] - pub trait Psp22Metadata { - /// Returns the token name. - #[ink(message)] - fn token_name(&self) -> Option>; - - /// Returns the token symbol. - #[ink(message)] - fn token_symbol(&self) -> Option>; - - /// Returns the token decimals. - #[ink(message)] - fn token_decimals(&self) -> u8; - } - - /// The PSP22 Mintable trait. - #[ink::trait_definition] - pub trait Psp22Mintable { - /// Creates `value` amount of tokens and assigns them to `account`, increasing the total supply. - /// - /// # Parameters - /// - `account` - The account to be credited with the created tokens. - /// - `value` - The number of tokens to mint. - /// - /// # Events - /// On success a `Transfer` event is emitted with `None` sender. - /// - /// No-op if `value` is zero, returns success and no events are emitted. - /// - /// # Errors - /// Reverts with `Custom (max supply exceeded)` if the total supply increased by - /// `value` exceeds maximal value of `u128` type. - #[ink(message)] - fn mint(&mut self, account: AccountId, amount: Balance) -> Result<()>; - } - - /// The PSP22 Burnable trait. - #[ink::trait_definition] - pub trait Psp22Burnable { - /// Destroys `value` amount of tokens from `account`, reducing the total supply. - /// - /// # Parameters - /// - `account` - The account from which the tokens will be destroyed. - /// - `value` - The number of tokens to destroy. - /// - /// # Events - /// On success a `Transfer` event is emitted with `None` recipient. - /// - /// No-op if `value` is zero, returns success and no events are emitted. - /// - /// # Errors - /// Reverts with `InsufficientBalance` if the `value` exceeds the caller's balance. - #[ink(message)] - fn burn(&mut self, account: AccountId, amount: Balance) -> Result<()>; - } -} - -/// Represents various errors related to fungible tokens. -/// -/// The `FungiblesError` provides a detailed and specific set of error types that can occur when -/// interacting with fungible tokens. Each variant signifies a particular error -/// condition, facilitating precise error handling and debugging. -/// -/// It is designed to be lightweight, including only the essential errors relevant to fungible token -/// operations. The `Other` variant serves as a catch-all for any unexpected errors. For more -/// detailed debugging, the `Other` variant can be converted into the richer `Error` type defined in -/// the primitives crate. -#[derive(Debug, PartialEq, Eq)] -#[ink::scale_derive(Encode, Decode, TypeInfo)] -pub enum FungiblesError { - /// An unspecified or unknown error occurred. - Other(StatusCode), - /// The token is not live; either frozen or being destroyed. - NotLive, - /// Not enough allowance to fulfill a request is available. - InsufficientAllowance, - /// Not enough balance to fulfill a request is available. - InsufficientBalance, - /// The token ID is already taken. - InUse, - /// Minimum balance should be non-zero. - MinBalanceZero, - /// The account to alter does not exist. - NoAccount, - /// The signing account has no permission to do the operation. - NoPermission, - /// The given token ID is unknown. - Unknown, - /// No balance for creation of tokens or fees. - // TODO: Originally `pallet_balances::Error::InsufficientBalance` but collides with the - // `InsufficientBalance` error that is used for `pallet_assets::Error::BalanceLow` to adhere - // to the standard. This deserves a second look. - NoBalance, -} - -impl From for FungiblesError { - /// Converts a `StatusCode` to a `FungiblesError`. - /// - /// This conversion maps a `StatusCode`, returned by the runtime, to a more descriptive - /// `FungiblesError`. This provides better context and understanding of the error, allowing - /// developers to handle the most important errors effectively. - fn from(value: StatusCode) -> Self { - let encoded = value.0.to_le_bytes(); - match encoded { - // Balances. - [_, BALANCES, 2, _] => FungiblesError::NoBalance, - // Assets. - [_, ASSETS, 0, _] => FungiblesError::NoAccount, - [_, ASSETS, 1, _] => FungiblesError::NoPermission, - [_, ASSETS, 2, _] => FungiblesError::Unknown, - [_, ASSETS, 3, _] => FungiblesError::InUse, - [_, ASSETS, 5, _] => FungiblesError::MinBalanceZero, - [_, ASSETS, 7, _] => FungiblesError::InsufficientAllowance, - [_, ASSETS, 10, _] => FungiblesError::NotLive, - _ => FungiblesError::Other(value), - } - } -} - -#[cfg(test)] -mod tests { - use ink::scale::{Decode, Encode}; - - use super::FungiblesError; - use crate::{ - constants::{ASSETS, BALANCES}, - primitives::{ - ArithmeticError::*, - Error::{self, *}, - TokenError::*, - TransactionalError::*, - }, - StatusCode, - }; - - fn error_into_status_code(error: Error) -> StatusCode { - let mut encoded_error = error.encode(); - encoded_error.resize(4, 0); - let value = u32::from_le_bytes( - encoded_error.try_into().expect("qed, resized to 4 bytes line above"), - ); - value.into() - } - - fn into_fungibles_error(error: Error) -> FungiblesError { - let status_code: StatusCode = error_into_status_code(error); - status_code.into() - } - - // If we ever want to change the conversion from bytes to `u32`. - #[test] - fn status_code_vs_encoded() { - assert_eq!(u32::decode(&mut &[3u8, 10, 2, 0][..]).unwrap(), 133635u32); - assert_eq!(u32::decode(&mut &[3u8, 52, 0, 0][..]).unwrap(), 13315u32); - assert_eq!(u32::decode(&mut &[3u8, 52, 1, 0][..]).unwrap(), 78851u32); - assert_eq!(u32::decode(&mut &[3u8, 52, 2, 0][..]).unwrap(), 144387u32); - assert_eq!(u32::decode(&mut &[3u8, 52, 3, 0][..]).unwrap(), 209923u32); - assert_eq!(u32::decode(&mut &[3u8, 52, 5, 0][..]).unwrap(), 340995u32); - assert_eq!(u32::decode(&mut &[3u8, 52, 7, 0][..]).unwrap(), 472067u32); - assert_eq!(u32::decode(&mut &[3u8, 52, 10, 0][..]).unwrap(), 668675u32); - } - - #[test] - fn converting_status_code_into_fungibles_error_works() { - let other_errors = vec![ - Other, - CannotLookup, - BadOrigin, - // `ModuleError` other than assets module. - Module { index: 2, error: [5, 0] }, - ConsumerRemaining, - NoProviders, - TooManyConsumers, - Token(OnlyProvider), - Arithmetic(Overflow), - Transactional(NoLayer), - Exhausted, - Corruption, - Unavailable, - RootNotAllowed, - Unknown { dispatch_error_index: 5, error_index: 5, error: 1 }, - DecodingFailed, - ]; - for error in other_errors { - let status_code: StatusCode = error_into_status_code(error); - let fungibles_error: FungiblesError = status_code.into(); - assert_eq!(fungibles_error, FungiblesError::Other(status_code)) - } - - assert_eq!( - into_fungibles_error(Module { index: BALANCES, error: [2, 0] }), - FungiblesError::NoBalance - ); - assert_eq!( - into_fungibles_error(Module { index: ASSETS, error: [0, 0] }), - FungiblesError::NoAccount - ); - assert_eq!( - into_fungibles_error(Module { index: ASSETS, error: [1, 0] }), - FungiblesError::NoPermission - ); - assert_eq!( - into_fungibles_error(Module { index: ASSETS, error: [2, 0] }), - FungiblesError::Unknown - ); - assert_eq!( - into_fungibles_error(Module { index: ASSETS, error: [3, 0] }), - FungiblesError::InUse - ); - assert_eq!( - into_fungibles_error(Module { index: ASSETS, error: [5, 0] }), - FungiblesError::MinBalanceZero - ); - assert_eq!( - into_fungibles_error(Module { index: ASSETS, error: [7, 0] }), - FungiblesError::InsufficientAllowance - ); - assert_eq!( - into_fungibles_error(Module { index: ASSETS, error: [10, 0] }), - FungiblesError::NotLive - ); - } -} diff --git a/pop-api/src/v0/fungibles/errors.rs b/pop-api/src/v0/fungibles/errors.rs new file mode 100644 index 00000000..b29127e5 --- /dev/null +++ b/pop-api/src/v0/fungibles/errors.rs @@ -0,0 +1,63 @@ +use super::*; + +/// Represents various errors related to fungible tokens. +/// +/// The `FungiblesError` provides a detailed and specific set of error types that can occur when +/// interacting with fungible tokens. Each variant signifies a particular error +/// condition, facilitating precise error handling and debugging. +/// +/// It is designed to be lightweight, including only the essential errors relevant to fungible token +/// operations. The `Other` variant serves as a catch-all for any unexpected errors. For more +/// detailed debugging, the `Other` variant can be converted into the richer `Error` type defined in +/// the primitives crate. +#[derive(Debug, PartialEq, Eq)] +#[ink::scale_derive(Encode, Decode, TypeInfo)] +pub enum FungiblesError { + /// An unspecified or unknown error occurred. + Other(StatusCode), + /// The token is not live; either frozen or being destroyed. + NotLive, + /// Not enough allowance to fulfill a request is available. + InsufficientAllowance, + /// Not enough balance to fulfill a request is available. + InsufficientBalance, + /// The token ID is already taken. + InUse, + /// Minimum balance should be non-zero. + MinBalanceZero, + /// The account to alter does not exist. + NoAccount, + /// The signing account has no permission to do the operation. + NoPermission, + /// The given token ID is unknown. + Unknown, + /// No balance for creation of tokens or fees. + // TODO: Originally `pallet_balances::Error::InsufficientBalance` but collides with the + // `InsufficientBalance` error that is used for `pallet_assets::Error::BalanceLow` to adhere + // to the standard. This deserves a second look. + NoBalance, +} + +impl From for FungiblesError { + /// Converts a `StatusCode` to a `FungiblesError`. + /// + /// This conversion maps a `StatusCode`, returned by the runtime, to a more descriptive + /// `FungiblesError`. This provides better context and understanding of the error, allowing + /// developers to handle the most important errors effectively. + fn from(value: StatusCode) -> Self { + let encoded = value.0.to_le_bytes(); + match encoded { + // Balances. + [_, BALANCES, 2, _] => FungiblesError::NoBalance, + // Assets. + [_, ASSETS, 0, _] => FungiblesError::NoAccount, + [_, ASSETS, 1, _] => FungiblesError::NoPermission, + [_, ASSETS, 2, _] => FungiblesError::Unknown, + [_, ASSETS, 3, _] => FungiblesError::InUse, + [_, ASSETS, 5, _] => FungiblesError::MinBalanceZero, + [_, ASSETS, 7, _] => FungiblesError::InsufficientAllowance, + [_, ASSETS, 10, _] => FungiblesError::NotLive, + _ => FungiblesError::Other(value), + } + } +} diff --git a/pop-api/src/v0/fungibles/events.rs b/pop-api/src/v0/fungibles/events.rs new file mode 100644 index 00000000..b0639e10 --- /dev/null +++ b/pop-api/src/v0/fungibles/events.rs @@ -0,0 +1,82 @@ +/// A set of events for use in smart contracts interacting with the fungibles API. +/// +/// The `Transfer` and `Approval` events conform to the PSP-22 standard. The other events +/// (`Create`, `StartDestroy`, `SetMetadata`, `ClearMetadata`) are provided for convenience. +/// +/// These events are not emitted by the API itself but can be used in your contracts to +/// track token operations. Be mindful of the costs associated with emitting events. +/// +/// For more details, refer to [ink! events](https://use.ink/basics/events). +use super::*; + +/// Event emitted when allowance by `owner` to `spender` changes. +#[ink::event] +pub struct Approval { + /// The owner providing the allowance. + #[ink(topic)] + pub owner: AccountId, + /// The beneficiary of the allowance. + #[ink(topic)] + pub spender: AccountId, + /// The new allowance amount. + pub value: u128, +} + +/// Event emitted when transfer of tokens occurs. +#[ink::event] +pub struct Transfer { + /// The source of the transfer. `None` when minting. + #[ink(topic)] + pub from: Option, + /// The recipient of the transfer. `None` when burning. + #[ink(topic)] + pub to: Option, + /// The amount transferred (or minted/burned). + pub value: u128, +} + +/// Event emitted when a token is created. +#[ink::event] +pub struct Created { + /// The token identifier. + #[ink(topic)] + pub id: TokenId, + /// The creator of the token. + #[ink(topic)] + pub creator: AccountId, + /// The administrator of the token. + #[ink(topic)] + pub admin: AccountId, +} + +/// Event emitted when a token is in the process of being destroyed. +#[ink::event] +pub struct DestroyStarted { + /// The token. + #[ink(topic)] + pub token: TokenId, +} + +/// Event emitted when new metadata is set for a token. +#[ink::event] +pub struct MetadataSet { + /// The token. + #[ink(topic)] + pub token: TokenId, + /// The name of the token. + #[ink(topic)] + pub name: Vec, + /// The symbol of the token. + #[ink(topic)] + pub symbol: Vec, + /// The decimals of the token. + pub decimals: u8, +} + +/// Event emitted when metadata is cleared for a token. +#[ink::event] +pub struct MetadataCleared { + /// The token. + #[ink(topic)] + pub token: TokenId, +} diff --git a/pop-api/src/v0/fungibles/interfaces.rs b/pop-api/src/v0/fungibles/interfaces.rs new file mode 100644 index 00000000..6023ce37 --- /dev/null +++ b/pop-api/src/v0/fungibles/interfaces.rs @@ -0,0 +1,215 @@ +use super::*; + +pub type Result = core::result::Result; + +#[ink::trait_definition] +pub trait Psp22 { + /// Returns the total token supply. + #[ink(message)] + fn total_supply(&self) -> Balance; + + /// Returns the account balance for the specified `owner`. + /// + /// # Parameters + /// - `owner` - The account whose balance is being queried. + /// + /// Returns `0` if the account is non-existent. + #[ink(message)] + fn balance_of(&self, owner: AccountId) -> Balance; + + /// Returns the allowance for a `spender` approved by an `owner`. + /// + /// # Parameters + /// - `owner` - The account that owns the tokens. + /// - `spender` - The account that is allowed to spend the tokens. + /// + /// Returns `0` if no allowance has been set. + #[ink(message)] + fn allowance(&self, owner: AccountId, spender: AccountId) -> Balance; + + /// Transfers `value` amount of tokens from the caller's account to account `to` + /// with additional `data` in unspecified format. + /// + /// # Parameters + /// - `to` - The recipient account. + /// - `value` - The number of tokens to transfer. + /// - `data` - Additional data in unspecified format. + /// + /// # Events + /// On success a `Transfer` event is emitted. + /// + /// No-op if the caller and `to` is the same address or `value` is zero, returns success + /// and no events are emitted. + /// + /// # Errors + /// Reverts with `InsufficientBalance` if the `value` exceeds the caller's balance. + #[ink(message)] + fn transfer(&mut self, to: AccountId, value: Balance, data: Vec) -> Result<()>; + + /// Transfers `value` tokens on behalf of `from` to the account `to` + /// with additional `data` in unspecified format. + /// + /// # Parameters + /// - `from` - The account from which the token balance will be withdrawn. + /// - `to` - The recipient account. + /// - `value` - The number of tokens to transfer. + /// + /// If `from` and the caller are different addresses, the caller must be allowed + /// by `from` to spend at least `value` tokens. + /// + /// # Events + /// On success a `Transfer` event is emitted. + /// + /// No-op if `from` and `to` is the same address or `value` is zero, returns success + /// and no events are emitted. + /// + /// If `from` and the caller are different addresses, a successful transfer results + /// in decreased allowance by `from` to the caller and an `Approval` event with + /// the new allowance amount is emitted. + /// + /// # Errors + /// Reverts with `InsufficientBalance` if the `value` exceeds the balance of the account `from`. + /// + /// Reverts with `InsufficientAllowance` if `from` and the caller are different addresses and + /// the `value` exceeds the allowance granted by `from` to the caller. + /// + /// If conditions for both `InsufficientBalance` and `InsufficientAllowance` errors are met, + /// reverts with `InsufficientAllowance`. + #[ink(message)] + fn transfer_from( + &mut self, + from: AccountId, + to: AccountId, + value: Balance, + data: Vec, + ) -> Result<()>; + + /// Approves `spender` to spend `value` amount of tokens on behalf of the caller. + /// + /// Successive calls of this method overwrite previous values. + /// + /// # Parameters + /// - `spender` - The account that is allowed to spend the tokens. + /// - `value` - The number of tokens to approve. + /// + /// # Events + /// An `Approval` event is emitted. + /// + /// No-op if the caller and `spender` is the same address, returns success and no events are emitted. + #[ink(message)] + fn approve(&mut self, spender: AccountId, value: Balance) -> Result<()>; + + /// Increases the allowance of `spender` by `value` amount of tokens. + /// + /// # Parameters + /// - `spender` - The account that is allowed to spend the tokens. + /// - `value` - The number of tokens to increase the allowance by. + /// + /// # Events + /// An `Approval` event with the new allowance amount is emitted. + /// + /// No-op if the caller and `spender` is the same address or `value` is zero, returns success + /// and no events are emitted. + #[ink(message)] + fn increase_allowance(&mut self, spender: AccountId, value: Balance) -> Result<()>; + + /// Decreases the allowance of `spender` by `value` amount of tokens. + /// + /// # Parameters + /// - `spender` - The account that is allowed to spend the tokens. + /// - `value` - The number of tokens to decrease the allowance by. + /// + /// # Events + /// An `Approval` event with the new allowance amount is emitted. + /// + /// No-op if the caller and `spender` is the same address or `value` is zero, returns success + /// and no events are emitted. + /// + /// # Errors + /// Reverts with `InsufficientAllowance` if `spender` and the caller are different addresses and + /// the `value` exceeds the allowance granted by the caller to `spender`. + #[ink(message)] + fn decrease_allowance(&mut self, spender: AccountId, value: Balance) -> Result<()>; +} + +/// The PSP22 Metadata trait. +#[ink::trait_definition] +pub trait Psp22Managable { + #[ink(message)] + fn create(&mut self, id: TokenId, admin: AccountId, min_balance: Balance) -> Result<()>; + + #[ink(message)] + fn start_destroy(&mut self, token: TokenId) -> Result<()>; + + #[ink(message)] + fn set_metadata( + &mut self, + token: TokenId, + name: Vec, + symbol: Vec, + decimals: u8, + ) -> Result<()>; + + #[ink(message)] + fn clear_metadata(&mut self, token: TokenId) -> Result<()>; + + #[ink(message)] + fn token_exists(&self, token: TokenId) -> Result; +} + +/// The PSP22 Metadata trait. +#[ink::trait_definition] +pub trait Psp22Metadata { + /// Returns the token name. + #[ink(message)] + fn token_name(&self) -> Option>; + + /// Returns the token symbol. + #[ink(message)] + fn token_symbol(&self) -> Option>; + + /// Returns the token decimals. + #[ink(message)] + fn token_decimals(&self) -> u8; +} + +/// The PSP22 Mintable trait. +#[ink::trait_definition] +pub trait Psp22Mintable { + /// Creates `value` amount of tokens and assigns them to `account`, increasing the total supply. + /// + /// # Parameters + /// - `account` - The account to be credited with the created tokens. + /// - `value` - The number of tokens to mint. + /// + /// # Events + /// On success a `Transfer` event is emitted with `None` sender. + /// + /// No-op if `value` is zero, returns success and no events are emitted. + /// + /// # Errors + /// Reverts with `Custom (max supply exceeded)` if the total supply increased by + /// `value` exceeds maximal value of `u128` type. + #[ink(message)] + fn mint(&mut self, account: AccountId, amount: Balance) -> Result<()>; +} + +/// The PSP22 Burnable trait. +#[ink::trait_definition] +pub trait Psp22Burnable { + /// Destroys `value` amount of tokens from `account`, reducing the total supply. + /// + /// # Parameters + /// - `account` - The account from which the tokens will be destroyed. + /// - `value` - The number of tokens to destroy. + /// + /// # Events + /// On success a `Transfer` event is emitted with `None` recipient. + /// + /// No-op if `value` is zero, returns success and no events are emitted. + /// + /// # Errors + /// Reverts with `InsufficientBalance` if the `value` exceeds the caller's balance. + #[ink(message)] + fn burn(&mut self, account: AccountId, amount: Balance) -> Result<()>; +} diff --git a/pop-api/src/v0/fungibles/mod.rs b/pop-api/src/v0/fungibles/mod.rs new file mode 100644 index 00000000..e8d4e81d --- /dev/null +++ b/pop-api/src/v0/fungibles/mod.rs @@ -0,0 +1,343 @@ +//! The `fungibles` module provides an API for interacting and managing fungible tokens. +//! +//! The API includes the following interfaces: +//! 1. PSP-22 +//! 2. PSP-22 Metadata +//! 3. Management +//! 4. PSP-22 Mintable & Burnable +pub mod errors; +pub mod events; +pub mod interfaces; +#[cfg(test)] +mod tests; + +use crate::{ + constants::{ASSETS, BALANCES, FUNGIBLES}, + primitives::{AccountId, Balance, TokenId}, + ChainExtensionMethodApi, StatusCode, +}; +use constants::*; +pub use errors::*; +pub use events::*; +use ink::prelude::vec::Vec; +pub use interfaces::*; +pub use management::*; +pub use metadata::*; + +// Helper method to build a dispatch call. +// +// Parameters: +// - 'dispatchable': The index of the dispatchable function within the module. +fn build_dispatch(dispatchable: u8) -> ChainExtensionMethodApi { + crate::v0::build_dispatch(FUNGIBLES, dispatchable) +} + +// Helper method to build a call to read state. +// +// Parameters: +// - 'state_query': The index of the runtime state query. +fn build_read_state(state_query: u8) -> ChainExtensionMethodApi { + crate::v0::build_read_state(FUNGIBLES, state_query) +} + +mod constants { + /// 1. PSP-22 Interface: + pub(super) const TOTAL_SUPPLY: u8 = 0; + pub(super) const BALANCE_OF: u8 = 1; + pub(super) const ALLOWANCE: u8 = 2; + pub(super) const TRANSFER: u8 = 3; + pub(super) const TRANSFER_FROM: u8 = 4; + pub(super) const APPROVE: u8 = 5; + pub(super) const INCREASE_ALLOWANCE: u8 = 6; + pub(super) const DECREASE_ALLOWANCE: u8 = 7; + + /// 2. PSP-22 Metadata Interface: + pub(super) const TOKEN_NAME: u8 = 8; + pub(super) const TOKEN_SYMBOL: u8 = 9; + pub(super) const TOKEN_DECIMALS: u8 = 10; + + /// 3. Asset Management: + pub(super) const CREATE: u8 = 11; + pub(super) const START_DESTROY: u8 = 12; + pub(super) const SET_METADATA: u8 = 16; + pub(super) const CLEAR_METADATA: u8 = 17; + pub(super) const TOKEN_EXISTS: u8 = 18; + + /// 4. PSP-22 Mintable & Burnable interface: + pub(super) const MINT: u8 = 19; + pub(super) const BURN: u8 = 20; +} + +/// Returns the total token supply for a specified token. +/// +/// # Parameters +/// - `token` - The token. +#[inline] +pub fn total_supply(token: TokenId) -> Result { + build_read_state(TOTAL_SUPPLY) + .input::() + .output::, true>() + .handle_error_code::() + .call(&(token)) +} + +/// Returns the account balance for a specified `token` and `owner`. Returns `0` if +/// the account is non-existent. +/// +/// # Parameters +/// - `token` - The token. +/// - `owner` - The account whose balance is being queried. +#[inline] +pub fn balance_of(token: TokenId, owner: AccountId) -> Result { + build_read_state(BALANCE_OF) + .input::<(TokenId, AccountId)>() + .output::, true>() + .handle_error_code::() + .call(&(token, owner)) +} + +/// Returns the allowance for a `spender` approved by an `owner`, for a specified `token`. Returns +/// `0` if no allowance has been set. +/// +/// # Parameters +/// - `token` - The token. +/// - `owner` - The account that owns the tokens. +/// - `spender` - The account that is allowed to spend the tokens. +#[inline] +pub fn allowance(token: TokenId, owner: AccountId, spender: AccountId) -> Result { + build_read_state(ALLOWANCE) + .input::<(TokenId, AccountId, AccountId)>() + .output::, true>() + .handle_error_code::() + .call(&(token, owner, spender)) +} + +/// Transfers `value` amount of tokens from the caller's account to account `to`. +/// +/// # Parameters +/// - `token` - The token to transfer. +/// - `to` - The recipient account. +/// - `value` - The number of tokens to transfer. +#[inline] +pub fn transfer(token: TokenId, to: AccountId, value: Balance) -> Result<()> { + build_dispatch(TRANSFER) + .input::<(TokenId, AccountId, Balance)>() + .output::, true>() + .handle_error_code::() + .call(&(token, to, value)) +} + +/// Transfers `value` amount tokens on behalf of `from` to account `to`. +/// +/// # Parameters +/// - `token` - The token to transfer. +/// - `from` - The account from which the token balance will be withdrawn. +/// - `to` - The recipient account. +/// - `value` - The number of tokens to transfer. +#[inline] +pub fn transfer_from(token: TokenId, from: AccountId, to: AccountId, value: Balance) -> Result<()> { + build_dispatch(TRANSFER_FROM) + .input::<(TokenId, AccountId, AccountId, Balance)>() + .output::, true>() + .handle_error_code::() + .call(&(token, from, to, value)) +} + +/// Approves `spender` to spend `value` amount of tokens on behalf of the caller. +/// +/// # Parameters +/// - `token` - The token to approve. +/// - `spender` - The account that is allowed to spend the tokens. +/// - `value` - The number of tokens to approve. +#[inline] +pub fn approve(token: TokenId, spender: AccountId, value: Balance) -> Result<()> { + build_dispatch(APPROVE) + .input::<(TokenId, AccountId, Balance)>() + .output::, true>() + .handle_error_code::() + .call(&(token, spender, value)) +} + +/// Increases the allowance of `spender` by `value` amount of tokens. +/// +/// # Parameters +/// - `token` - The token to have an allowance increased. +/// - `spender` - The account that is allowed to spend the tokens. +/// - `value` - The number of tokens to increase the allowance by. +#[inline] +pub fn increase_allowance(token: TokenId, spender: AccountId, value: Balance) -> Result<()> { + build_dispatch(INCREASE_ALLOWANCE) + .input::<(TokenId, AccountId, Balance)>() + .output::, true>() + .handle_error_code::() + .call(&(token, spender, value)) +} + +/// Decreases the allowance of `spender` by `value` amount of tokens. +/// +/// # Parameters +/// - `token` - The token to have an allowance decreased. +/// - `spender` - The account that is allowed to spend the tokens. +/// - `value` - The number of tokens to decrease the allowance by. +#[inline] +pub fn decrease_allowance(token: TokenId, spender: AccountId, value: Balance) -> Result<()> { + build_dispatch(DECREASE_ALLOWANCE) + .input::<(TokenId, AccountId, Balance)>() + .output::, true>() + .handle_error_code::() + .call(&(token, spender, value)) +} + +/// Creates `value` amount of tokens and assigns them to `account`, increasing the total supply. +/// +/// # Parameters +/// - `token` - The token to mint. +/// - `account` - The account to be credited with the created tokens. +/// - `value` - The number of tokens to mint. +#[inline] +pub fn mint(token: TokenId, account: AccountId, value: Balance) -> Result<()> { + build_dispatch(MINT) + .input::<(TokenId, AccountId, Balance)>() + .output::, true>() + .handle_error_code::() + .call(&(token, account, value)) +} + +/// Destroys `value` amount of tokens from `account`, reducing the total supply. +/// +/// # Parameters +/// - `token` - the token to burn. +/// - `account` - The account from which the tokens will be destroyed. +/// - `value` - The number of tokens to destroy. +#[inline] +pub fn burn(token: TokenId, account: AccountId, value: Balance) -> Result<()> { + build_dispatch(BURN) + .input::<(TokenId, AccountId, Balance)>() + .output::, true>() + .handle_error_code::() + .call(&(token, account, value)) +} + +/// The PSP-22 compliant interface for querying metadata. +pub mod metadata { + use super::*; + + /// Returns the name of the specified token. + /// + /// # Parameters + /// - `token` - The token. + #[inline] + pub fn token_name(token: TokenId) -> Result> { + build_read_state(TOKEN_NAME) + .input::() + .output::>, true>() + .handle_error_code::() + .call(&(token)) + } + + /// Returns the symbol for the specified token. + /// + /// # Parameters + /// - `token` - The token. + #[inline] + pub fn token_symbol(token: TokenId) -> Result> { + build_read_state(TOKEN_SYMBOL) + .input::() + .output::>, true>() + .handle_error_code::() + .call(&(token)) + } + + /// Returns the decimals for the specified token. + /// + /// # Parameters + /// - `token` - The token. + #[inline] + pub fn token_decimals(token: TokenId) -> Result { + build_read_state(TOKEN_DECIMALS) + .input::() + .output::, true>() + .handle_error_code::() + .call(&(token)) + } +} + +/// The interface for creating, managing and destroying fungible tokens. +pub mod management { + use super::*; + + /// Create a new token with a given identifier. + /// + /// # Parameters + /// - `id` - The identifier of the token. + /// - `admin` - The account that will administer the token. + /// - `min_balance` - The minimum balance required for accounts holding this token. + #[inline] + pub fn create(id: TokenId, admin: AccountId, min_balance: Balance) -> Result<()> { + build_dispatch(CREATE) + .input::<(TokenId, AccountId, Balance)>() + .output::, true>() + .handle_error_code::() + .call(&(id, admin, min_balance)) + } + + /// Start the process of destroying a token. + /// + /// # Parameters + /// - `token` - The token to be destroyed. + #[inline] + pub fn start_destroy(token: TokenId) -> Result<()> { + build_dispatch(START_DESTROY) + .input::() + .output::, true>() + .handle_error_code::() + .call(&(token)) + } + + /// Set the metadata for a token. + /// + /// # Parameters + /// - `token`: The token to update. + /// - `name`: The user friendly name of this token. + /// - `symbol`: The exchange symbol for this token. + /// - `decimals`: The number of decimals this token uses to represent one unit. + #[inline] + pub fn set_metadata( + token: TokenId, + name: Vec, + symbol: Vec, + decimals: u8, + ) -> Result<()> { + build_dispatch(SET_METADATA) + .input::<(TokenId, Vec, Vec, u8)>() + .output::, true>() + .handle_error_code::() + .call(&(token, name, symbol, decimals)) + } + + /// Clear the metadata for a token. + /// + /// # Parameters + /// - `token` - The token to update + #[inline] + pub fn clear_metadata(token: TokenId) -> Result<()> { + build_dispatch(CLEAR_METADATA) + .input::() + .output::, true>() + .handle_error_code::() + .call(&(token)) + } + + /// Checks if a specified token exists. + /// + /// # Parameters + /// - `token` - The token. + #[inline] + pub fn token_exists(token: TokenId) -> Result { + build_read_state(TOKEN_EXISTS) + .input::() + .output::, true>() + .handle_error_code::() + .call(&(token)) + } +} diff --git a/pop-api/src/v0/fungibles/tests.rs b/pop-api/src/v0/fungibles/tests.rs new file mode 100644 index 00000000..128cf4cb --- /dev/null +++ b/pop-api/src/v0/fungibles/tests.rs @@ -0,0 +1,99 @@ +use super::FungiblesError; +use crate::{ + constants::{ASSETS, BALANCES}, + primitives::{ + ArithmeticError::*, + Error::{self, *}, + TokenError::*, + TransactionalError::*, + }, + StatusCode, +}; +use ink::scale::{Decode, Encode}; + +fn error_into_status_code(error: Error) -> StatusCode { + let mut encoded_error = error.encode(); + encoded_error.resize(4, 0); + let value = + u32::from_le_bytes(encoded_error.try_into().expect("qed, resized to 4 bytes line above")); + value.into() +} + +fn into_fungibles_error(error: Error) -> FungiblesError { + let status_code: StatusCode = error_into_status_code(error); + status_code.into() +} + +// If we ever want to change the conversion from bytes to `u32`. +#[test] +fn status_code_vs_encoded() { + assert_eq!(u32::decode(&mut &[3u8, 10, 2, 0][..]).unwrap(), 133635u32); + assert_eq!(u32::decode(&mut &[3u8, 52, 0, 0][..]).unwrap(), 13315u32); + assert_eq!(u32::decode(&mut &[3u8, 52, 1, 0][..]).unwrap(), 78851u32); + assert_eq!(u32::decode(&mut &[3u8, 52, 2, 0][..]).unwrap(), 144387u32); + assert_eq!(u32::decode(&mut &[3u8, 52, 3, 0][..]).unwrap(), 209923u32); + assert_eq!(u32::decode(&mut &[3u8, 52, 5, 0][..]).unwrap(), 340995u32); + assert_eq!(u32::decode(&mut &[3u8, 52, 7, 0][..]).unwrap(), 472067u32); + assert_eq!(u32::decode(&mut &[3u8, 52, 10, 0][..]).unwrap(), 668675u32); +} + +#[test] +fn converting_status_code_into_fungibles_error_works() { + let other_errors = vec![ + Other, + CannotLookup, + BadOrigin, + // `ModuleError` other than assets module. + Module { index: 2, error: [5, 0] }, + ConsumerRemaining, + NoProviders, + TooManyConsumers, + Token(OnlyProvider), + Arithmetic(Overflow), + Transactional(NoLayer), + Exhausted, + Corruption, + Unavailable, + RootNotAllowed, + Unknown { dispatch_error_index: 5, error_index: 5, error: 1 }, + DecodingFailed, + ]; + for error in other_errors { + let status_code: StatusCode = error_into_status_code(error); + let fungibles_error: FungiblesError = status_code.into(); + assert_eq!(fungibles_error, FungiblesError::Other(status_code)) + } + + assert_eq!( + into_fungibles_error(Module { index: BALANCES, error: [2, 0] }), + FungiblesError::NoBalance + ); + assert_eq!( + into_fungibles_error(Module { index: ASSETS, error: [0, 0] }), + FungiblesError::NoAccount + ); + assert_eq!( + into_fungibles_error(Module { index: ASSETS, error: [1, 0] }), + FungiblesError::NoPermission + ); + assert_eq!( + into_fungibles_error(Module { index: ASSETS, error: [2, 0] }), + FungiblesError::Unknown + ); + assert_eq!( + into_fungibles_error(Module { index: ASSETS, error: [3, 0] }), + FungiblesError::InUse + ); + assert_eq!( + into_fungibles_error(Module { index: ASSETS, error: [5, 0] }), + FungiblesError::MinBalanceZero + ); + assert_eq!( + into_fungibles_error(Module { index: ASSETS, error: [7, 0] }), + FungiblesError::InsufficientAllowance + ); + assert_eq!( + into_fungibles_error(Module { index: ASSETS, error: [10, 0] }), + FungiblesError::NotLive + ); +} From 21c6826aa83261a7c1c2a5e6c16c1b9cdee168c2 Mon Sep 17 00:00:00 2001 From: chungquantin <56880684+chungquantin@users.noreply.github.com> Date: Wed, 18 Sep 2024 16:45:48 +0800 Subject: [PATCH 072/112] refactor: fungible example --- pop-api/examples/fungibles/lib.rs | 129 ++++++++++++++++--------- pop-api/src/v0/fungibles/errors.rs | 30 ++++++ pop-api/src/v0/fungibles/interfaces.rs | 99 +++++-------------- 3 files changed, 142 insertions(+), 116 deletions(-) diff --git a/pop-api/examples/fungibles/lib.rs b/pop-api/examples/fungibles/lib.rs index 11eafe21..c46b302f 100755 --- a/pop-api/examples/fungibles/lib.rs +++ b/pop-api/examples/fungibles/lib.rs @@ -1,108 +1,151 @@ #![cfg_attr(not(feature = "std"), no_std, no_main)] -use ink::prelude::vec::Vec; +use ink::prelude::{string::String, vec::Vec}; use pop_api::{ - fungibles::{self as api}, primitives::TokenId, + v0::fungibles::{self as api, events::Created, PSP22Error}, StatusCode, }; -pub type Result = core::result::Result; +#[cfg(test)] +mod tests; + +type PSP22Result = core::result::Result; #[ink::contract] mod fungibles { use super::*; #[ink(storage)] - #[derive(Default)] - pub struct Fungibles; + pub struct Fungibles { + id: TokenId, + } impl Fungibles { + /// Instantiate the contract and wrap around an existing token. + /// + /// # Parameters + /// * - `token` - The token. #[ink(constructor, payable)] - pub fn new() -> Self { - Default::default() + pub fn new_existing(id: TokenId) -> PSP22Result { + // Make sure token exists. + if !api::token_exists(id).unwrap_or_default() { + return Err(PSP22Error::Custom(String::from("Unknown"))); + } + let contract = Self { id }; + Ok(contract) } - #[ink(message)] - pub fn total_supply(&self, token: TokenId) -> Result { - api::total_supply(token) + /// Instantiate the contract and create a new token. The token identifier will be stored + /// in contract's storage. + /// + /// # Parameters + /// * - `id` - The identifier of the token. + /// * - `admin` - The account that will administer the token. + /// * - `min_balance` - The minimum balance required for accounts holding this token. + #[ink(constructor, payable)] + pub fn new(id: TokenId, admin: AccountId, min_balance: Balance) -> PSP22Result { + // TODO: should be nicer conversion possible. + api::create(id, admin, min_balance).map_err(|e| PSP22Error::from(e))?; + let contract = Self { id }; + contract + .env() + .emit_event(Created { id, creator: contract.env().account_id(), admin }); + Ok(contract) } #[ink(message)] - pub fn balance_of(&self, token: TokenId, owner: AccountId) -> Result { - api::balance_of(token, owner) + pub fn mint(&mut self, account: AccountId, amount: Balance) -> PSP22Result<()> { + api::mint(self.id, account, amount).map_err(|e| PSP22Error::from(e)) } #[ink(message)] - pub fn allowance( - &self, - token: TokenId, - owner: AccountId, - spender: AccountId, - ) -> Result { - api::allowance(token, owner, spender) + pub fn burn(&mut self, account: AccountId, amount: Balance) -> PSP22Result<()> { + api::burn(self.id, account, amount).map_err(|e| PSP22Error::from(e)) } #[ink(message)] - pub fn transfer(&mut self, token: TokenId, to: AccountId, value: Balance) -> Result<()> { - api::transfer(token, to, value) + pub fn transfer(&mut self, to: AccountId, value: Balance) -> PSP22Result<()> { + api::transfer(self.id, to, value).map_err(|e| PSP22Error::from(e)) } #[ink(message)] pub fn transfer_from( &mut self, - token: TokenId, from: AccountId, to: AccountId, value: Balance, _data: Vec, - ) -> Result<()> { - api::transfer_from(token, from, to, value) + ) -> PSP22Result<()> { + api::transfer_from(self.id, from, to, value).map_err(|e| PSP22Error::from(e)) } #[ink(message)] - pub fn approve( - &mut self, - token: TokenId, - spender: AccountId, - value: Balance, - ) -> Result<()> { - api::approve(token, spender, value) + pub fn approve(&mut self, spender: AccountId, value: Balance) -> PSP22Result<()> { + api::approve(self.id, spender, value).map_err(|e| PSP22Error::from(e)) } #[ink(message)] pub fn increase_allowance( &mut self, - token: TokenId, spender: AccountId, value: Balance, - ) -> Result<()> { - api::increase_allowance(token, spender, value) + ) -> PSP22Result<()> { + api::increase_allowance(self.id, spender, value).map_err(|e| PSP22Error::from(e)) } #[ink(message)] pub fn decrease_allowance( &mut self, - token: TokenId, spender: AccountId, value: Balance, - ) -> Result<()> { - api::decrease_allowance(token, spender, value) + ) -> PSP22Result<()> { + api::decrease_allowance(self.id, spender, value).map_err(|e| PSP22Error::from(e)) + } + + #[ink(message)] + pub fn set_metadata( + &self, + name: Vec, + symbol: Vec, + decimals: u8, + ) -> PSP22Result<()> { + api::set_metadata(self.id, name, symbol, decimals).map_err(|e| PSP22Error::from(e)) + } + + #[ink(message)] + pub fn total_supply(&self) -> PSP22Result { + api::total_supply(self.id).map_err(|e| PSP22Error::from(e)) + } + + #[ink(message)] + pub fn balance_of(&self, owner: AccountId) -> PSP22Result { + api::balance_of(self.id, owner).map_err(|e| PSP22Error::from(e)) + } + + #[ink(message)] + pub fn allowance(&self, owner: AccountId, spender: AccountId) -> PSP22Result { + api::allowance(self.id, owner, spender).map_err(|e| PSP22Error::from(e)) + } + + #[ink(message)] + pub fn token_name(&self) -> PSP22Result> { + api::token_name(self.id).map_err(|e| PSP22Error::from(e)) } #[ink(message)] - pub fn token_name(&self, token: TokenId) -> Result> { - api::token_name(token) + pub fn token_symbol(&self) -> PSP22Result> { + api::token_symbol(self.id).map_err(|e| PSP22Error::from(e)) } #[ink(message)] - pub fn token_symbol(&self, token: TokenId) -> Result> { - api::token_symbol(token) + pub fn token_decimals(&self) -> PSP22Result { + api::token_decimals(self.id).map_err(|e| PSP22Error::from(e)) } #[ink(message)] - pub fn token_decimals(&self, token: TokenId) -> Result { - api::token_decimals(token) + pub fn token_exists(&self) -> PSP22Result { + api::token_exists(self.id).map_err(|e| PSP22Error::from(e)) } } } diff --git a/pop-api/src/v0/fungibles/errors.rs b/pop-api/src/v0/fungibles/errors.rs index b29127e5..872e8d64 100644 --- a/pop-api/src/v0/fungibles/errors.rs +++ b/pop-api/src/v0/fungibles/errors.rs @@ -61,3 +61,33 @@ impl From for FungiblesError { } } } + +/// The PSP22 error. +#[derive(Debug, PartialEq, Eq)] +#[ink::scale_derive(Encode, Decode, TypeInfo)] +pub enum PSP22Error { + /// Custom error type for implementation-based errors. + Custom(String), + /// Returned when an account does not have enough tokens to complete the operation. + InsufficientBalance, + /// Returned if there is not enough allowance to complete the operation. + InsufficientAllowance, + /// Returned if recipient's address is zero. + ZeroRecipientAddress, + /// Returned if sender's address is zero. + ZeroSenderAddress, + /// Returned if a safe transfer check failed. + SafeTransferCheckFailed(String), +} + +impl From for PSP22Error { + /// Converts a `StatusCode` to a `PSP22Error`. + fn from(value: StatusCode) -> Self { + let encoded = value.0.to_le_bytes(); + match encoded { + [_, ASSETS, 3, _] => PSP22Error::Custom(String::from("Unknown")), + [_, ASSETS, 7, _] => PSP22Error::InsufficientAllowance, + _ => PSP22Error::Custom(String::from("Other")), + } + } +} diff --git a/pop-api/src/v0/fungibles/interfaces.rs b/pop-api/src/v0/fungibles/interfaces.rs index 6023ce37..5b52504a 100644 --- a/pop-api/src/v0/fungibles/interfaces.rs +++ b/pop-api/src/v0/fungibles/interfaces.rs @@ -12,8 +12,6 @@ pub trait Psp22 { /// /// # Parameters /// - `owner` - The account whose balance is being queried. - /// - /// Returns `0` if the account is non-existent. #[ink(message)] fn balance_of(&self, owner: AccountId) -> Balance; @@ -22,8 +20,6 @@ pub trait Psp22 { /// # Parameters /// - `owner` - The account that owns the tokens. /// - `spender` - The account that is allowed to spend the tokens. - /// - /// Returns `0` if no allowance has been set. #[ink(message)] fn allowance(&self, owner: AccountId, spender: AccountId) -> Balance; @@ -34,15 +30,6 @@ pub trait Psp22 { /// - `to` - The recipient account. /// - `value` - The number of tokens to transfer. /// - `data` - Additional data in unspecified format. - /// - /// # Events - /// On success a `Transfer` event is emitted. - /// - /// No-op if the caller and `to` is the same address or `value` is zero, returns success - /// and no events are emitted. - /// - /// # Errors - /// Reverts with `InsufficientBalance` if the `value` exceeds the caller's balance. #[ink(message)] fn transfer(&mut self, to: AccountId, value: Balance, data: Vec) -> Result<()>; @@ -53,28 +40,6 @@ pub trait Psp22 { /// - `from` - The account from which the token balance will be withdrawn. /// - `to` - The recipient account. /// - `value` - The number of tokens to transfer. - /// - /// If `from` and the caller are different addresses, the caller must be allowed - /// by `from` to spend at least `value` tokens. - /// - /// # Events - /// On success a `Transfer` event is emitted. - /// - /// No-op if `from` and `to` is the same address or `value` is zero, returns success - /// and no events are emitted. - /// - /// If `from` and the caller are different addresses, a successful transfer results - /// in decreased allowance by `from` to the caller and an `Approval` event with - /// the new allowance amount is emitted. - /// - /// # Errors - /// Reverts with `InsufficientBalance` if the `value` exceeds the balance of the account `from`. - /// - /// Reverts with `InsufficientAllowance` if `from` and the caller are different addresses and - /// the `value` exceeds the allowance granted by `from` to the caller. - /// - /// If conditions for both `InsufficientBalance` and `InsufficientAllowance` errors are met, - /// reverts with `InsufficientAllowance`. #[ink(message)] fn transfer_from( &mut self, @@ -91,11 +56,6 @@ pub trait Psp22 { /// # Parameters /// - `spender` - The account that is allowed to spend the tokens. /// - `value` - The number of tokens to approve. - /// - /// # Events - /// An `Approval` event is emitted. - /// - /// No-op if the caller and `spender` is the same address, returns success and no events are emitted. #[ink(message)] fn approve(&mut self, spender: AccountId, value: Balance) -> Result<()>; @@ -104,12 +64,6 @@ pub trait Psp22 { /// # Parameters /// - `spender` - The account that is allowed to spend the tokens. /// - `value` - The number of tokens to increase the allowance by. - /// - /// # Events - /// An `Approval` event with the new allowance amount is emitted. - /// - /// No-op if the caller and `spender` is the same address or `value` is zero, returns success - /// and no events are emitted. #[ink(message)] fn increase_allowance(&mut self, spender: AccountId, value: Balance) -> Result<()>; @@ -118,16 +72,6 @@ pub trait Psp22 { /// # Parameters /// - `spender` - The account that is allowed to spend the tokens. /// - `value` - The number of tokens to decrease the allowance by. - /// - /// # Events - /// An `Approval` event with the new allowance amount is emitted. - /// - /// No-op if the caller and `spender` is the same address or `value` is zero, returns success - /// and no events are emitted. - /// - /// # Errors - /// Reverts with `InsufficientAllowance` if `spender` and the caller are different addresses and - /// the `value` exceeds the allowance granted by the caller to `spender`. #[ink(message)] fn decrease_allowance(&mut self, spender: AccountId, value: Balance) -> Result<()>; } @@ -135,12 +79,30 @@ pub trait Psp22 { /// The PSP22 Metadata trait. #[ink::trait_definition] pub trait Psp22Managable { + /// Creates a new token with the specified `id`, assigns `admin` as the administrator, + /// and sets a minimum balance requirement. + /// + /// # Parameters + /// - `id`: The unique identifier for the token to be created. + /// - `admin`: The account that will have administrative privileges over the token. + /// - `min_balance`: The minimum balance required to hold the token. #[ink(message)] fn create(&mut self, id: TokenId, admin: AccountId, min_balance: Balance) -> Result<()>; + /// Initiates the process to destroy the specified `token`. + /// + /// # Parameters + /// - `token`: The identifier of the token to be destroyed. #[ink(message)] fn start_destroy(&mut self, token: TokenId) -> Result<()>; + /// Sets metadata for the specified `token`, including its name, symbol, and decimal places. + /// + /// # Parameters + /// - `token`: The identifier of the token to set metadata for. + /// - `name`: The name of the token. + /// - `symbol`: The symbol representing the token. + /// - `decimals`: The number of decimal places the token uses. #[ink(message)] fn set_metadata( &mut self, @@ -150,9 +112,17 @@ pub trait Psp22Managable { decimals: u8, ) -> Result<()>; + /// Clears the metadata for the specified `token`. + /// + /// # Parameters + /// - `token`: The identifier of the token to clear metadata for. #[ink(message)] fn clear_metadata(&mut self, token: TokenId) -> Result<()>; + /// Checks whether a token with the specified `token` identifier exists. + /// + /// # Parameters + /// - `token`: The identifier of the token to check for existence. #[ink(message)] fn token_exists(&self, token: TokenId) -> Result; } @@ -181,15 +151,6 @@ pub trait Psp22Mintable { /// # Parameters /// - `account` - The account to be credited with the created tokens. /// - `value` - The number of tokens to mint. - /// - /// # Events - /// On success a `Transfer` event is emitted with `None` sender. - /// - /// No-op if `value` is zero, returns success and no events are emitted. - /// - /// # Errors - /// Reverts with `Custom (max supply exceeded)` if the total supply increased by - /// `value` exceeds maximal value of `u128` type. #[ink(message)] fn mint(&mut self, account: AccountId, amount: Balance) -> Result<()>; } @@ -202,14 +163,6 @@ pub trait Psp22Burnable { /// # Parameters /// - `account` - The account from which the tokens will be destroyed. /// - `value` - The number of tokens to destroy. - /// - /// # Events - /// On success a `Transfer` event is emitted with `None` recipient. - /// - /// No-op if `value` is zero, returns success and no events are emitted. - /// - /// # Errors - /// Reverts with `InsufficientBalance` if the `value` exceeds the caller's balance. #[ink(message)] fn burn(&mut self, account: AccountId, amount: Balance) -> Result<()>; } From 894fcf90306a8a792d7df5b723ab7937d0ede4be Mon Sep 17 00:00:00 2001 From: chungquantin <56880684+chungquantin@users.noreply.github.com> Date: Wed, 18 Sep 2024 17:39:13 +0800 Subject: [PATCH 073/112] feat: refactor example contract to follow spec --- pop-api/examples/fungibles/lib.rs | 107 ++++++++++++++----------- pop-api/src/v0/fungibles/interfaces.rs | 28 +++---- pop-api/src/v0/fungibles/mod.rs | 81 ++++++++++--------- 3 files changed, 116 insertions(+), 100 deletions(-) diff --git a/pop-api/examples/fungibles/lib.rs b/pop-api/examples/fungibles/lib.rs index c46b302f..0f6bcd63 100755 --- a/pop-api/examples/fungibles/lib.rs +++ b/pop-api/examples/fungibles/lib.rs @@ -3,15 +3,18 @@ use ink::prelude::{string::String, vec::Vec}; use pop_api::{ primitives::TokenId, - v0::fungibles::{self as api, events::Created, PSP22Error}, + v0::fungibles::{ + self as api, + events::Created, + interfaces::{Psp22, Psp22Burnable, Psp22Metadata, Psp22Mintable}, + PSP22Error, PSP22Result, + }, StatusCode, }; #[cfg(test)] mod tests; -type PSP22Result = core::result::Result; - #[ink::contract] mod fungibles { use super::*; @@ -55,97 +58,103 @@ mod fungibles { } #[ink(message)] - pub fn mint(&mut self, account: AccountId, amount: Balance) -> PSP22Result<()> { - api::mint(self.id, account, amount).map_err(|e| PSP22Error::from(e)) + pub fn set_metadata( + &self, + name: Vec, + symbol: Vec, + decimals: u8, + ) -> PSP22Result<()> { + api::set_metadata(self.id, name, symbol, decimals).map_err(|e| PSP22Error::from(e)) } #[ink(message)] - pub fn burn(&mut self, account: AccountId, amount: Balance) -> PSP22Result<()> { - api::burn(self.id, account, amount).map_err(|e| PSP22Error::from(e)) + pub fn token_exists(&self) -> PSP22Result { + api::token_exists(self.id).map_err(|e| PSP22Error::from(e)) } + } + impl Psp22 for Fungibles { #[ink(message)] - pub fn transfer(&mut self, to: AccountId, value: Balance) -> PSP22Result<()> { - api::transfer(self.id, to, value).map_err(|e| PSP22Error::from(e)) + fn total_supply(&self) -> Balance { + api::total_supply(self.id).unwrap_or_default() } #[ink(message)] - pub fn transfer_from( - &mut self, - from: AccountId, - to: AccountId, - value: Balance, - _data: Vec, - ) -> PSP22Result<()> { - api::transfer_from(self.id, from, to, value).map_err(|e| PSP22Error::from(e)) + fn balance_of(&self, owner: AccountId) -> Balance { + api::balance_of(self.id, owner).unwrap_or_default() } #[ink(message)] - pub fn approve(&mut self, spender: AccountId, value: Balance) -> PSP22Result<()> { - api::approve(self.id, spender, value).map_err(|e| PSP22Error::from(e)) + fn allowance(&self, owner: AccountId, spender: AccountId) -> Balance { + api::allowance(self.id, owner, spender).unwrap_or_default() } #[ink(message)] - pub fn increase_allowance( - &mut self, - spender: AccountId, - value: Balance, - ) -> PSP22Result<()> { - api::increase_allowance(self.id, spender, value).map_err(|e| PSP22Error::from(e)) + fn transfer(&mut self, to: AccountId, value: Balance, _data: Vec) -> PSP22Result<()> { + api::transfer(self.id, to, value).map_err(|e| PSP22Error::from(e)) } #[ink(message)] - pub fn decrease_allowance( + fn transfer_from( &mut self, - spender: AccountId, + from: AccountId, + to: AccountId, value: Balance, + _data: Vec, ) -> PSP22Result<()> { - api::decrease_allowance(self.id, spender, value).map_err(|e| PSP22Error::from(e)) + api::transfer_from(self.id, from, to, value).map_err(|e| PSP22Error::from(e)) } #[ink(message)] - pub fn set_metadata( - &self, - name: Vec, - symbol: Vec, - decimals: u8, - ) -> PSP22Result<()> { - api::set_metadata(self.id, name, symbol, decimals).map_err(|e| PSP22Error::from(e)) + fn approve(&mut self, spender: AccountId, value: Balance) -> PSP22Result<()> { + api::approve(self.id, spender, value).map_err(|e| PSP22Error::from(e)) } #[ink(message)] - pub fn total_supply(&self) -> PSP22Result { - api::total_supply(self.id).map_err(|e| PSP22Error::from(e)) + fn increase_allowance(&mut self, spender: AccountId, value: Balance) -> PSP22Result<()> { + api::increase_allowance(self.id, spender, value).map_err(|e| PSP22Error::from(e)) } #[ink(message)] - pub fn balance_of(&self, owner: AccountId) -> PSP22Result { - api::balance_of(self.id, owner).map_err(|e| PSP22Error::from(e)) + fn decrease_allowance(&mut self, spender: AccountId, value: Balance) -> PSP22Result<()> { + api::decrease_allowance(self.id, spender, value).map_err(|e| PSP22Error::from(e)) } + } + impl Psp22Metadata for Fungibles { #[ink(message)] - pub fn allowance(&self, owner: AccountId, spender: AccountId) -> PSP22Result { - api::allowance(self.id, owner, spender).map_err(|e| PSP22Error::from(e)) + fn token_name(&self) -> Option> { + if let Ok(value) = api::token_name(self.id) { + return Some(value); + } + None } #[ink(message)] - pub fn token_name(&self) -> PSP22Result> { - api::token_name(self.id).map_err(|e| PSP22Error::from(e)) + fn token_symbol(&self) -> Option> { + if let Ok(value) = api::token_symbol(self.id) { + return Some(value); + } + None } #[ink(message)] - pub fn token_symbol(&self) -> PSP22Result> { - api::token_symbol(self.id).map_err(|e| PSP22Error::from(e)) + fn token_decimals(&self) -> u8 { + api::token_decimals(self.id).unwrap_or_default() } + } + impl Psp22Mintable for Fungibles { #[ink(message)] - pub fn token_decimals(&self) -> PSP22Result { - api::token_decimals(self.id).map_err(|e| PSP22Error::from(e)) + fn mint(&mut self, account: AccountId, amount: Balance) -> PSP22Result<()> { + api::mint(self.id, account, amount).map_err(|e| PSP22Error::from(e)) } + } + impl Psp22Burnable for Fungibles { #[ink(message)] - pub fn token_exists(&self) -> PSP22Result { - api::token_exists(self.id).map_err(|e| PSP22Error::from(e)) + fn burn(&mut self, account: AccountId, amount: Balance) -> PSP22Result<()> { + api::burn(self.id, account, amount).map_err(|e| PSP22Error::from(e)) } } } diff --git a/pop-api/src/v0/fungibles/interfaces.rs b/pop-api/src/v0/fungibles/interfaces.rs index 5b52504a..a4b48a4c 100644 --- a/pop-api/src/v0/fungibles/interfaces.rs +++ b/pop-api/src/v0/fungibles/interfaces.rs @@ -1,7 +1,5 @@ use super::*; -pub type Result = core::result::Result; - #[ink::trait_definition] pub trait Psp22 { /// Returns the total token supply. @@ -31,7 +29,7 @@ pub trait Psp22 { /// - `value` - The number of tokens to transfer. /// - `data` - Additional data in unspecified format. #[ink(message)] - fn transfer(&mut self, to: AccountId, value: Balance, data: Vec) -> Result<()>; + fn transfer(&mut self, to: AccountId, value: Balance, data: Vec) -> PSP22Result<()>; /// Transfers `value` tokens on behalf of `from` to the account `to` /// with additional `data` in unspecified format. @@ -47,7 +45,7 @@ pub trait Psp22 { to: AccountId, value: Balance, data: Vec, - ) -> Result<()>; + ) -> PSP22Result<()>; /// Approves `spender` to spend `value` amount of tokens on behalf of the caller. /// @@ -57,7 +55,7 @@ pub trait Psp22 { /// - `spender` - The account that is allowed to spend the tokens. /// - `value` - The number of tokens to approve. #[ink(message)] - fn approve(&mut self, spender: AccountId, value: Balance) -> Result<()>; + fn approve(&mut self, spender: AccountId, value: Balance) -> PSP22Result<()>; /// Increases the allowance of `spender` by `value` amount of tokens. /// @@ -65,7 +63,7 @@ pub trait Psp22 { /// - `spender` - The account that is allowed to spend the tokens. /// - `value` - The number of tokens to increase the allowance by. #[ink(message)] - fn increase_allowance(&mut self, spender: AccountId, value: Balance) -> Result<()>; + fn increase_allowance(&mut self, spender: AccountId, value: Balance) -> PSP22Result<()>; /// Decreases the allowance of `spender` by `value` amount of tokens. /// @@ -73,12 +71,12 @@ pub trait Psp22 { /// - `spender` - The account that is allowed to spend the tokens. /// - `value` - The number of tokens to decrease the allowance by. #[ink(message)] - fn decrease_allowance(&mut self, spender: AccountId, value: Balance) -> Result<()>; + fn decrease_allowance(&mut self, spender: AccountId, value: Balance) -> PSP22Result<()>; } /// The PSP22 Metadata trait. #[ink::trait_definition] -pub trait Psp22Managable { +pub trait Management { /// Creates a new token with the specified `id`, assigns `admin` as the administrator, /// and sets a minimum balance requirement. /// @@ -87,14 +85,14 @@ pub trait Psp22Managable { /// - `admin`: The account that will have administrative privileges over the token. /// - `min_balance`: The minimum balance required to hold the token. #[ink(message)] - fn create(&mut self, id: TokenId, admin: AccountId, min_balance: Balance) -> Result<()>; + fn create(&mut self, id: TokenId, admin: AccountId, min_balance: Balance) -> PSP22Result<()>; /// Initiates the process to destroy the specified `token`. /// /// # Parameters /// - `token`: The identifier of the token to be destroyed. #[ink(message)] - fn start_destroy(&mut self, token: TokenId) -> Result<()>; + fn start_destroy(&mut self, token: TokenId) -> PSP22Result<()>; /// Sets metadata for the specified `token`, including its name, symbol, and decimal places. /// @@ -110,21 +108,21 @@ pub trait Psp22Managable { name: Vec, symbol: Vec, decimals: u8, - ) -> Result<()>; + ) -> PSP22Result<()>; /// Clears the metadata for the specified `token`. /// /// # Parameters /// - `token`: The identifier of the token to clear metadata for. #[ink(message)] - fn clear_metadata(&mut self, token: TokenId) -> Result<()>; + fn clear_metadata(&mut self, token: TokenId) -> PSP22Result<()>; /// Checks whether a token with the specified `token` identifier exists. /// /// # Parameters /// - `token`: The identifier of the token to check for existence. #[ink(message)] - fn token_exists(&self, token: TokenId) -> Result; + fn token_exists(&self, token: TokenId) -> PSP22Result; } /// The PSP22 Metadata trait. @@ -152,7 +150,7 @@ pub trait Psp22Mintable { /// - `account` - The account to be credited with the created tokens. /// - `value` - The number of tokens to mint. #[ink(message)] - fn mint(&mut self, account: AccountId, amount: Balance) -> Result<()>; + fn mint(&mut self, account: AccountId, amount: Balance) -> PSP22Result<()>; } /// The PSP22 Burnable trait. @@ -164,5 +162,5 @@ pub trait Psp22Burnable { /// - `account` - The account from which the tokens will be destroyed. /// - `value` - The number of tokens to destroy. #[ink(message)] - fn burn(&mut self, account: AccountId, amount: Balance) -> Result<()>; + fn burn(&mut self, account: AccountId, amount: Balance) -> PSP22Result<()>; } diff --git a/pop-api/src/v0/fungibles/mod.rs b/pop-api/src/v0/fungibles/mod.rs index e8d4e81d..da731819 100644 --- a/pop-api/src/v0/fungibles/mod.rs +++ b/pop-api/src/v0/fungibles/mod.rs @@ -17,6 +17,7 @@ use crate::{ ChainExtensionMethodApi, StatusCode, }; use constants::*; +use core::result::Result; pub use errors::*; pub use events::*; use ink::prelude::vec::Vec; @@ -24,6 +25,9 @@ pub use interfaces::*; pub use management::*; pub use metadata::*; +pub type PSP22Result = Result; +pub type PopApiResult = Result; + // Helper method to build a dispatch call. // // Parameters: @@ -73,10 +77,10 @@ mod constants { /// # Parameters /// - `token` - The token. #[inline] -pub fn total_supply(token: TokenId) -> Result { +pub fn total_supply(token: TokenId) -> PopApiResult { build_read_state(TOTAL_SUPPLY) .input::() - .output::, true>() + .output::, true>() .handle_error_code::() .call(&(token)) } @@ -88,10 +92,10 @@ pub fn total_supply(token: TokenId) -> Result { /// - `token` - The token. /// - `owner` - The account whose balance is being queried. #[inline] -pub fn balance_of(token: TokenId, owner: AccountId) -> Result { +pub fn balance_of(token: TokenId, owner: AccountId) -> PopApiResult { build_read_state(BALANCE_OF) .input::<(TokenId, AccountId)>() - .output::, true>() + .output::, true>() .handle_error_code::() .call(&(token, owner)) } @@ -104,10 +108,10 @@ pub fn balance_of(token: TokenId, owner: AccountId) -> Result { /// - `owner` - The account that owns the tokens. /// - `spender` - The account that is allowed to spend the tokens. #[inline] -pub fn allowance(token: TokenId, owner: AccountId, spender: AccountId) -> Result { +pub fn allowance(token: TokenId, owner: AccountId, spender: AccountId) -> PopApiResult { build_read_state(ALLOWANCE) .input::<(TokenId, AccountId, AccountId)>() - .output::, true>() + .output::, true>() .handle_error_code::() .call(&(token, owner, spender)) } @@ -119,10 +123,10 @@ pub fn allowance(token: TokenId, owner: AccountId, spender: AccountId) -> Result /// - `to` - The recipient account. /// - `value` - The number of tokens to transfer. #[inline] -pub fn transfer(token: TokenId, to: AccountId, value: Balance) -> Result<()> { +pub fn transfer(token: TokenId, to: AccountId, value: Balance) -> PopApiResult<()> { build_dispatch(TRANSFER) .input::<(TokenId, AccountId, Balance)>() - .output::, true>() + .output::, true>() .handle_error_code::() .call(&(token, to, value)) } @@ -135,10 +139,15 @@ pub fn transfer(token: TokenId, to: AccountId, value: Balance) -> Result<()> { /// - `to` - The recipient account. /// - `value` - The number of tokens to transfer. #[inline] -pub fn transfer_from(token: TokenId, from: AccountId, to: AccountId, value: Balance) -> Result<()> { +pub fn transfer_from( + token: TokenId, + from: AccountId, + to: AccountId, + value: Balance, +) -> PopApiResult<()> { build_dispatch(TRANSFER_FROM) .input::<(TokenId, AccountId, AccountId, Balance)>() - .output::, true>() + .output::, true>() .handle_error_code::() .call(&(token, from, to, value)) } @@ -150,10 +159,10 @@ pub fn transfer_from(token: TokenId, from: AccountId, to: AccountId, value: Bala /// - `spender` - The account that is allowed to spend the tokens. /// - `value` - The number of tokens to approve. #[inline] -pub fn approve(token: TokenId, spender: AccountId, value: Balance) -> Result<()> { +pub fn approve(token: TokenId, spender: AccountId, value: Balance) -> PopApiResult<()> { build_dispatch(APPROVE) .input::<(TokenId, AccountId, Balance)>() - .output::, true>() + .output::, true>() .handle_error_code::() .call(&(token, spender, value)) } @@ -165,10 +174,10 @@ pub fn approve(token: TokenId, spender: AccountId, value: Balance) -> Result<()> /// - `spender` - The account that is allowed to spend the tokens. /// - `value` - The number of tokens to increase the allowance by. #[inline] -pub fn increase_allowance(token: TokenId, spender: AccountId, value: Balance) -> Result<()> { +pub fn increase_allowance(token: TokenId, spender: AccountId, value: Balance) -> PopApiResult<()> { build_dispatch(INCREASE_ALLOWANCE) .input::<(TokenId, AccountId, Balance)>() - .output::, true>() + .output::, true>() .handle_error_code::() .call(&(token, spender, value)) } @@ -180,10 +189,10 @@ pub fn increase_allowance(token: TokenId, spender: AccountId, value: Balance) -> /// - `spender` - The account that is allowed to spend the tokens. /// - `value` - The number of tokens to decrease the allowance by. #[inline] -pub fn decrease_allowance(token: TokenId, spender: AccountId, value: Balance) -> Result<()> { +pub fn decrease_allowance(token: TokenId, spender: AccountId, value: Balance) -> PopApiResult<()> { build_dispatch(DECREASE_ALLOWANCE) .input::<(TokenId, AccountId, Balance)>() - .output::, true>() + .output::, true>() .handle_error_code::() .call(&(token, spender, value)) } @@ -195,10 +204,10 @@ pub fn decrease_allowance(token: TokenId, spender: AccountId, value: Balance) -> /// - `account` - The account to be credited with the created tokens. /// - `value` - The number of tokens to mint. #[inline] -pub fn mint(token: TokenId, account: AccountId, value: Balance) -> Result<()> { +pub fn mint(token: TokenId, account: AccountId, value: Balance) -> PopApiResult<()> { build_dispatch(MINT) .input::<(TokenId, AccountId, Balance)>() - .output::, true>() + .output::, true>() .handle_error_code::() .call(&(token, account, value)) } @@ -210,10 +219,10 @@ pub fn mint(token: TokenId, account: AccountId, value: Balance) -> Result<()> { /// - `account` - The account from which the tokens will be destroyed. /// - `value` - The number of tokens to destroy. #[inline] -pub fn burn(token: TokenId, account: AccountId, value: Balance) -> Result<()> { +pub fn burn(token: TokenId, account: AccountId, value: Balance) -> PopApiResult<()> { build_dispatch(BURN) .input::<(TokenId, AccountId, Balance)>() - .output::, true>() + .output::, true>() .handle_error_code::() .call(&(token, account, value)) } @@ -227,10 +236,10 @@ pub mod metadata { /// # Parameters /// - `token` - The token. #[inline] - pub fn token_name(token: TokenId) -> Result> { + pub fn token_name(token: TokenId) -> PopApiResult> { build_read_state(TOKEN_NAME) .input::() - .output::>, true>() + .output::>, true>() .handle_error_code::() .call(&(token)) } @@ -240,10 +249,10 @@ pub mod metadata { /// # Parameters /// - `token` - The token. #[inline] - pub fn token_symbol(token: TokenId) -> Result> { + pub fn token_symbol(token: TokenId) -> PopApiResult> { build_read_state(TOKEN_SYMBOL) .input::() - .output::>, true>() + .output::>, true>() .handle_error_code::() .call(&(token)) } @@ -253,10 +262,10 @@ pub mod metadata { /// # Parameters /// - `token` - The token. #[inline] - pub fn token_decimals(token: TokenId) -> Result { + pub fn token_decimals(token: TokenId) -> PopApiResult { build_read_state(TOKEN_DECIMALS) .input::() - .output::, true>() + .output::, true>() .handle_error_code::() .call(&(token)) } @@ -273,10 +282,10 @@ pub mod management { /// - `admin` - The account that will administer the token. /// - `min_balance` - The minimum balance required for accounts holding this token. #[inline] - pub fn create(id: TokenId, admin: AccountId, min_balance: Balance) -> Result<()> { + pub fn create(id: TokenId, admin: AccountId, min_balance: Balance) -> PopApiResult<()> { build_dispatch(CREATE) .input::<(TokenId, AccountId, Balance)>() - .output::, true>() + .output::, true>() .handle_error_code::() .call(&(id, admin, min_balance)) } @@ -286,10 +295,10 @@ pub mod management { /// # Parameters /// - `token` - The token to be destroyed. #[inline] - pub fn start_destroy(token: TokenId) -> Result<()> { + pub fn start_destroy(token: TokenId) -> PopApiResult<()> { build_dispatch(START_DESTROY) .input::() - .output::, true>() + .output::, true>() .handle_error_code::() .call(&(token)) } @@ -307,10 +316,10 @@ pub mod management { name: Vec, symbol: Vec, decimals: u8, - ) -> Result<()> { + ) -> PopApiResult<()> { build_dispatch(SET_METADATA) .input::<(TokenId, Vec, Vec, u8)>() - .output::, true>() + .output::, true>() .handle_error_code::() .call(&(token, name, symbol, decimals)) } @@ -320,10 +329,10 @@ pub mod management { /// # Parameters /// - `token` - The token to update #[inline] - pub fn clear_metadata(token: TokenId) -> Result<()> { + pub fn clear_metadata(token: TokenId) -> PopApiResult<()> { build_dispatch(CLEAR_METADATA) .input::() - .output::, true>() + .output::, true>() .handle_error_code::() .call(&(token)) } @@ -333,10 +342,10 @@ pub mod management { /// # Parameters /// - `token` - The token. #[inline] - pub fn token_exists(token: TokenId) -> Result { + pub fn token_exists(token: TokenId) -> PopApiResult { build_read_state(TOKEN_EXISTS) .input::() - .output::, true>() + .output::, true>() .handle_error_code::() .call(&(token)) } From 817a35155da041cbfc589549189a5c60fb0a8711 Mon Sep 17 00:00:00 2001 From: chungquantin <56880684+chungquantin@users.noreply.github.com> Date: Wed, 18 Sep 2024 17:59:19 +0800 Subject: [PATCH 074/112] test: psp22error --- pop-api/src/v0/fungibles/tests.rs | 44 ++++++++++++++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) diff --git a/pop-api/src/v0/fungibles/tests.rs b/pop-api/src/v0/fungibles/tests.rs index 128cf4cb..55b832e4 100644 --- a/pop-api/src/v0/fungibles/tests.rs +++ b/pop-api/src/v0/fungibles/tests.rs @@ -1,4 +1,4 @@ -use super::FungiblesError; +use super::{FungiblesError, PSP22Error}; use crate::{ constants::{ASSETS, BALANCES}, primitives::{ @@ -24,6 +24,11 @@ fn into_fungibles_error(error: Error) -> FungiblesError { status_code.into() } +fn into_psp22_error(error: Error) -> PSP22Error { + let status_code: StatusCode = error_into_status_code(error); + status_code.into() +} + // If we ever want to change the conversion from bytes to `u32`. #[test] fn status_code_vs_encoded() { @@ -97,3 +102,40 @@ fn converting_status_code_into_fungibles_error_works() { FungiblesError::NotLive ); } + +#[test] +fn converting_status_code_into_psp22_error_works() { + let other_errors = vec![ + Other, + CannotLookup, + BadOrigin, + // `ModuleError` other than assets module. + Module { index: 2, error: [5, 0] }, + ConsumerRemaining, + NoProviders, + TooManyConsumers, + Token(OnlyProvider), + Arithmetic(Overflow), + Transactional(NoLayer), + Exhausted, + Corruption, + Unavailable, + RootNotAllowed, + Unknown { dispatch_error_index: 5, error_index: 5, error: 1 }, + DecodingFailed, + ]; + for error in other_errors { + let status_code: StatusCode = error_into_status_code(error); + let fungibles_error: PSP22Error = status_code.into(); + assert_eq!(fungibles_error, PSP22Error::Custom(String::from("Other"))) + } + + assert_eq!( + into_psp22_error(Module { index: ASSETS, error: [3, 0] }), + PSP22Error::Custom(String::from("Unknown")) + ); + assert_eq!( + into_psp22_error(Module { index: ASSETS, error: [7, 0] }), + PSP22Error::InsufficientAllowance + ); +} From 6042f09370738a5e4ed24b04ccf5e6fbb39752fa Mon Sep 17 00:00:00 2001 From: chungquantin <56880684+chungquantin@users.noreply.github.com> Date: Wed, 18 Sep 2024 18:27:19 +0800 Subject: [PATCH 075/112] fix: missing String --- pop-api/src/v0/fungibles/errors.rs | 1 + pop-api/src/v0/fungibles/tests.rs | 1 + 2 files changed, 2 insertions(+) diff --git a/pop-api/src/v0/fungibles/errors.rs b/pop-api/src/v0/fungibles/errors.rs index 872e8d64..486077c8 100644 --- a/pop-api/src/v0/fungibles/errors.rs +++ b/pop-api/src/v0/fungibles/errors.rs @@ -1,4 +1,5 @@ use super::*; +use ink::prelude::string::String; /// Represents various errors related to fungible tokens. /// diff --git a/pop-api/src/v0/fungibles/tests.rs b/pop-api/src/v0/fungibles/tests.rs index 55b832e4..bac16335 100644 --- a/pop-api/src/v0/fungibles/tests.rs +++ b/pop-api/src/v0/fungibles/tests.rs @@ -9,6 +9,7 @@ use crate::{ }, StatusCode, }; +use ink::prelude::string::String; use ink::scale::{Decode, Encode}; fn error_into_status_code(error: Error) -> StatusCode { From c8cc9d1112e2c1d6b10cb30a1dcecbd329e8af7a Mon Sep 17 00:00:00 2001 From: chungquantin <56880684+chungquantin@users.noreply.github.com> Date: Thu, 19 Sep 2024 09:24:29 +0800 Subject: [PATCH 076/112] chore: revert example --- pop-api/examples/fungibles/lib.rs | 107 ++++++++++++++---------------- 1 file changed, 49 insertions(+), 58 deletions(-) diff --git a/pop-api/examples/fungibles/lib.rs b/pop-api/examples/fungibles/lib.rs index 0f6bcd63..c46b302f 100755 --- a/pop-api/examples/fungibles/lib.rs +++ b/pop-api/examples/fungibles/lib.rs @@ -3,18 +3,15 @@ use ink::prelude::{string::String, vec::Vec}; use pop_api::{ primitives::TokenId, - v0::fungibles::{ - self as api, - events::Created, - interfaces::{Psp22, Psp22Burnable, Psp22Metadata, Psp22Mintable}, - PSP22Error, PSP22Result, - }, + v0::fungibles::{self as api, events::Created, PSP22Error}, StatusCode, }; #[cfg(test)] mod tests; +type PSP22Result = core::result::Result; + #[ink::contract] mod fungibles { use super::*; @@ -58,103 +55,97 @@ mod fungibles { } #[ink(message)] - pub fn set_metadata( - &self, - name: Vec, - symbol: Vec, - decimals: u8, - ) -> PSP22Result<()> { - api::set_metadata(self.id, name, symbol, decimals).map_err(|e| PSP22Error::from(e)) + pub fn mint(&mut self, account: AccountId, amount: Balance) -> PSP22Result<()> { + api::mint(self.id, account, amount).map_err(|e| PSP22Error::from(e)) } #[ink(message)] - pub fn token_exists(&self) -> PSP22Result { - api::token_exists(self.id).map_err(|e| PSP22Error::from(e)) + pub fn burn(&mut self, account: AccountId, amount: Balance) -> PSP22Result<()> { + api::burn(self.id, account, amount).map_err(|e| PSP22Error::from(e)) } - } - impl Psp22 for Fungibles { #[ink(message)] - fn total_supply(&self) -> Balance { - api::total_supply(self.id).unwrap_or_default() + pub fn transfer(&mut self, to: AccountId, value: Balance) -> PSP22Result<()> { + api::transfer(self.id, to, value).map_err(|e| PSP22Error::from(e)) } #[ink(message)] - fn balance_of(&self, owner: AccountId) -> Balance { - api::balance_of(self.id, owner).unwrap_or_default() + pub fn transfer_from( + &mut self, + from: AccountId, + to: AccountId, + value: Balance, + _data: Vec, + ) -> PSP22Result<()> { + api::transfer_from(self.id, from, to, value).map_err(|e| PSP22Error::from(e)) } #[ink(message)] - fn allowance(&self, owner: AccountId, spender: AccountId) -> Balance { - api::allowance(self.id, owner, spender).unwrap_or_default() + pub fn approve(&mut self, spender: AccountId, value: Balance) -> PSP22Result<()> { + api::approve(self.id, spender, value).map_err(|e| PSP22Error::from(e)) } #[ink(message)] - fn transfer(&mut self, to: AccountId, value: Balance, _data: Vec) -> PSP22Result<()> { - api::transfer(self.id, to, value).map_err(|e| PSP22Error::from(e)) + pub fn increase_allowance( + &mut self, + spender: AccountId, + value: Balance, + ) -> PSP22Result<()> { + api::increase_allowance(self.id, spender, value).map_err(|e| PSP22Error::from(e)) } #[ink(message)] - fn transfer_from( + pub fn decrease_allowance( &mut self, - from: AccountId, - to: AccountId, + spender: AccountId, value: Balance, - _data: Vec, ) -> PSP22Result<()> { - api::transfer_from(self.id, from, to, value).map_err(|e| PSP22Error::from(e)) + api::decrease_allowance(self.id, spender, value).map_err(|e| PSP22Error::from(e)) } #[ink(message)] - fn approve(&mut self, spender: AccountId, value: Balance) -> PSP22Result<()> { - api::approve(self.id, spender, value).map_err(|e| PSP22Error::from(e)) + pub fn set_metadata( + &self, + name: Vec, + symbol: Vec, + decimals: u8, + ) -> PSP22Result<()> { + api::set_metadata(self.id, name, symbol, decimals).map_err(|e| PSP22Error::from(e)) } #[ink(message)] - fn increase_allowance(&mut self, spender: AccountId, value: Balance) -> PSP22Result<()> { - api::increase_allowance(self.id, spender, value).map_err(|e| PSP22Error::from(e)) + pub fn total_supply(&self) -> PSP22Result { + api::total_supply(self.id).map_err(|e| PSP22Error::from(e)) } #[ink(message)] - fn decrease_allowance(&mut self, spender: AccountId, value: Balance) -> PSP22Result<()> { - api::decrease_allowance(self.id, spender, value).map_err(|e| PSP22Error::from(e)) + pub fn balance_of(&self, owner: AccountId) -> PSP22Result { + api::balance_of(self.id, owner).map_err(|e| PSP22Error::from(e)) } - } - impl Psp22Metadata for Fungibles { #[ink(message)] - fn token_name(&self) -> Option> { - if let Ok(value) = api::token_name(self.id) { - return Some(value); - } - None + pub fn allowance(&self, owner: AccountId, spender: AccountId) -> PSP22Result { + api::allowance(self.id, owner, spender).map_err(|e| PSP22Error::from(e)) } #[ink(message)] - fn token_symbol(&self) -> Option> { - if let Ok(value) = api::token_symbol(self.id) { - return Some(value); - } - None + pub fn token_name(&self) -> PSP22Result> { + api::token_name(self.id).map_err(|e| PSP22Error::from(e)) } #[ink(message)] - fn token_decimals(&self) -> u8 { - api::token_decimals(self.id).unwrap_or_default() + pub fn token_symbol(&self) -> PSP22Result> { + api::token_symbol(self.id).map_err(|e| PSP22Error::from(e)) } - } - impl Psp22Mintable for Fungibles { #[ink(message)] - fn mint(&mut self, account: AccountId, amount: Balance) -> PSP22Result<()> { - api::mint(self.id, account, amount).map_err(|e| PSP22Error::from(e)) + pub fn token_decimals(&self) -> PSP22Result { + api::token_decimals(self.id).map_err(|e| PSP22Error::from(e)) } - } - impl Psp22Burnable for Fungibles { #[ink(message)] - fn burn(&mut self, account: AccountId, amount: Balance) -> PSP22Result<()> { - api::burn(self.id, account, amount).map_err(|e| PSP22Error::from(e)) + pub fn token_exists(&self) -> PSP22Result { + api::token_exists(self.id).map_err(|e| PSP22Error::from(e)) } } } From a8c063ca1de592785f2cd349462f67324905199a Mon Sep 17 00:00:00 2001 From: chungquantin <56880684+chungquantin@users.noreply.github.com> Date: Thu, 19 Sep 2024 09:41:13 +0800 Subject: [PATCH 077/112] fix: resolve comments --- pop-api/src/v0/fungibles/errors.rs | 149 ++++++++++++++++++ pop-api/src/v0/fungibles/events.rs | 20 +-- pop-api/src/v0/fungibles/mod.rs | 103 ++++++------ pop-api/src/v0/fungibles/tests.rs | 142 ----------------- .../v0/fungibles/{interfaces.rs => traits.rs} | 52 +----- 5 files changed, 211 insertions(+), 255 deletions(-) delete mode 100644 pop-api/src/v0/fungibles/tests.rs rename pop-api/src/v0/fungibles/{interfaces.rs => traits.rs} (68%) diff --git a/pop-api/src/v0/fungibles/errors.rs b/pop-api/src/v0/fungibles/errors.rs index 486077c8..c8dae082 100644 --- a/pop-api/src/v0/fungibles/errors.rs +++ b/pop-api/src/v0/fungibles/errors.rs @@ -11,6 +11,7 @@ use ink::prelude::string::String; /// operations. The `Other` variant serves as a catch-all for any unexpected errors. For more /// detailed debugging, the `Other` variant can be converted into the richer `Error` type defined in /// the primitives crate. +/// NOTE: The `FungiblesError` is WIP #[derive(Debug, PartialEq, Eq)] #[ink::scale_derive(Encode, Decode, TypeInfo)] pub enum FungiblesError { @@ -64,6 +65,7 @@ impl From for FungiblesError { } /// The PSP22 error. +/// TODO: Issue https://github.com/r0gue-io/pop-node/issues/298 #[derive(Debug, PartialEq, Eq)] #[ink::scale_derive(Encode, Decode, TypeInfo)] pub enum PSP22Error { @@ -92,3 +94,150 @@ impl From for PSP22Error { } } } + +#[cfg(test)] +mod tests { + use super::{FungiblesError, PSP22Error}; + use crate::{ + constants::{ASSETS, BALANCES}, + primitives::{ + ArithmeticError::*, + Error::{self, *}, + TokenError::*, + TransactionalError::*, + }, + StatusCode, + }; + use ink::prelude::string::String; + use ink::scale::{Decode, Encode}; + + fn error_into_status_code(error: Error) -> StatusCode { + let mut encoded_error = error.encode(); + encoded_error.resize(4, 0); + let value = u32::from_le_bytes( + encoded_error.try_into().expect("qed, resized to 4 bytes line above"), + ); + value.into() + } + + fn into_fungibles_error(error: Error) -> FungiblesError { + let status_code: StatusCode = error_into_status_code(error); + status_code.into() + } + + fn into_psp22_error(error: Error) -> PSP22Error { + let status_code: StatusCode = error_into_status_code(error); + status_code.into() + } + + // If we ever want to change the conversion from bytes to `u32`. + #[test] + fn status_code_vs_encoded() { + assert_eq!(u32::decode(&mut &[3u8, 10, 2, 0][..]).unwrap(), 133635u32); + assert_eq!(u32::decode(&mut &[3u8, 52, 0, 0][..]).unwrap(), 13315u32); + assert_eq!(u32::decode(&mut &[3u8, 52, 1, 0][..]).unwrap(), 78851u32); + assert_eq!(u32::decode(&mut &[3u8, 52, 2, 0][..]).unwrap(), 144387u32); + assert_eq!(u32::decode(&mut &[3u8, 52, 3, 0][..]).unwrap(), 209923u32); + assert_eq!(u32::decode(&mut &[3u8, 52, 5, 0][..]).unwrap(), 340995u32); + assert_eq!(u32::decode(&mut &[3u8, 52, 7, 0][..]).unwrap(), 472067u32); + assert_eq!(u32::decode(&mut &[3u8, 52, 10, 0][..]).unwrap(), 668675u32); + } + + #[test] + fn converting_status_code_into_fungibles_error_works() { + let other_errors = vec![ + Other, + CannotLookup, + BadOrigin, + // `ModuleError` other than assets module. + Module { index: 2, error: [5, 0] }, + ConsumerRemaining, + NoProviders, + TooManyConsumers, + Token(OnlyProvider), + Arithmetic(Overflow), + Transactional(NoLayer), + Exhausted, + Corruption, + Unavailable, + RootNotAllowed, + Unknown { dispatch_error_index: 5, error_index: 5, error: 1 }, + DecodingFailed, + ]; + for error in other_errors { + let status_code: StatusCode = error_into_status_code(error); + let fungibles_error: FungiblesError = status_code.into(); + assert_eq!(fungibles_error, FungiblesError::Other(status_code)) + } + + assert_eq!( + into_fungibles_error(Module { index: BALANCES, error: [2, 0] }), + FungiblesError::NoBalance + ); + assert_eq!( + into_fungibles_error(Module { index: ASSETS, error: [0, 0] }), + FungiblesError::NoAccount + ); + assert_eq!( + into_fungibles_error(Module { index: ASSETS, error: [1, 0] }), + FungiblesError::NoPermission + ); + assert_eq!( + into_fungibles_error(Module { index: ASSETS, error: [2, 0] }), + FungiblesError::Unknown + ); + assert_eq!( + into_fungibles_error(Module { index: ASSETS, error: [3, 0] }), + FungiblesError::InUse + ); + assert_eq!( + into_fungibles_error(Module { index: ASSETS, error: [5, 0] }), + FungiblesError::MinBalanceZero + ); + assert_eq!( + into_fungibles_error(Module { index: ASSETS, error: [7, 0] }), + FungiblesError::InsufficientAllowance + ); + assert_eq!( + into_fungibles_error(Module { index: ASSETS, error: [10, 0] }), + FungiblesError::NotLive + ); + } + + #[test] + fn converting_status_code_into_psp22_error_works() { + let other_errors = vec![ + Other, + CannotLookup, + BadOrigin, + // `ModuleError` other than assets module. + Module { index: 2, error: [5, 0] }, + ConsumerRemaining, + NoProviders, + TooManyConsumers, + Token(OnlyProvider), + Arithmetic(Overflow), + Transactional(NoLayer), + Exhausted, + Corruption, + Unavailable, + RootNotAllowed, + Unknown { dispatch_error_index: 5, error_index: 5, error: 1 }, + DecodingFailed, + ]; + for error in other_errors { + let status_code: StatusCode = error_into_status_code(error); + let fungibles_error: PSP22Error = status_code.into(); + assert_eq!(fungibles_error, PSP22Error::Custom(String::from("Other"))) + } + + assert_eq!( + into_psp22_error(Module { index: ASSETS, error: [3, 0] }), + PSP22Error::Custom(String::from("Unknown")) + ); + assert_eq!( + into_psp22_error(Module { index: ASSETS, error: [7, 0] }), + PSP22Error::InsufficientAllowance + ); + } +} diff --git a/pop-api/src/v0/fungibles/events.rs b/pop-api/src/v0/fungibles/events.rs index b0639e10..a018ac59 100644 --- a/pop-api/src/v0/fungibles/events.rs +++ b/pop-api/src/v0/fungibles/events.rs @@ -1,15 +1,16 @@ -/// A set of events for use in smart contracts interacting with the fungibles API. -/// -/// The `Transfer` and `Approval` events conform to the PSP-22 standard. The other events -/// (`Create`, `StartDestroy`, `SetMetadata`, `ClearMetadata`) are provided for convenience. -/// -/// These events are not emitted by the API itself but can be used in your contracts to -/// track token operations. Be mindful of the costs associated with emitting events. -/// -/// For more details, refer to [ink! events](https://use.ink/basics/events). +//! A set of events for use in smart contracts interacting with the fungibles API. +//! +//! The `Transfer` and `Approval` events conform to the PSP-22 standard. The other events +//! (`Create`, `StartDestroy`, `SetMetadata`, `ClearMetadata`) are provided for convenience. +//! +//! These events are not emitted by the API itself but can be used in your contracts to +//! track token operations. Be mindful of the costs associated with emitting events. +//! +//! For more details, refer to [ink! events](https://use.ink/basics/events). use super::*; /// Event emitted when allowance by `owner` to `spender` changes. +// Differing style: event name abides by the PSP22 standard. #[ink::event] pub struct Approval { /// The owner providing the allowance. @@ -23,6 +24,7 @@ pub struct Approval { } /// Event emitted when transfer of tokens occurs. +// Differing style: event name abides by the PSP22 standard. #[ink::event] pub struct Transfer { /// The source of the transfer. `None` when minting. diff --git a/pop-api/src/v0/fungibles/mod.rs b/pop-api/src/v0/fungibles/mod.rs index da731819..e864f690 100644 --- a/pop-api/src/v0/fungibles/mod.rs +++ b/pop-api/src/v0/fungibles/mod.rs @@ -1,15 +1,10 @@ //! The `fungibles` module provides an API for interacting and managing fungible tokens. //! -//! The API includes the following interfaces: +//! The API includes the following traits: //! 1. PSP-22 //! 2. PSP-22 Metadata //! 3. Management //! 4. PSP-22 Mintable & Burnable -pub mod errors; -pub mod events; -pub mod interfaces; -#[cfg(test)] -mod tests; use crate::{ constants::{ASSETS, BALANCES, FUNGIBLES}, @@ -17,60 +12,18 @@ use crate::{ ChainExtensionMethodApi, StatusCode, }; use constants::*; -use core::result::Result; pub use errors::*; pub use events::*; use ink::prelude::vec::Vec; -pub use interfaces::*; pub use management::*; pub use metadata::*; +pub use traits::*; -pub type PSP22Result = Result; -pub type PopApiResult = Result; - -// Helper method to build a dispatch call. -// -// Parameters: -// - 'dispatchable': The index of the dispatchable function within the module. -fn build_dispatch(dispatchable: u8) -> ChainExtensionMethodApi { - crate::v0::build_dispatch(FUNGIBLES, dispatchable) -} - -// Helper method to build a call to read state. -// -// Parameters: -// - 'state_query': The index of the runtime state query. -fn build_read_state(state_query: u8) -> ChainExtensionMethodApi { - crate::v0::build_read_state(FUNGIBLES, state_query) -} - -mod constants { - /// 1. PSP-22 Interface: - pub(super) const TOTAL_SUPPLY: u8 = 0; - pub(super) const BALANCE_OF: u8 = 1; - pub(super) const ALLOWANCE: u8 = 2; - pub(super) const TRANSFER: u8 = 3; - pub(super) const TRANSFER_FROM: u8 = 4; - pub(super) const APPROVE: u8 = 5; - pub(super) const INCREASE_ALLOWANCE: u8 = 6; - pub(super) const DECREASE_ALLOWANCE: u8 = 7; - - /// 2. PSP-22 Metadata Interface: - pub(super) const TOKEN_NAME: u8 = 8; - pub(super) const TOKEN_SYMBOL: u8 = 9; - pub(super) const TOKEN_DECIMALS: u8 = 10; +pub mod errors; +pub mod events; +pub mod traits; - /// 3. Asset Management: - pub(super) const CREATE: u8 = 11; - pub(super) const START_DESTROY: u8 = 12; - pub(super) const SET_METADATA: u8 = 16; - pub(super) const CLEAR_METADATA: u8 = 17; - pub(super) const TOKEN_EXISTS: u8 = 18; - - /// 4. PSP-22 Mintable & Burnable interface: - pub(super) const MINT: u8 = 19; - pub(super) const BURN: u8 = 20; -} +pub type PSP22Result = core::result::Result; /// Returns the total token supply for a specified token. /// @@ -350,3 +303,47 @@ pub mod management { .call(&(token)) } } + +mod constants { + /// 1. PSP-22 Interface: + pub(super) const TOTAL_SUPPLY: u8 = 0; + pub(super) const BALANCE_OF: u8 = 1; + pub(super) const ALLOWANCE: u8 = 2; + pub(super) const TRANSFER: u8 = 3; + pub(super) const TRANSFER_FROM: u8 = 4; + pub(super) const APPROVE: u8 = 5; + pub(super) const INCREASE_ALLOWANCE: u8 = 6; + pub(super) const DECREASE_ALLOWANCE: u8 = 7; + + /// 2. PSP-22 Metadata Interface: + pub(super) const TOKEN_NAME: u8 = 8; + pub(super) const TOKEN_SYMBOL: u8 = 9; + pub(super) const TOKEN_DECIMALS: u8 = 10; + + /// 3. Asset Management: + pub(super) const CREATE: u8 = 11; + pub(super) const START_DESTROY: u8 = 12; + pub(super) const SET_METADATA: u8 = 16; + pub(super) const CLEAR_METADATA: u8 = 17; + pub(super) const TOKEN_EXISTS: u8 = 18; + + /// 4. PSP-22 Mintable & Burnable interface: + pub(super) const MINT: u8 = 19; + pub(super) const BURN: u8 = 20; +} + +// Helper method to build a dispatch call. +// +// Parameters: +// - 'dispatchable': The index of the dispatchable function within the module. +fn build_dispatch(dispatchable: u8) -> ChainExtensionMethodApi { + crate::v0::build_dispatch(FUNGIBLES, dispatchable) +} + +// Helper method to build a call to read state. +// +// Parameters: +// - 'state_query': The index of the runtime state query. +fn build_read_state(state_query: u8) -> ChainExtensionMethodApi { + crate::v0::build_read_state(FUNGIBLES, state_query) +} diff --git a/pop-api/src/v0/fungibles/tests.rs b/pop-api/src/v0/fungibles/tests.rs deleted file mode 100644 index bac16335..00000000 --- a/pop-api/src/v0/fungibles/tests.rs +++ /dev/null @@ -1,142 +0,0 @@ -use super::{FungiblesError, PSP22Error}; -use crate::{ - constants::{ASSETS, BALANCES}, - primitives::{ - ArithmeticError::*, - Error::{self, *}, - TokenError::*, - TransactionalError::*, - }, - StatusCode, -}; -use ink::prelude::string::String; -use ink::scale::{Decode, Encode}; - -fn error_into_status_code(error: Error) -> StatusCode { - let mut encoded_error = error.encode(); - encoded_error.resize(4, 0); - let value = - u32::from_le_bytes(encoded_error.try_into().expect("qed, resized to 4 bytes line above")); - value.into() -} - -fn into_fungibles_error(error: Error) -> FungiblesError { - let status_code: StatusCode = error_into_status_code(error); - status_code.into() -} - -fn into_psp22_error(error: Error) -> PSP22Error { - let status_code: StatusCode = error_into_status_code(error); - status_code.into() -} - -// If we ever want to change the conversion from bytes to `u32`. -#[test] -fn status_code_vs_encoded() { - assert_eq!(u32::decode(&mut &[3u8, 10, 2, 0][..]).unwrap(), 133635u32); - assert_eq!(u32::decode(&mut &[3u8, 52, 0, 0][..]).unwrap(), 13315u32); - assert_eq!(u32::decode(&mut &[3u8, 52, 1, 0][..]).unwrap(), 78851u32); - assert_eq!(u32::decode(&mut &[3u8, 52, 2, 0][..]).unwrap(), 144387u32); - assert_eq!(u32::decode(&mut &[3u8, 52, 3, 0][..]).unwrap(), 209923u32); - assert_eq!(u32::decode(&mut &[3u8, 52, 5, 0][..]).unwrap(), 340995u32); - assert_eq!(u32::decode(&mut &[3u8, 52, 7, 0][..]).unwrap(), 472067u32); - assert_eq!(u32::decode(&mut &[3u8, 52, 10, 0][..]).unwrap(), 668675u32); -} - -#[test] -fn converting_status_code_into_fungibles_error_works() { - let other_errors = vec![ - Other, - CannotLookup, - BadOrigin, - // `ModuleError` other than assets module. - Module { index: 2, error: [5, 0] }, - ConsumerRemaining, - NoProviders, - TooManyConsumers, - Token(OnlyProvider), - Arithmetic(Overflow), - Transactional(NoLayer), - Exhausted, - Corruption, - Unavailable, - RootNotAllowed, - Unknown { dispatch_error_index: 5, error_index: 5, error: 1 }, - DecodingFailed, - ]; - for error in other_errors { - let status_code: StatusCode = error_into_status_code(error); - let fungibles_error: FungiblesError = status_code.into(); - assert_eq!(fungibles_error, FungiblesError::Other(status_code)) - } - - assert_eq!( - into_fungibles_error(Module { index: BALANCES, error: [2, 0] }), - FungiblesError::NoBalance - ); - assert_eq!( - into_fungibles_error(Module { index: ASSETS, error: [0, 0] }), - FungiblesError::NoAccount - ); - assert_eq!( - into_fungibles_error(Module { index: ASSETS, error: [1, 0] }), - FungiblesError::NoPermission - ); - assert_eq!( - into_fungibles_error(Module { index: ASSETS, error: [2, 0] }), - FungiblesError::Unknown - ); - assert_eq!( - into_fungibles_error(Module { index: ASSETS, error: [3, 0] }), - FungiblesError::InUse - ); - assert_eq!( - into_fungibles_error(Module { index: ASSETS, error: [5, 0] }), - FungiblesError::MinBalanceZero - ); - assert_eq!( - into_fungibles_error(Module { index: ASSETS, error: [7, 0] }), - FungiblesError::InsufficientAllowance - ); - assert_eq!( - into_fungibles_error(Module { index: ASSETS, error: [10, 0] }), - FungiblesError::NotLive - ); -} - -#[test] -fn converting_status_code_into_psp22_error_works() { - let other_errors = vec![ - Other, - CannotLookup, - BadOrigin, - // `ModuleError` other than assets module. - Module { index: 2, error: [5, 0] }, - ConsumerRemaining, - NoProviders, - TooManyConsumers, - Token(OnlyProvider), - Arithmetic(Overflow), - Transactional(NoLayer), - Exhausted, - Corruption, - Unavailable, - RootNotAllowed, - Unknown { dispatch_error_index: 5, error_index: 5, error: 1 }, - DecodingFailed, - ]; - for error in other_errors { - let status_code: StatusCode = error_into_status_code(error); - let fungibles_error: PSP22Error = status_code.into(); - assert_eq!(fungibles_error, PSP22Error::Custom(String::from("Other"))) - } - - assert_eq!( - into_psp22_error(Module { index: ASSETS, error: [3, 0] }), - PSP22Error::Custom(String::from("Unknown")) - ); - assert_eq!( - into_psp22_error(Module { index: ASSETS, error: [7, 0] }), - PSP22Error::InsufficientAllowance - ); -} diff --git a/pop-api/src/v0/fungibles/interfaces.rs b/pop-api/src/v0/fungibles/traits.rs similarity index 68% rename from pop-api/src/v0/fungibles/interfaces.rs rename to pop-api/src/v0/fungibles/traits.rs index a4b48a4c..74ef742a 100644 --- a/pop-api/src/v0/fungibles/interfaces.rs +++ b/pop-api/src/v0/fungibles/traits.rs @@ -38,6 +38,7 @@ pub trait Psp22 { /// - `from` - The account from which the token balance will be withdrawn. /// - `to` - The recipient account. /// - `value` - The number of tokens to transfer. + /// - `data` - Additional data with unspecified format. #[ink(message)] fn transfer_from( &mut self, @@ -74,57 +75,6 @@ pub trait Psp22 { fn decrease_allowance(&mut self, spender: AccountId, value: Balance) -> PSP22Result<()>; } -/// The PSP22 Metadata trait. -#[ink::trait_definition] -pub trait Management { - /// Creates a new token with the specified `id`, assigns `admin` as the administrator, - /// and sets a minimum balance requirement. - /// - /// # Parameters - /// - `id`: The unique identifier for the token to be created. - /// - `admin`: The account that will have administrative privileges over the token. - /// - `min_balance`: The minimum balance required to hold the token. - #[ink(message)] - fn create(&mut self, id: TokenId, admin: AccountId, min_balance: Balance) -> PSP22Result<()>; - - /// Initiates the process to destroy the specified `token`. - /// - /// # Parameters - /// - `token`: The identifier of the token to be destroyed. - #[ink(message)] - fn start_destroy(&mut self, token: TokenId) -> PSP22Result<()>; - - /// Sets metadata for the specified `token`, including its name, symbol, and decimal places. - /// - /// # Parameters - /// - `token`: The identifier of the token to set metadata for. - /// - `name`: The name of the token. - /// - `symbol`: The symbol representing the token. - /// - `decimals`: The number of decimal places the token uses. - #[ink(message)] - fn set_metadata( - &mut self, - token: TokenId, - name: Vec, - symbol: Vec, - decimals: u8, - ) -> PSP22Result<()>; - - /// Clears the metadata for the specified `token`. - /// - /// # Parameters - /// - `token`: The identifier of the token to clear metadata for. - #[ink(message)] - fn clear_metadata(&mut self, token: TokenId) -> PSP22Result<()>; - - /// Checks whether a token with the specified `token` identifier exists. - /// - /// # Parameters - /// - `token`: The identifier of the token to check for existence. - #[ink(message)] - fn token_exists(&self, token: TokenId) -> PSP22Result; -} - /// The PSP22 Metadata trait. #[ink::trait_definition] pub trait Psp22Metadata { From 817647490967e06f023494782250883fdd9140a0 Mon Sep 17 00:00:00 2001 From: chungquantin <56880684+chungquantin@users.noreply.github.com> Date: Thu, 19 Sep 2024 09:43:31 +0800 Subject: [PATCH 078/112] fix: revert example contract --- pop-api/examples/fungibles/lib.rs | 129 ++++++++++-------------------- 1 file changed, 43 insertions(+), 86 deletions(-) diff --git a/pop-api/examples/fungibles/lib.rs b/pop-api/examples/fungibles/lib.rs index c46b302f..11eafe21 100755 --- a/pop-api/examples/fungibles/lib.rs +++ b/pop-api/examples/fungibles/lib.rs @@ -1,151 +1,108 @@ #![cfg_attr(not(feature = "std"), no_std, no_main)] -use ink::prelude::{string::String, vec::Vec}; +use ink::prelude::vec::Vec; use pop_api::{ + fungibles::{self as api}, primitives::TokenId, - v0::fungibles::{self as api, events::Created, PSP22Error}, StatusCode, }; -#[cfg(test)] -mod tests; - -type PSP22Result = core::result::Result; +pub type Result = core::result::Result; #[ink::contract] mod fungibles { use super::*; #[ink(storage)] - pub struct Fungibles { - id: TokenId, - } + #[derive(Default)] + pub struct Fungibles; impl Fungibles { - /// Instantiate the contract and wrap around an existing token. - /// - /// # Parameters - /// * - `token` - The token. #[ink(constructor, payable)] - pub fn new_existing(id: TokenId) -> PSP22Result { - // Make sure token exists. - if !api::token_exists(id).unwrap_or_default() { - return Err(PSP22Error::Custom(String::from("Unknown"))); - } - let contract = Self { id }; - Ok(contract) + pub fn new() -> Self { + Default::default() } - /// Instantiate the contract and create a new token. The token identifier will be stored - /// in contract's storage. - /// - /// # Parameters - /// * - `id` - The identifier of the token. - /// * - `admin` - The account that will administer the token. - /// * - `min_balance` - The minimum balance required for accounts holding this token. - #[ink(constructor, payable)] - pub fn new(id: TokenId, admin: AccountId, min_balance: Balance) -> PSP22Result { - // TODO: should be nicer conversion possible. - api::create(id, admin, min_balance).map_err(|e| PSP22Error::from(e))?; - let contract = Self { id }; - contract - .env() - .emit_event(Created { id, creator: contract.env().account_id(), admin }); - Ok(contract) + #[ink(message)] + pub fn total_supply(&self, token: TokenId) -> Result { + api::total_supply(token) } #[ink(message)] - pub fn mint(&mut self, account: AccountId, amount: Balance) -> PSP22Result<()> { - api::mint(self.id, account, amount).map_err(|e| PSP22Error::from(e)) + pub fn balance_of(&self, token: TokenId, owner: AccountId) -> Result { + api::balance_of(token, owner) } #[ink(message)] - pub fn burn(&mut self, account: AccountId, amount: Balance) -> PSP22Result<()> { - api::burn(self.id, account, amount).map_err(|e| PSP22Error::from(e)) + pub fn allowance( + &self, + token: TokenId, + owner: AccountId, + spender: AccountId, + ) -> Result { + api::allowance(token, owner, spender) } #[ink(message)] - pub fn transfer(&mut self, to: AccountId, value: Balance) -> PSP22Result<()> { - api::transfer(self.id, to, value).map_err(|e| PSP22Error::from(e)) + pub fn transfer(&mut self, token: TokenId, to: AccountId, value: Balance) -> Result<()> { + api::transfer(token, to, value) } #[ink(message)] pub fn transfer_from( &mut self, + token: TokenId, from: AccountId, to: AccountId, value: Balance, _data: Vec, - ) -> PSP22Result<()> { - api::transfer_from(self.id, from, to, value).map_err(|e| PSP22Error::from(e)) + ) -> Result<()> { + api::transfer_from(token, from, to, value) } #[ink(message)] - pub fn approve(&mut self, spender: AccountId, value: Balance) -> PSP22Result<()> { - api::approve(self.id, spender, value).map_err(|e| PSP22Error::from(e)) + pub fn approve( + &mut self, + token: TokenId, + spender: AccountId, + value: Balance, + ) -> Result<()> { + api::approve(token, spender, value) } #[ink(message)] pub fn increase_allowance( &mut self, + token: TokenId, spender: AccountId, value: Balance, - ) -> PSP22Result<()> { - api::increase_allowance(self.id, spender, value).map_err(|e| PSP22Error::from(e)) + ) -> Result<()> { + api::increase_allowance(token, spender, value) } #[ink(message)] pub fn decrease_allowance( &mut self, + token: TokenId, spender: AccountId, value: Balance, - ) -> PSP22Result<()> { - api::decrease_allowance(self.id, spender, value).map_err(|e| PSP22Error::from(e)) - } - - #[ink(message)] - pub fn set_metadata( - &self, - name: Vec, - symbol: Vec, - decimals: u8, - ) -> PSP22Result<()> { - api::set_metadata(self.id, name, symbol, decimals).map_err(|e| PSP22Error::from(e)) - } - - #[ink(message)] - pub fn total_supply(&self) -> PSP22Result { - api::total_supply(self.id).map_err(|e| PSP22Error::from(e)) - } - - #[ink(message)] - pub fn balance_of(&self, owner: AccountId) -> PSP22Result { - api::balance_of(self.id, owner).map_err(|e| PSP22Error::from(e)) - } - - #[ink(message)] - pub fn allowance(&self, owner: AccountId, spender: AccountId) -> PSP22Result { - api::allowance(self.id, owner, spender).map_err(|e| PSP22Error::from(e)) - } - - #[ink(message)] - pub fn token_name(&self) -> PSP22Result> { - api::token_name(self.id).map_err(|e| PSP22Error::from(e)) + ) -> Result<()> { + api::decrease_allowance(token, spender, value) } #[ink(message)] - pub fn token_symbol(&self) -> PSP22Result> { - api::token_symbol(self.id).map_err(|e| PSP22Error::from(e)) + pub fn token_name(&self, token: TokenId) -> Result> { + api::token_name(token) } #[ink(message)] - pub fn token_decimals(&self) -> PSP22Result { - api::token_decimals(self.id).map_err(|e| PSP22Error::from(e)) + pub fn token_symbol(&self, token: TokenId) -> Result> { + api::token_symbol(token) } #[ink(message)] - pub fn token_exists(&self) -> PSP22Result { - api::token_exists(self.id).map_err(|e| PSP22Error::from(e)) + pub fn token_decimals(&self, token: TokenId) -> Result { + api::token_decimals(token) } } } From 1945683237e7a6a018344f953b86cf06a3a33803 Mon Sep 17 00:00:00 2001 From: chungquantin <56880684+chungquantin@users.noreply.github.com> Date: Thu, 19 Sep 2024 09:46:14 +0800 Subject: [PATCH 079/112] fix: add mod comment --- pop-api/src/v0/fungibles/errors.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/pop-api/src/v0/fungibles/errors.rs b/pop-api/src/v0/fungibles/errors.rs index c8dae082..30d98285 100644 --- a/pop-api/src/v0/fungibles/errors.rs +++ b/pop-api/src/v0/fungibles/errors.rs @@ -1,3 +1,4 @@ +//! A set of errors for use in smart contracts to manage the returned errors. use super::*; use ink::prelude::string::String; From 6aede89bc5fc3b05cfb04b4ed5c394bb28e116f2 Mon Sep 17 00:00:00 2001 From: chungquantin <56880684+chungquantin@users.noreply.github.com> Date: Thu, 19 Sep 2024 21:37:49 +0700 Subject: [PATCH 080/112] fix: result type --- pop-api/src/v0/fungibles/mod.rs | 79 +++++++++++++++------------------ 1 file changed, 37 insertions(+), 42 deletions(-) diff --git a/pop-api/src/v0/fungibles/mod.rs b/pop-api/src/v0/fungibles/mod.rs index e864f690..fe6c685e 100644 --- a/pop-api/src/v0/fungibles/mod.rs +++ b/pop-api/src/v0/fungibles/mod.rs @@ -9,7 +9,7 @@ use crate::{ constants::{ASSETS, BALANCES, FUNGIBLES}, primitives::{AccountId, Balance, TokenId}, - ChainExtensionMethodApi, StatusCode, + ChainExtensionMethodApi, Result, StatusCode, }; use constants::*; pub use errors::*; @@ -30,10 +30,10 @@ pub type PSP22Result = core::result::Result; /// # Parameters /// - `token` - The token. #[inline] -pub fn total_supply(token: TokenId) -> PopApiResult { +pub fn total_supply(token: TokenId) -> Result { build_read_state(TOTAL_SUPPLY) .input::() - .output::, true>() + .output::, true>() .handle_error_code::() .call(&(token)) } @@ -45,10 +45,10 @@ pub fn total_supply(token: TokenId) -> PopApiResult { /// - `token` - The token. /// - `owner` - The account whose balance is being queried. #[inline] -pub fn balance_of(token: TokenId, owner: AccountId) -> PopApiResult { +pub fn balance_of(token: TokenId, owner: AccountId) -> Result { build_read_state(BALANCE_OF) .input::<(TokenId, AccountId)>() - .output::, true>() + .output::, true>() .handle_error_code::() .call(&(token, owner)) } @@ -61,10 +61,10 @@ pub fn balance_of(token: TokenId, owner: AccountId) -> PopApiResult { /// - `owner` - The account that owns the tokens. /// - `spender` - The account that is allowed to spend the tokens. #[inline] -pub fn allowance(token: TokenId, owner: AccountId, spender: AccountId) -> PopApiResult { +pub fn allowance(token: TokenId, owner: AccountId, spender: AccountId) -> Result { build_read_state(ALLOWANCE) .input::<(TokenId, AccountId, AccountId)>() - .output::, true>() + .output::, true>() .handle_error_code::() .call(&(token, owner, spender)) } @@ -76,10 +76,10 @@ pub fn allowance(token: TokenId, owner: AccountId, spender: AccountId) -> PopApi /// - `to` - The recipient account. /// - `value` - The number of tokens to transfer. #[inline] -pub fn transfer(token: TokenId, to: AccountId, value: Balance) -> PopApiResult<()> { +pub fn transfer(token: TokenId, to: AccountId, value: Balance) -> Result<()> { build_dispatch(TRANSFER) .input::<(TokenId, AccountId, Balance)>() - .output::, true>() + .output::, true>() .handle_error_code::() .call(&(token, to, value)) } @@ -92,15 +92,10 @@ pub fn transfer(token: TokenId, to: AccountId, value: Balance) -> PopApiResult<( /// - `to` - The recipient account. /// - `value` - The number of tokens to transfer. #[inline] -pub fn transfer_from( - token: TokenId, - from: AccountId, - to: AccountId, - value: Balance, -) -> PopApiResult<()> { +pub fn transfer_from(token: TokenId, from: AccountId, to: AccountId, value: Balance) -> Result<()> { build_dispatch(TRANSFER_FROM) .input::<(TokenId, AccountId, AccountId, Balance)>() - .output::, true>() + .output::, true>() .handle_error_code::() .call(&(token, from, to, value)) } @@ -112,10 +107,10 @@ pub fn transfer_from( /// - `spender` - The account that is allowed to spend the tokens. /// - `value` - The number of tokens to approve. #[inline] -pub fn approve(token: TokenId, spender: AccountId, value: Balance) -> PopApiResult<()> { +pub fn approve(token: TokenId, spender: AccountId, value: Balance) -> Result<()> { build_dispatch(APPROVE) .input::<(TokenId, AccountId, Balance)>() - .output::, true>() + .output::, true>() .handle_error_code::() .call(&(token, spender, value)) } @@ -127,10 +122,10 @@ pub fn approve(token: TokenId, spender: AccountId, value: Balance) -> PopApiResu /// - `spender` - The account that is allowed to spend the tokens. /// - `value` - The number of tokens to increase the allowance by. #[inline] -pub fn increase_allowance(token: TokenId, spender: AccountId, value: Balance) -> PopApiResult<()> { +pub fn increase_allowance(token: TokenId, spender: AccountId, value: Balance) -> Result<()> { build_dispatch(INCREASE_ALLOWANCE) .input::<(TokenId, AccountId, Balance)>() - .output::, true>() + .output::, true>() .handle_error_code::() .call(&(token, spender, value)) } @@ -142,10 +137,10 @@ pub fn increase_allowance(token: TokenId, spender: AccountId, value: Balance) -> /// - `spender` - The account that is allowed to spend the tokens. /// - `value` - The number of tokens to decrease the allowance by. #[inline] -pub fn decrease_allowance(token: TokenId, spender: AccountId, value: Balance) -> PopApiResult<()> { +pub fn decrease_allowance(token: TokenId, spender: AccountId, value: Balance) -> Result<()> { build_dispatch(DECREASE_ALLOWANCE) .input::<(TokenId, AccountId, Balance)>() - .output::, true>() + .output::, true>() .handle_error_code::() .call(&(token, spender, value)) } @@ -157,10 +152,10 @@ pub fn decrease_allowance(token: TokenId, spender: AccountId, value: Balance) -> /// - `account` - The account to be credited with the created tokens. /// - `value` - The number of tokens to mint. #[inline] -pub fn mint(token: TokenId, account: AccountId, value: Balance) -> PopApiResult<()> { +pub fn mint(token: TokenId, account: AccountId, value: Balance) -> Result<()> { build_dispatch(MINT) .input::<(TokenId, AccountId, Balance)>() - .output::, true>() + .output::, true>() .handle_error_code::() .call(&(token, account, value)) } @@ -172,10 +167,10 @@ pub fn mint(token: TokenId, account: AccountId, value: Balance) -> PopApiResult< /// - `account` - The account from which the tokens will be destroyed. /// - `value` - The number of tokens to destroy. #[inline] -pub fn burn(token: TokenId, account: AccountId, value: Balance) -> PopApiResult<()> { +pub fn burn(token: TokenId, account: AccountId, value: Balance) -> Result<()> { build_dispatch(BURN) .input::<(TokenId, AccountId, Balance)>() - .output::, true>() + .output::, true>() .handle_error_code::() .call(&(token, account, value)) } @@ -189,10 +184,10 @@ pub mod metadata { /// # Parameters /// - `token` - The token. #[inline] - pub fn token_name(token: TokenId) -> PopApiResult> { + pub fn token_name(token: TokenId) -> Result> { build_read_state(TOKEN_NAME) .input::() - .output::>, true>() + .output::>, true>() .handle_error_code::() .call(&(token)) } @@ -202,10 +197,10 @@ pub mod metadata { /// # Parameters /// - `token` - The token. #[inline] - pub fn token_symbol(token: TokenId) -> PopApiResult> { + pub fn token_symbol(token: TokenId) -> Result> { build_read_state(TOKEN_SYMBOL) .input::() - .output::>, true>() + .output::>, true>() .handle_error_code::() .call(&(token)) } @@ -215,10 +210,10 @@ pub mod metadata { /// # Parameters /// - `token` - The token. #[inline] - pub fn token_decimals(token: TokenId) -> PopApiResult { + pub fn token_decimals(token: TokenId) -> Result { build_read_state(TOKEN_DECIMALS) .input::() - .output::, true>() + .output::, true>() .handle_error_code::() .call(&(token)) } @@ -235,10 +230,10 @@ pub mod management { /// - `admin` - The account that will administer the token. /// - `min_balance` - The minimum balance required for accounts holding this token. #[inline] - pub fn create(id: TokenId, admin: AccountId, min_balance: Balance) -> PopApiResult<()> { + pub fn create(id: TokenId, admin: AccountId, min_balance: Balance) -> Result<()> { build_dispatch(CREATE) .input::<(TokenId, AccountId, Balance)>() - .output::, true>() + .output::, true>() .handle_error_code::() .call(&(id, admin, min_balance)) } @@ -248,10 +243,10 @@ pub mod management { /// # Parameters /// - `token` - The token to be destroyed. #[inline] - pub fn start_destroy(token: TokenId) -> PopApiResult<()> { + pub fn start_destroy(token: TokenId) -> Result<()> { build_dispatch(START_DESTROY) .input::() - .output::, true>() + .output::, true>() .handle_error_code::() .call(&(token)) } @@ -269,10 +264,10 @@ pub mod management { name: Vec, symbol: Vec, decimals: u8, - ) -> PopApiResult<()> { + ) -> Result<()> { build_dispatch(SET_METADATA) .input::<(TokenId, Vec, Vec, u8)>() - .output::, true>() + .output::, true>() .handle_error_code::() .call(&(token, name, symbol, decimals)) } @@ -282,10 +277,10 @@ pub mod management { /// # Parameters /// - `token` - The token to update #[inline] - pub fn clear_metadata(token: TokenId) -> PopApiResult<()> { + pub fn clear_metadata(token: TokenId) -> Result<()> { build_dispatch(CLEAR_METADATA) .input::() - .output::, true>() + .output::, true>() .handle_error_code::() .call(&(token)) } @@ -295,10 +290,10 @@ pub mod management { /// # Parameters /// - `token` - The token. #[inline] - pub fn token_exists(token: TokenId) -> PopApiResult { + pub fn token_exists(token: TokenId) -> Result { build_read_state(TOKEN_EXISTS) .input::() - .output::, true>() + .output::, true>() .handle_error_code::() .call(&(token)) } From b52ad332b87a8b6d63257763a98c86ad3cf70503 Mon Sep 17 00:00:00 2001 From: chungquantin <56880684+chungquantin@users.noreply.github.com> Date: Thu, 19 Sep 2024 22:22:09 +0700 Subject: [PATCH 081/112] fix: update PSP22Metadata --- pop-api/src/v0/fungibles/traits.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pop-api/src/v0/fungibles/traits.rs b/pop-api/src/v0/fungibles/traits.rs index 74ef742a..01f25710 100644 --- a/pop-api/src/v0/fungibles/traits.rs +++ b/pop-api/src/v0/fungibles/traits.rs @@ -80,11 +80,11 @@ pub trait Psp22 { pub trait Psp22Metadata { /// Returns the token name. #[ink(message)] - fn token_name(&self) -> Option>; + fn token_name(&self) -> Option; /// Returns the token symbol. #[ink(message)] - fn token_symbol(&self) -> Option>; + fn token_symbol(&self) -> Option; /// Returns the token decimals. #[ink(message)] From 6b2f17a556605e46dd3cf3adaa9b7f23a38c4ceb Mon Sep 17 00:00:00 2001 From: chungquantin <56880684+chungquantin@users.noreply.github.com> Date: Thu, 19 Sep 2024 22:25:06 +0700 Subject: [PATCH 082/112] fix: add comment for Psp22 trait --- pop-api/src/v0/fungibles/traits.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/pop-api/src/v0/fungibles/traits.rs b/pop-api/src/v0/fungibles/traits.rs index 01f25710..0d9d2d29 100644 --- a/pop-api/src/v0/fungibles/traits.rs +++ b/pop-api/src/v0/fungibles/traits.rs @@ -1,5 +1,6 @@ use super::*; +/// The PSP22 trait. #[ink::trait_definition] pub trait Psp22 { /// Returns the total token supply. From 4a1bf3b184979efff2af0b26032d7fed0196dcab Mon Sep 17 00:00:00 2001 From: chungquantin <56880684+chungquantin@users.noreply.github.com> Date: Thu, 19 Sep 2024 23:13:42 +0700 Subject: [PATCH 083/112] fix: resolve comments --- pop-api/src/v0/fungibles/errors.rs | 4 ++-- pop-api/src/v0/fungibles/events.rs | 1 + pop-api/src/v0/fungibles/mod.rs | 10 ++++------ pop-api/src/v0/fungibles/traits.rs | 15 ++++++++------- 4 files changed, 15 insertions(+), 15 deletions(-) diff --git a/pop-api/src/v0/fungibles/errors.rs b/pop-api/src/v0/fungibles/errors.rs index 30d98285..e76c4bcc 100644 --- a/pop-api/src/v0/fungibles/errors.rs +++ b/pop-api/src/v0/fungibles/errors.rs @@ -1,4 +1,4 @@ -//! A set of errors for use in smart contracts to manage the returned errors. +//! A set of errors for use in smart contracts that interact with the fungibles api. This includes errors compliant to standards. use super::*; use ink::prelude::string::String; @@ -66,7 +66,7 @@ impl From for FungiblesError { } /// The PSP22 error. -/// TODO: Issue https://github.com/r0gue-io/pop-node/issues/298 +// TODO: Issue https://github.com/r0gue-io/pop-node/issues/298 #[derive(Debug, PartialEq, Eq)] #[ink::scale_derive(Encode, Decode, TypeInfo)] pub enum PSP22Error { diff --git a/pop-api/src/v0/fungibles/events.rs b/pop-api/src/v0/fungibles/events.rs index a018ac59..130ead65 100644 --- a/pop-api/src/v0/fungibles/events.rs +++ b/pop-api/src/v0/fungibles/events.rs @@ -7,6 +7,7 @@ //! track token operations. Be mindful of the costs associated with emitting events. //! //! For more details, refer to [ink! events](https://use.ink/basics/events). + use super::*; /// Event emitted when allowance by `owner` to `spender` changes. diff --git a/pop-api/src/v0/fungibles/mod.rs b/pop-api/src/v0/fungibles/mod.rs index fe6c685e..77f5f32c 100644 --- a/pop-api/src/v0/fungibles/mod.rs +++ b/pop-api/src/v0/fungibles/mod.rs @@ -23,8 +23,6 @@ pub mod errors; pub mod events; pub mod traits; -pub type PSP22Result = core::result::Result; - /// Returns the total token supply for a specified token. /// /// # Parameters @@ -300,7 +298,7 @@ pub mod management { } mod constants { - /// 1. PSP-22 Interface: + /// 1. PSP-22 pub(super) const TOTAL_SUPPLY: u8 = 0; pub(super) const BALANCE_OF: u8 = 1; pub(super) const ALLOWANCE: u8 = 2; @@ -310,19 +308,19 @@ mod constants { pub(super) const INCREASE_ALLOWANCE: u8 = 6; pub(super) const DECREASE_ALLOWANCE: u8 = 7; - /// 2. PSP-22 Metadata Interface: + /// 2. PSP-22 Metadata pub(super) const TOKEN_NAME: u8 = 8; pub(super) const TOKEN_SYMBOL: u8 = 9; pub(super) const TOKEN_DECIMALS: u8 = 10; - /// 3. Asset Management: + /// 3. Management pub(super) const CREATE: u8 = 11; pub(super) const START_DESTROY: u8 = 12; pub(super) const SET_METADATA: u8 = 16; pub(super) const CLEAR_METADATA: u8 = 17; pub(super) const TOKEN_EXISTS: u8 = 18; - /// 4. PSP-22 Mintable & Burnable interface: + /// 4. PSP-22 Mintable & Burnable pub(super) const MINT: u8 = 19; pub(super) const BURN: u8 = 20; } diff --git a/pop-api/src/v0/fungibles/traits.rs b/pop-api/src/v0/fungibles/traits.rs index 0d9d2d29..0220d363 100644 --- a/pop-api/src/v0/fungibles/traits.rs +++ b/pop-api/src/v0/fungibles/traits.rs @@ -1,3 +1,4 @@ +/// A set of traits that implement the PSP22 token standard. use super::*; /// The PSP22 trait. @@ -30,7 +31,7 @@ pub trait Psp22 { /// - `value` - The number of tokens to transfer. /// - `data` - Additional data in unspecified format. #[ink(message)] - fn transfer(&mut self, to: AccountId, value: Balance, data: Vec) -> PSP22Result<()>; + fn transfer(&mut self, to: AccountId, value: Balance, data: Vec) -> Result<(), PSP22Error>; /// Transfers `value` tokens on behalf of `from` to the account `to` /// with additional `data` in unspecified format. @@ -47,7 +48,7 @@ pub trait Psp22 { to: AccountId, value: Balance, data: Vec, - ) -> PSP22Result<()>; + ) -> Result<(), PSP22Error>; /// Approves `spender` to spend `value` amount of tokens on behalf of the caller. /// @@ -57,7 +58,7 @@ pub trait Psp22 { /// - `spender` - The account that is allowed to spend the tokens. /// - `value` - The number of tokens to approve. #[ink(message)] - fn approve(&mut self, spender: AccountId, value: Balance) -> PSP22Result<()>; + fn approve(&mut self, spender: AccountId, value: Balance) -> Result<(), PSP22Error>; /// Increases the allowance of `spender` by `value` amount of tokens. /// @@ -65,7 +66,7 @@ pub trait Psp22 { /// - `spender` - The account that is allowed to spend the tokens. /// - `value` - The number of tokens to increase the allowance by. #[ink(message)] - fn increase_allowance(&mut self, spender: AccountId, value: Balance) -> PSP22Result<()>; + fn increase_allowance(&mut self, spender: AccountId, value: Balance) -> Result<(), PSP22Error>; /// Decreases the allowance of `spender` by `value` amount of tokens. /// @@ -73,7 +74,7 @@ pub trait Psp22 { /// - `spender` - The account that is allowed to spend the tokens. /// - `value` - The number of tokens to decrease the allowance by. #[ink(message)] - fn decrease_allowance(&mut self, spender: AccountId, value: Balance) -> PSP22Result<()>; + fn decrease_allowance(&mut self, spender: AccountId, value: Balance) -> Result<(), PSP22Error>; } /// The PSP22 Metadata trait. @@ -101,7 +102,7 @@ pub trait Psp22Mintable { /// - `account` - The account to be credited with the created tokens. /// - `value` - The number of tokens to mint. #[ink(message)] - fn mint(&mut self, account: AccountId, amount: Balance) -> PSP22Result<()>; + fn mint(&mut self, account: AccountId, value: Balance) -> Result<(), PSP22Error>; } /// The PSP22 Burnable trait. @@ -113,5 +114,5 @@ pub trait Psp22Burnable { /// - `account` - The account from which the tokens will be destroyed. /// - `value` - The number of tokens to destroy. #[ink(message)] - fn burn(&mut self, account: AccountId, amount: Balance) -> PSP22Result<()>; + fn burn(&mut self, account: AccountId, value: Balance) -> Result<(), PSP22Error>; } From 699275cdcc0932dadfbcd0cf805a32082c91afcf Mon Sep 17 00:00:00 2001 From: chungquantin <56880684+chungquantin@users.noreply.github.com> Date: Thu, 19 Sep 2024 23:18:36 +0700 Subject: [PATCH 084/112] fix: api integration tests --- pop-api/src/v0/fungibles/traits.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/pop-api/src/v0/fungibles/traits.rs b/pop-api/src/v0/fungibles/traits.rs index 0220d363..9bcf2e8d 100644 --- a/pop-api/src/v0/fungibles/traits.rs +++ b/pop-api/src/v0/fungibles/traits.rs @@ -1,5 +1,8 @@ -/// A set of traits that implement the PSP22 token standard. +//! A set of traits that implement the PSP22 token standard. + use super::*; +use ink::prelude::string::String; +use std::result::Result; /// The PSP22 trait. #[ink::trait_definition] From 94ee34ec9e4c4fc2eb8b4c0e066190bd91458707 Mon Sep 17 00:00:00 2001 From: chungquantin <56880684+chungquantin@users.noreply.github.com> Date: Thu, 19 Sep 2024 23:49:26 +0700 Subject: [PATCH 085/112] fix: result type --- pop-api/src/v0/fungibles/traits.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pop-api/src/v0/fungibles/traits.rs b/pop-api/src/v0/fungibles/traits.rs index 9bcf2e8d..caa4c68d 100644 --- a/pop-api/src/v0/fungibles/traits.rs +++ b/pop-api/src/v0/fungibles/traits.rs @@ -1,8 +1,8 @@ //! A set of traits that implement the PSP22 token standard. use super::*; +use core::result::Result; use ink::prelude::string::String; -use std::result::Result; /// The PSP22 trait. #[ink::trait_definition] From 9bb3be84717e25359ed90afb1a98130a768adef6 Mon Sep 17 00:00:00 2001 From: chungquantin <56880684+chungquantin@users.noreply.github.com> Date: Thu, 19 Sep 2024 23:53:54 +0700 Subject: [PATCH 086/112] fix: comment --- pop-api/src/v0/fungibles/errors.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/pop-api/src/v0/fungibles/errors.rs b/pop-api/src/v0/fungibles/errors.rs index e76c4bcc..313107b4 100644 --- a/pop-api/src/v0/fungibles/errors.rs +++ b/pop-api/src/v0/fungibles/errors.rs @@ -1,4 +1,5 @@ //! A set of errors for use in smart contracts that interact with the fungibles api. This includes errors compliant to standards. + use super::*; use ink::prelude::string::String; From f03a5ae2a917503c79969b1701e9d368a43f4ea3 Mon Sep 17 00:00:00 2001 From: chungquantin <56880684+chungquantin@users.noreply.github.com> Date: Wed, 18 Sep 2024 12:48:36 +0800 Subject: [PATCH 087/112] feat: add interfaces for psp22 --- pop-api/src/v0/fungibles.rs | 87 +++++++++++++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) diff --git a/pop-api/src/v0/fungibles.rs b/pop-api/src/v0/fungibles.rs index 99c1261a..9ab53957 100644 --- a/pop-api/src/v0/fungibles.rs +++ b/pop-api/src/v0/fungibles.rs @@ -420,6 +420,93 @@ pub mod management { } } +pub mod interfaces { + use super::*; + + pub type Result = core::result::Result; + + #[ink::trait_definition] + pub trait Psp22Impl { + #[ink(message)] + fn total_supply(&self) -> Balance; + + #[ink(message)] + fn balance_of(&self, owner: AccountId) -> Balance; + + #[ink(message)] + fn allowance(&self, owner: AccountId, spender: AccountId) -> Balance; + + #[ink(message)] + fn transfer(&mut self, to: AccountId, value: Balance, data: Vec) -> Result<()>; + + #[ink(message)] + fn transfer_from( + &mut self, + from: AccountId, + to: AccountId, + value: Balance, + data: Vec, + ) -> Result<()>; + + #[ink(message)] + fn approve(&mut self, spender: AccountId, value: Balance) -> Result<()>; + + #[ink(message)] + fn increase_allowance(&mut self, spender: AccountId, value: Balance) -> Result<()>; + + #[ink(message)] + fn decrease_allowance(&mut self, spender: AccountId, value: Balance) -> Result<()>; + } + + #[ink::trait_definition] + pub trait Psp2ManagableImpl { + #[ink(message)] + fn create(&mut self, id: TokenId, admin: AccountId, min_balance: Balance) -> Result<()>; + + #[ink(message)] + fn start_destroy(&mut self, token: TokenId) -> Result<()>; + + #[ink(message)] + fn set_metadata( + &mut self, + token: TokenId, + name: Vec, + symbol: Vec, + decimals: u8, + ) -> Result<()>; + + #[ink(message)] + fn clear_metadata(&mut self, token: TokenId) -> Result<()>; + + #[ink(message)] + fn token_exists(&self, token: TokenId) -> Result; + } + + #[ink::trait_definition] + pub trait Psp22MetadataImpl { + #[ink(message)] + fn token_name(&self) -> Option>; + + #[ink(message)] + fn token_symbol(&self) -> Option>; + + #[ink(message)] + fn token_decimals(&self, id: TokenId) -> u8; + } + + #[ink::trait_definition] + pub trait Psp22MintableImpl { + #[ink(message)] + fn mint(&mut self, account: AccountId, amount: Balance) -> Result<()>; + } + + #[ink::trait_definition] + pub trait Psp22BurnableImpl { + #[ink(message)] + fn burn(&mut self, account: AccountId, amount: Balance) -> Result<()>; + } +} + /// Represents various errors related to fungible tokens. /// /// The `FungiblesError` provides a detailed and specific set of error types that can occur when From 1bbc3ed4e182d45e97f5e6eb99c42b3b9db2ee31 Mon Sep 17 00:00:00 2001 From: chungquantin <56880684+chungquantin@users.noreply.github.com> Date: Wed, 18 Sep 2024 16:03:39 +0800 Subject: [PATCH 088/112] chore: add comments --- pop-api/src/v0/fungibles.rs | 143 ++++++++++++++++++++++++++++++++++-- 1 file changed, 137 insertions(+), 6 deletions(-) diff --git a/pop-api/src/v0/fungibles.rs b/pop-api/src/v0/fungibles.rs index 9ab53957..096017c6 100644 --- a/pop-api/src/v0/fungibles.rs +++ b/pop-api/src/v0/fungibles.rs @@ -426,19 +426,78 @@ pub mod interfaces { pub type Result = core::result::Result; #[ink::trait_definition] - pub trait Psp22Impl { + pub trait Psp22 { + /// Returns the total token supply. #[ink(message)] fn total_supply(&self) -> Balance; + /// Returns the account balance for the specified `owner`. + /// + /// # Parameters + /// - `owner` - The account whose balance is being queried. + /// + /// Returns `0` if the account is non-existent. #[ink(message)] fn balance_of(&self, owner: AccountId) -> Balance; + /// Returns the allowance for a `spender` approved by an `owner`. + /// + /// # Parameters + /// - `owner` - The account that owns the tokens. + /// - `spender` - The account that is allowed to spend the tokens. + /// + /// Returns `0` if no allowance has been set. #[ink(message)] fn allowance(&self, owner: AccountId, spender: AccountId) -> Balance; + /// Transfers `value` amount of tokens from the caller's account to account `to` + /// with additional `data` in unspecified format. + /// + /// # Parameters + /// - `to` - The recipient account. + /// - `value` - The number of tokens to transfer. + /// - `data` - Additional data in unspecified format. + /// + /// # Events + /// On success a `Transfer` event is emitted. + /// + /// No-op if the caller and `to` is the same address or `value` is zero, returns success + /// and no events are emitted. + /// + /// # Errors + /// Reverts with `InsufficientBalance` if the `value` exceeds the caller's balance. #[ink(message)] fn transfer(&mut self, to: AccountId, value: Balance, data: Vec) -> Result<()>; + /// Transfers `value` tokens on behalf of `from` to the account `to` + /// with additional `data` in unspecified format. + /// + /// # Parameters + /// - `from` - The account from which the token balance will be withdrawn. + /// - `to` - The recipient account. + /// - `value` - The number of tokens to transfer. + /// + /// If `from` and the caller are different addresses, the caller must be allowed + /// by `from` to spend at least `value` tokens. + /// + /// # Events + /// On success a `Transfer` event is emitted. + /// + /// No-op if `from` and `to` is the same address or `value` is zero, returns success + /// and no events are emitted. + /// + /// If `from` and the caller are different addresses, a successful transfer results + /// in decreased allowance by `from` to the caller and an `Approval` event with + /// the new allowance amount is emitted. + /// + /// # Errors + /// Reverts with `InsufficientBalance` if the `value` exceeds the balance of the account `from`. + /// + /// Reverts with `InsufficientAllowance` if `from` and the caller are different addresses and + /// the `value` exceeds the allowance granted by `from` to the caller. + /// + /// If conditions for both `InsufficientBalance` and `InsufficientAllowance` errors are met, + /// reverts with `InsufficientAllowance`. #[ink(message)] fn transfer_from( &mut self, @@ -448,18 +507,57 @@ pub mod interfaces { data: Vec, ) -> Result<()>; + /// Approves `spender` to spend `value` amount of tokens on behalf of the caller. + /// + /// Successive calls of this method overwrite previous values. + /// + /// # Parameters + /// - `spender` - The account that is allowed to spend the tokens. + /// - `value` - The number of tokens to approve. + /// + /// # Events + /// An `Approval` event is emitted. + /// + /// No-op if the caller and `spender` is the same address, returns success and no events are emitted. #[ink(message)] fn approve(&mut self, spender: AccountId, value: Balance) -> Result<()>; + /// Increases the allowance of `spender` by `value` amount of tokens. + /// + /// # Parameters + /// - `spender` - The account that is allowed to spend the tokens. + /// - `value` - The number of tokens to increase the allowance by. + /// + /// # Events + /// An `Approval` event with the new allowance amount is emitted. + /// + /// No-op if the caller and `spender` is the same address or `value` is zero, returns success + /// and no events are emitted. #[ink(message)] fn increase_allowance(&mut self, spender: AccountId, value: Balance) -> Result<()>; + /// Decreases the allowance of `spender` by `value` amount of tokens. + /// + /// # Parameters + /// - `spender` - The account that is allowed to spend the tokens. + /// - `value` - The number of tokens to decrease the allowance by. + /// + /// # Events + /// An `Approval` event with the new allowance amount is emitted. + /// + /// No-op if the caller and `spender` is the same address or `value` is zero, returns success + /// and no events are emitted. + /// + /// # Errors + /// Reverts with `InsufficientAllowance` if `spender` and the caller are different addresses and + /// the `value` exceeds the allowance granted by the caller to `spender`. #[ink(message)] fn decrease_allowance(&mut self, spender: AccountId, value: Balance) -> Result<()>; } + /// The PSP22 Metadata trait. #[ink::trait_definition] - pub trait Psp2ManagableImpl { + pub trait Psp22Managable { #[ink(message)] fn create(&mut self, id: TokenId, admin: AccountId, min_balance: Balance) -> Result<()>; @@ -482,26 +580,59 @@ pub mod interfaces { fn token_exists(&self, token: TokenId) -> Result; } + /// The PSP22 Metadata trait. #[ink::trait_definition] - pub trait Psp22MetadataImpl { + pub trait Psp22Metadata { + /// Returns the token name. #[ink(message)] fn token_name(&self) -> Option>; + /// Returns the token symbol. #[ink(message)] fn token_symbol(&self) -> Option>; + /// Returns the token decimals. #[ink(message)] - fn token_decimals(&self, id: TokenId) -> u8; + fn token_decimals(&self) -> u8; } + /// The PSP22 Mintable trait. #[ink::trait_definition] - pub trait Psp22MintableImpl { + pub trait Psp22Mintable { + /// Creates `value` amount of tokens and assigns them to `account`, increasing the total supply. + /// + /// # Parameters + /// - `account` - The account to be credited with the created tokens. + /// - `value` - The number of tokens to mint. + /// + /// # Events + /// On success a `Transfer` event is emitted with `None` sender. + /// + /// No-op if `value` is zero, returns success and no events are emitted. + /// + /// # Errors + /// Reverts with `Custom (max supply exceeded)` if the total supply increased by + /// `value` exceeds maximal value of `u128` type. #[ink(message)] fn mint(&mut self, account: AccountId, amount: Balance) -> Result<()>; } + /// The PSP22 Burnable trait. #[ink::trait_definition] - pub trait Psp22BurnableImpl { + pub trait Psp22Burnable { + /// Destroys `value` amount of tokens from `account`, reducing the total supply. + /// + /// # Parameters + /// - `account` - The account from which the tokens will be destroyed. + /// - `value` - The number of tokens to destroy. + /// + /// # Events + /// On success a `Transfer` event is emitted with `None` recipient. + /// + /// No-op if `value` is zero, returns success and no events are emitted. + /// + /// # Errors + /// Reverts with `InsufficientBalance` if the `value` exceeds the caller's balance. #[ink(message)] fn burn(&mut self, account: AccountId, amount: Balance) -> Result<()>; } From e8d68a99e04a992f63e6831d885568bdd324375c Mon Sep 17 00:00:00 2001 From: chungquantin <56880684+chungquantin@users.noreply.github.com> Date: Wed, 18 Sep 2024 16:30:18 +0800 Subject: [PATCH 089/112] refactor: separate modules into files --- pop-api/src/v0/fungibles.rs | 806 ------------------------- pop-api/src/v0/fungibles/errors.rs | 63 ++ pop-api/src/v0/fungibles/events.rs | 82 +++ pop-api/src/v0/fungibles/interfaces.rs | 215 +++++++ pop-api/src/v0/fungibles/mod.rs | 343 +++++++++++ pop-api/src/v0/fungibles/tests.rs | 99 +++ 6 files changed, 802 insertions(+), 806 deletions(-) delete mode 100644 pop-api/src/v0/fungibles.rs create mode 100644 pop-api/src/v0/fungibles/errors.rs create mode 100644 pop-api/src/v0/fungibles/events.rs create mode 100644 pop-api/src/v0/fungibles/interfaces.rs create mode 100644 pop-api/src/v0/fungibles/mod.rs create mode 100644 pop-api/src/v0/fungibles/tests.rs diff --git a/pop-api/src/v0/fungibles.rs b/pop-api/src/v0/fungibles.rs deleted file mode 100644 index 096017c6..00000000 --- a/pop-api/src/v0/fungibles.rs +++ /dev/null @@ -1,806 +0,0 @@ -//! The `fungibles` module provides an API for interacting and managing fungible tokens. -//! -//! The API includes the following interfaces: -//! 1. PSP-22 -//! 2. PSP-22 Metadata -//! 3. Management -//! 4. PSP-22 Mintable & Burnable - -use constants::*; -use ink::prelude::vec::Vec; -pub use management::*; -pub use metadata::*; - -use crate::{ - constants::{ASSETS, BALANCES, FUNGIBLES}, - primitives::{AccountId, Balance, TokenId}, - ChainExtensionMethodApi, Result, StatusCode, -}; - -// Helper method to build a dispatch call. -// -// Parameters: -// - 'dispatchable': The index of the dispatchable function within the module. -fn build_dispatch(dispatchable: u8) -> ChainExtensionMethodApi { - crate::v0::build_dispatch(FUNGIBLES, dispatchable) -} - -// Helper method to build a call to read state. -// -// Parameters: -// - 'state_query': The index of the runtime state query. -fn build_read_state(state_query: u8) -> ChainExtensionMethodApi { - crate::v0::build_read_state(FUNGIBLES, state_query) -} - -mod constants { - /// 1. PSP-22 Interface: - pub(super) const TOTAL_SUPPLY: u8 = 0; - pub(super) const BALANCE_OF: u8 = 1; - pub(super) const ALLOWANCE: u8 = 2; - pub(super) const TRANSFER: u8 = 3; - pub(super) const TRANSFER_FROM: u8 = 4; - pub(super) const APPROVE: u8 = 5; - pub(super) const INCREASE_ALLOWANCE: u8 = 6; - pub(super) const DECREASE_ALLOWANCE: u8 = 7; - - /// 2. PSP-22 Metadata Interface: - pub(super) const TOKEN_NAME: u8 = 8; - pub(super) const TOKEN_SYMBOL: u8 = 9; - pub(super) const TOKEN_DECIMALS: u8 = 10; - - /// 3. Asset Management: - pub(super) const CREATE: u8 = 11; - pub(super) const START_DESTROY: u8 = 12; - pub(super) const SET_METADATA: u8 = 16; - pub(super) const CLEAR_METADATA: u8 = 17; - pub(super) const TOKEN_EXISTS: u8 = 18; - - /// 4. PSP-22 Mintable & Burnable interface: - pub(super) const MINT: u8 = 19; - pub(super) const BURN: u8 = 20; -} - -/// A set of events for use in smart contracts interacting with the fungibles API. -/// -/// The `Transfer` and `Approval` events conform to the PSP-22 standard. The other events -/// (`Create`, `StartDestroy`, `SetMetadata`, `ClearMetadata`) are provided for convenience. -/// -/// These events are not emitted by the API itself but can be used in your contracts to -/// track token operations. Be mindful of the costs associated with emitting events. -/// -/// For more details, refer to [ink! events](https://use.ink/basics/events). -pub mod events { - use super::*; - - /// Event emitted when allowance by `owner` to `spender` changes. - #[ink::event] - pub struct Approval { - /// The owner providing the allowance. - #[ink(topic)] - pub owner: AccountId, - /// The beneficiary of the allowance. - #[ink(topic)] - pub spender: AccountId, - /// The new allowance amount. - pub value: u128, - } - - /// Event emitted when transfer of tokens occurs. - #[ink::event] - pub struct Transfer { - /// The source of the transfer. `None` when minting. - #[ink(topic)] - pub from: Option, - /// The recipient of the transfer. `None` when burning. - #[ink(topic)] - pub to: Option, - /// The amount transferred (or minted/burned). - pub value: u128, - } - - /// Event emitted when a token is created. - #[ink::event] - pub struct Created { - /// The token identifier. - #[ink(topic)] - pub id: TokenId, - /// The creator of the token. - #[ink(topic)] - pub creator: AccountId, - /// The administrator of the token. - #[ink(topic)] - pub admin: AccountId, - } - - /// Event emitted when a token is in the process of being destroyed. - #[ink::event] - pub struct DestroyStarted { - /// The token. - #[ink(topic)] - pub token: TokenId, - } - - /// Event emitted when new metadata is set for a token. - #[ink::event] - pub struct MetadataSet { - /// The token. - #[ink(topic)] - pub token: TokenId, - /// The name of the token. - #[ink(topic)] - pub name: Vec, - /// The symbol of the token. - #[ink(topic)] - pub symbol: Vec, - /// The decimals of the token. - pub decimals: u8, - } - - /// Event emitted when metadata is cleared for a token. - #[ink::event] - pub struct MetadataCleared { - /// The token. - #[ink(topic)] - pub token: TokenId, - } -} - -/// Returns the total token supply for a specified token. -/// -/// # Parameters -/// - `token` - The token. -#[inline] -pub fn total_supply(token: TokenId) -> Result { - build_read_state(TOTAL_SUPPLY) - .input::() - .output::, true>() - .handle_error_code::() - .call(&(token)) -} - -/// Returns the account balance for a specified `token` and `owner`. Returns `0` if -/// the account is non-existent. -/// -/// # Parameters -/// - `token` - The token. -/// - `owner` - The account whose balance is being queried. -#[inline] -pub fn balance_of(token: TokenId, owner: AccountId) -> Result { - build_read_state(BALANCE_OF) - .input::<(TokenId, AccountId)>() - .output::, true>() - .handle_error_code::() - .call(&(token, owner)) -} - -/// Returns the allowance for a `spender` approved by an `owner`, for a specified `token`. Returns -/// `0` if no allowance has been set. -/// -/// # Parameters -/// - `token` - The token. -/// - `owner` - The account that owns the tokens. -/// - `spender` - The account that is allowed to spend the tokens. -#[inline] -pub fn allowance(token: TokenId, owner: AccountId, spender: AccountId) -> Result { - build_read_state(ALLOWANCE) - .input::<(TokenId, AccountId, AccountId)>() - .output::, true>() - .handle_error_code::() - .call(&(token, owner, spender)) -} - -/// Transfers `value` amount of tokens from the caller's account to account `to`. -/// -/// # Parameters -/// - `token` - The token to transfer. -/// - `to` - The recipient account. -/// - `value` - The number of tokens to transfer. -#[inline] -pub fn transfer(token: TokenId, to: AccountId, value: Balance) -> Result<()> { - build_dispatch(TRANSFER) - .input::<(TokenId, AccountId, Balance)>() - .output::, true>() - .handle_error_code::() - .call(&(token, to, value)) -} - -/// Transfers `value` amount tokens on behalf of `from` to account `to`. -/// -/// # Parameters -/// - `token` - The token to transfer. -/// - `from` - The account from which the token balance will be withdrawn. -/// - `to` - The recipient account. -/// - `value` - The number of tokens to transfer. -#[inline] -pub fn transfer_from(token: TokenId, from: AccountId, to: AccountId, value: Balance) -> Result<()> { - build_dispatch(TRANSFER_FROM) - .input::<(TokenId, AccountId, AccountId, Balance)>() - .output::, true>() - .handle_error_code::() - .call(&(token, from, to, value)) -} - -/// Approves `spender` to spend `value` amount of tokens on behalf of the caller. -/// -/// # Parameters -/// - `token` - The token to approve. -/// - `spender` - The account that is allowed to spend the tokens. -/// - `value` - The number of tokens to approve. -#[inline] -pub fn approve(token: TokenId, spender: AccountId, value: Balance) -> Result<()> { - build_dispatch(APPROVE) - .input::<(TokenId, AccountId, Balance)>() - .output::, true>() - .handle_error_code::() - .call(&(token, spender, value)) -} - -/// Increases the allowance of `spender` by `value` amount of tokens. -/// -/// # Parameters -/// - `token` - The token to have an allowance increased. -/// - `spender` - The account that is allowed to spend the tokens. -/// - `value` - The number of tokens to increase the allowance by. -#[inline] -pub fn increase_allowance(token: TokenId, spender: AccountId, value: Balance) -> Result<()> { - build_dispatch(INCREASE_ALLOWANCE) - .input::<(TokenId, AccountId, Balance)>() - .output::, true>() - .handle_error_code::() - .call(&(token, spender, value)) -} - -/// Decreases the allowance of `spender` by `value` amount of tokens. -/// -/// # Parameters -/// - `token` - The token to have an allowance decreased. -/// - `spender` - The account that is allowed to spend the tokens. -/// - `value` - The number of tokens to decrease the allowance by. -#[inline] -pub fn decrease_allowance(token: TokenId, spender: AccountId, value: Balance) -> Result<()> { - build_dispatch(DECREASE_ALLOWANCE) - .input::<(TokenId, AccountId, Balance)>() - .output::, true>() - .handle_error_code::() - .call(&(token, spender, value)) -} - -/// Creates `value` amount of tokens and assigns them to `account`, increasing the total supply. -/// -/// # Parameters -/// - `token` - The token to mint. -/// - `account` - The account to be credited with the created tokens. -/// - `value` - The number of tokens to mint. -#[inline] -pub fn mint(token: TokenId, account: AccountId, value: Balance) -> Result<()> { - build_dispatch(MINT) - .input::<(TokenId, AccountId, Balance)>() - .output::, true>() - .handle_error_code::() - .call(&(token, account, value)) -} - -/// Destroys `value` amount of tokens from `account`, reducing the total supply. -/// -/// # Parameters -/// - `token` - the token to burn. -/// - `account` - The account from which the tokens will be destroyed. -/// - `value` - The number of tokens to destroy. -#[inline] -pub fn burn(token: TokenId, account: AccountId, value: Balance) -> Result<()> { - build_dispatch(BURN) - .input::<(TokenId, AccountId, Balance)>() - .output::, true>() - .handle_error_code::() - .call(&(token, account, value)) -} - -/// The PSP-22 compliant interface for querying metadata. -pub mod metadata { - use super::*; - - /// Returns the name of the specified token. - /// - /// # Parameters - /// - `token` - The token. - #[inline] - pub fn token_name(token: TokenId) -> Result> { - build_read_state(TOKEN_NAME) - .input::() - .output::>, true>() - .handle_error_code::() - .call(&(token)) - } - - /// Returns the symbol for the specified token. - /// - /// # Parameters - /// - `token` - The token. - #[inline] - pub fn token_symbol(token: TokenId) -> Result> { - build_read_state(TOKEN_SYMBOL) - .input::() - .output::>, true>() - .handle_error_code::() - .call(&(token)) - } - - /// Returns the decimals for the specified token. - /// - /// # Parameters - /// - `token` - The token. - #[inline] - pub fn token_decimals(token: TokenId) -> Result { - build_read_state(TOKEN_DECIMALS) - .input::() - .output::, true>() - .handle_error_code::() - .call(&(token)) - } -} - -/// The interface for creating, managing and destroying fungible tokens. -pub mod management { - use super::*; - - /// Create a new token with a given identifier. - /// - /// # Parameters - /// - `id` - The identifier of the token. - /// - `admin` - The account that will administer the token. - /// - `min_balance` - The minimum balance required for accounts holding this token. - #[inline] - pub fn create(id: TokenId, admin: AccountId, min_balance: Balance) -> Result<()> { - build_dispatch(CREATE) - .input::<(TokenId, AccountId, Balance)>() - .output::, true>() - .handle_error_code::() - .call(&(id, admin, min_balance)) - } - - /// Start the process of destroying a token. - /// - /// # Parameters - /// - `token` - The token to be destroyed. - #[inline] - pub fn start_destroy(token: TokenId) -> Result<()> { - build_dispatch(START_DESTROY) - .input::() - .output::, true>() - .handle_error_code::() - .call(&(token)) - } - - /// Set the metadata for a token. - /// - /// # Parameters - /// - `token`: The token to update. - /// - `name`: The user friendly name of this token. - /// - `symbol`: The exchange symbol for this token. - /// - `decimals`: The number of decimals this token uses to represent one unit. - #[inline] - pub fn set_metadata( - token: TokenId, - name: Vec, - symbol: Vec, - decimals: u8, - ) -> Result<()> { - build_dispatch(SET_METADATA) - .input::<(TokenId, Vec, Vec, u8)>() - .output::, true>() - .handle_error_code::() - .call(&(token, name, symbol, decimals)) - } - - /// Clear the metadata for a token. - /// - /// # Parameters - /// - `token` - The token to update - #[inline] - pub fn clear_metadata(token: TokenId) -> Result<()> { - build_dispatch(CLEAR_METADATA) - .input::() - .output::, true>() - .handle_error_code::() - .call(&(token)) - } - - /// Checks if a specified token exists. - /// - /// # Parameters - /// - `token` - The token. - #[inline] - pub fn token_exists(token: TokenId) -> Result { - build_read_state(TOKEN_EXISTS) - .input::() - .output::, true>() - .handle_error_code::() - .call(&(token)) - } -} - -pub mod interfaces { - use super::*; - - pub type Result = core::result::Result; - - #[ink::trait_definition] - pub trait Psp22 { - /// Returns the total token supply. - #[ink(message)] - fn total_supply(&self) -> Balance; - - /// Returns the account balance for the specified `owner`. - /// - /// # Parameters - /// - `owner` - The account whose balance is being queried. - /// - /// Returns `0` if the account is non-existent. - #[ink(message)] - fn balance_of(&self, owner: AccountId) -> Balance; - - /// Returns the allowance for a `spender` approved by an `owner`. - /// - /// # Parameters - /// - `owner` - The account that owns the tokens. - /// - `spender` - The account that is allowed to spend the tokens. - /// - /// Returns `0` if no allowance has been set. - #[ink(message)] - fn allowance(&self, owner: AccountId, spender: AccountId) -> Balance; - - /// Transfers `value` amount of tokens from the caller's account to account `to` - /// with additional `data` in unspecified format. - /// - /// # Parameters - /// - `to` - The recipient account. - /// - `value` - The number of tokens to transfer. - /// - `data` - Additional data in unspecified format. - /// - /// # Events - /// On success a `Transfer` event is emitted. - /// - /// No-op if the caller and `to` is the same address or `value` is zero, returns success - /// and no events are emitted. - /// - /// # Errors - /// Reverts with `InsufficientBalance` if the `value` exceeds the caller's balance. - #[ink(message)] - fn transfer(&mut self, to: AccountId, value: Balance, data: Vec) -> Result<()>; - - /// Transfers `value` tokens on behalf of `from` to the account `to` - /// with additional `data` in unspecified format. - /// - /// # Parameters - /// - `from` - The account from which the token balance will be withdrawn. - /// - `to` - The recipient account. - /// - `value` - The number of tokens to transfer. - /// - /// If `from` and the caller are different addresses, the caller must be allowed - /// by `from` to spend at least `value` tokens. - /// - /// # Events - /// On success a `Transfer` event is emitted. - /// - /// No-op if `from` and `to` is the same address or `value` is zero, returns success - /// and no events are emitted. - /// - /// If `from` and the caller are different addresses, a successful transfer results - /// in decreased allowance by `from` to the caller and an `Approval` event with - /// the new allowance amount is emitted. - /// - /// # Errors - /// Reverts with `InsufficientBalance` if the `value` exceeds the balance of the account `from`. - /// - /// Reverts with `InsufficientAllowance` if `from` and the caller are different addresses and - /// the `value` exceeds the allowance granted by `from` to the caller. - /// - /// If conditions for both `InsufficientBalance` and `InsufficientAllowance` errors are met, - /// reverts with `InsufficientAllowance`. - #[ink(message)] - fn transfer_from( - &mut self, - from: AccountId, - to: AccountId, - value: Balance, - data: Vec, - ) -> Result<()>; - - /// Approves `spender` to spend `value` amount of tokens on behalf of the caller. - /// - /// Successive calls of this method overwrite previous values. - /// - /// # Parameters - /// - `spender` - The account that is allowed to spend the tokens. - /// - `value` - The number of tokens to approve. - /// - /// # Events - /// An `Approval` event is emitted. - /// - /// No-op if the caller and `spender` is the same address, returns success and no events are emitted. - #[ink(message)] - fn approve(&mut self, spender: AccountId, value: Balance) -> Result<()>; - - /// Increases the allowance of `spender` by `value` amount of tokens. - /// - /// # Parameters - /// - `spender` - The account that is allowed to spend the tokens. - /// - `value` - The number of tokens to increase the allowance by. - /// - /// # Events - /// An `Approval` event with the new allowance amount is emitted. - /// - /// No-op if the caller and `spender` is the same address or `value` is zero, returns success - /// and no events are emitted. - #[ink(message)] - fn increase_allowance(&mut self, spender: AccountId, value: Balance) -> Result<()>; - - /// Decreases the allowance of `spender` by `value` amount of tokens. - /// - /// # Parameters - /// - `spender` - The account that is allowed to spend the tokens. - /// - `value` - The number of tokens to decrease the allowance by. - /// - /// # Events - /// An `Approval` event with the new allowance amount is emitted. - /// - /// No-op if the caller and `spender` is the same address or `value` is zero, returns success - /// and no events are emitted. - /// - /// # Errors - /// Reverts with `InsufficientAllowance` if `spender` and the caller are different addresses and - /// the `value` exceeds the allowance granted by the caller to `spender`. - #[ink(message)] - fn decrease_allowance(&mut self, spender: AccountId, value: Balance) -> Result<()>; - } - - /// The PSP22 Metadata trait. - #[ink::trait_definition] - pub trait Psp22Managable { - #[ink(message)] - fn create(&mut self, id: TokenId, admin: AccountId, min_balance: Balance) -> Result<()>; - - #[ink(message)] - fn start_destroy(&mut self, token: TokenId) -> Result<()>; - - #[ink(message)] - fn set_metadata( - &mut self, - token: TokenId, - name: Vec, - symbol: Vec, - decimals: u8, - ) -> Result<()>; - - #[ink(message)] - fn clear_metadata(&mut self, token: TokenId) -> Result<()>; - - #[ink(message)] - fn token_exists(&self, token: TokenId) -> Result; - } - - /// The PSP22 Metadata trait. - #[ink::trait_definition] - pub trait Psp22Metadata { - /// Returns the token name. - #[ink(message)] - fn token_name(&self) -> Option>; - - /// Returns the token symbol. - #[ink(message)] - fn token_symbol(&self) -> Option>; - - /// Returns the token decimals. - #[ink(message)] - fn token_decimals(&self) -> u8; - } - - /// The PSP22 Mintable trait. - #[ink::trait_definition] - pub trait Psp22Mintable { - /// Creates `value` amount of tokens and assigns them to `account`, increasing the total supply. - /// - /// # Parameters - /// - `account` - The account to be credited with the created tokens. - /// - `value` - The number of tokens to mint. - /// - /// # Events - /// On success a `Transfer` event is emitted with `None` sender. - /// - /// No-op if `value` is zero, returns success and no events are emitted. - /// - /// # Errors - /// Reverts with `Custom (max supply exceeded)` if the total supply increased by - /// `value` exceeds maximal value of `u128` type. - #[ink(message)] - fn mint(&mut self, account: AccountId, amount: Balance) -> Result<()>; - } - - /// The PSP22 Burnable trait. - #[ink::trait_definition] - pub trait Psp22Burnable { - /// Destroys `value` amount of tokens from `account`, reducing the total supply. - /// - /// # Parameters - /// - `account` - The account from which the tokens will be destroyed. - /// - `value` - The number of tokens to destroy. - /// - /// # Events - /// On success a `Transfer` event is emitted with `None` recipient. - /// - /// No-op if `value` is zero, returns success and no events are emitted. - /// - /// # Errors - /// Reverts with `InsufficientBalance` if the `value` exceeds the caller's balance. - #[ink(message)] - fn burn(&mut self, account: AccountId, amount: Balance) -> Result<()>; - } -} - -/// Represents various errors related to fungible tokens. -/// -/// The `FungiblesError` provides a detailed and specific set of error types that can occur when -/// interacting with fungible tokens. Each variant signifies a particular error -/// condition, facilitating precise error handling and debugging. -/// -/// It is designed to be lightweight, including only the essential errors relevant to fungible token -/// operations. The `Other` variant serves as a catch-all for any unexpected errors. For more -/// detailed debugging, the `Other` variant can be converted into the richer `Error` type defined in -/// the primitives crate. -#[derive(Debug, PartialEq, Eq)] -#[ink::scale_derive(Encode, Decode, TypeInfo)] -pub enum FungiblesError { - /// An unspecified or unknown error occurred. - Other(StatusCode), - /// The token is not live; either frozen or being destroyed. - NotLive, - /// Not enough allowance to fulfill a request is available. - InsufficientAllowance, - /// Not enough balance to fulfill a request is available. - InsufficientBalance, - /// The token ID is already taken. - InUse, - /// Minimum balance should be non-zero. - MinBalanceZero, - /// The account to alter does not exist. - NoAccount, - /// The signing account has no permission to do the operation. - NoPermission, - /// The given token ID is unknown. - Unknown, - /// No balance for creation of tokens or fees. - // TODO: Originally `pallet_balances::Error::InsufficientBalance` but collides with the - // `InsufficientBalance` error that is used for `pallet_assets::Error::BalanceLow` to adhere - // to the standard. This deserves a second look. - NoBalance, -} - -impl From for FungiblesError { - /// Converts a `StatusCode` to a `FungiblesError`. - /// - /// This conversion maps a `StatusCode`, returned by the runtime, to a more descriptive - /// `FungiblesError`. This provides better context and understanding of the error, allowing - /// developers to handle the most important errors effectively. - fn from(value: StatusCode) -> Self { - let encoded = value.0.to_le_bytes(); - match encoded { - // Balances. - [_, BALANCES, 2, _] => FungiblesError::NoBalance, - // Assets. - [_, ASSETS, 0, _] => FungiblesError::NoAccount, - [_, ASSETS, 1, _] => FungiblesError::NoPermission, - [_, ASSETS, 2, _] => FungiblesError::Unknown, - [_, ASSETS, 3, _] => FungiblesError::InUse, - [_, ASSETS, 5, _] => FungiblesError::MinBalanceZero, - [_, ASSETS, 7, _] => FungiblesError::InsufficientAllowance, - [_, ASSETS, 10, _] => FungiblesError::NotLive, - _ => FungiblesError::Other(value), - } - } -} - -#[cfg(test)] -mod tests { - use ink::scale::{Decode, Encode}; - - use super::FungiblesError; - use crate::{ - constants::{ASSETS, BALANCES}, - primitives::{ - ArithmeticError::*, - Error::{self, *}, - TokenError::*, - TransactionalError::*, - }, - StatusCode, - }; - - fn error_into_status_code(error: Error) -> StatusCode { - let mut encoded_error = error.encode(); - encoded_error.resize(4, 0); - let value = u32::from_le_bytes( - encoded_error.try_into().expect("qed, resized to 4 bytes line above"), - ); - value.into() - } - - fn into_fungibles_error(error: Error) -> FungiblesError { - let status_code: StatusCode = error_into_status_code(error); - status_code.into() - } - - // If we ever want to change the conversion from bytes to `u32`. - #[test] - fn status_code_vs_encoded() { - assert_eq!(u32::decode(&mut &[3u8, 10, 2, 0][..]).unwrap(), 133635u32); - assert_eq!(u32::decode(&mut &[3u8, 52, 0, 0][..]).unwrap(), 13315u32); - assert_eq!(u32::decode(&mut &[3u8, 52, 1, 0][..]).unwrap(), 78851u32); - assert_eq!(u32::decode(&mut &[3u8, 52, 2, 0][..]).unwrap(), 144387u32); - assert_eq!(u32::decode(&mut &[3u8, 52, 3, 0][..]).unwrap(), 209923u32); - assert_eq!(u32::decode(&mut &[3u8, 52, 5, 0][..]).unwrap(), 340995u32); - assert_eq!(u32::decode(&mut &[3u8, 52, 7, 0][..]).unwrap(), 472067u32); - assert_eq!(u32::decode(&mut &[3u8, 52, 10, 0][..]).unwrap(), 668675u32); - } - - #[test] - fn converting_status_code_into_fungibles_error_works() { - let other_errors = vec![ - Other, - CannotLookup, - BadOrigin, - // `ModuleError` other than assets module. - Module { index: 2, error: [5, 0] }, - ConsumerRemaining, - NoProviders, - TooManyConsumers, - Token(OnlyProvider), - Arithmetic(Overflow), - Transactional(NoLayer), - Exhausted, - Corruption, - Unavailable, - RootNotAllowed, - Unknown { dispatch_error_index: 5, error_index: 5, error: 1 }, - DecodingFailed, - ]; - for error in other_errors { - let status_code: StatusCode = error_into_status_code(error); - let fungibles_error: FungiblesError = status_code.into(); - assert_eq!(fungibles_error, FungiblesError::Other(status_code)) - } - - assert_eq!( - into_fungibles_error(Module { index: BALANCES, error: [2, 0] }), - FungiblesError::NoBalance - ); - assert_eq!( - into_fungibles_error(Module { index: ASSETS, error: [0, 0] }), - FungiblesError::NoAccount - ); - assert_eq!( - into_fungibles_error(Module { index: ASSETS, error: [1, 0] }), - FungiblesError::NoPermission - ); - assert_eq!( - into_fungibles_error(Module { index: ASSETS, error: [2, 0] }), - FungiblesError::Unknown - ); - assert_eq!( - into_fungibles_error(Module { index: ASSETS, error: [3, 0] }), - FungiblesError::InUse - ); - assert_eq!( - into_fungibles_error(Module { index: ASSETS, error: [5, 0] }), - FungiblesError::MinBalanceZero - ); - assert_eq!( - into_fungibles_error(Module { index: ASSETS, error: [7, 0] }), - FungiblesError::InsufficientAllowance - ); - assert_eq!( - into_fungibles_error(Module { index: ASSETS, error: [10, 0] }), - FungiblesError::NotLive - ); - } -} diff --git a/pop-api/src/v0/fungibles/errors.rs b/pop-api/src/v0/fungibles/errors.rs new file mode 100644 index 00000000..b29127e5 --- /dev/null +++ b/pop-api/src/v0/fungibles/errors.rs @@ -0,0 +1,63 @@ +use super::*; + +/// Represents various errors related to fungible tokens. +/// +/// The `FungiblesError` provides a detailed and specific set of error types that can occur when +/// interacting with fungible tokens. Each variant signifies a particular error +/// condition, facilitating precise error handling and debugging. +/// +/// It is designed to be lightweight, including only the essential errors relevant to fungible token +/// operations. The `Other` variant serves as a catch-all for any unexpected errors. For more +/// detailed debugging, the `Other` variant can be converted into the richer `Error` type defined in +/// the primitives crate. +#[derive(Debug, PartialEq, Eq)] +#[ink::scale_derive(Encode, Decode, TypeInfo)] +pub enum FungiblesError { + /// An unspecified or unknown error occurred. + Other(StatusCode), + /// The token is not live; either frozen or being destroyed. + NotLive, + /// Not enough allowance to fulfill a request is available. + InsufficientAllowance, + /// Not enough balance to fulfill a request is available. + InsufficientBalance, + /// The token ID is already taken. + InUse, + /// Minimum balance should be non-zero. + MinBalanceZero, + /// The account to alter does not exist. + NoAccount, + /// The signing account has no permission to do the operation. + NoPermission, + /// The given token ID is unknown. + Unknown, + /// No balance for creation of tokens or fees. + // TODO: Originally `pallet_balances::Error::InsufficientBalance` but collides with the + // `InsufficientBalance` error that is used for `pallet_assets::Error::BalanceLow` to adhere + // to the standard. This deserves a second look. + NoBalance, +} + +impl From for FungiblesError { + /// Converts a `StatusCode` to a `FungiblesError`. + /// + /// This conversion maps a `StatusCode`, returned by the runtime, to a more descriptive + /// `FungiblesError`. This provides better context and understanding of the error, allowing + /// developers to handle the most important errors effectively. + fn from(value: StatusCode) -> Self { + let encoded = value.0.to_le_bytes(); + match encoded { + // Balances. + [_, BALANCES, 2, _] => FungiblesError::NoBalance, + // Assets. + [_, ASSETS, 0, _] => FungiblesError::NoAccount, + [_, ASSETS, 1, _] => FungiblesError::NoPermission, + [_, ASSETS, 2, _] => FungiblesError::Unknown, + [_, ASSETS, 3, _] => FungiblesError::InUse, + [_, ASSETS, 5, _] => FungiblesError::MinBalanceZero, + [_, ASSETS, 7, _] => FungiblesError::InsufficientAllowance, + [_, ASSETS, 10, _] => FungiblesError::NotLive, + _ => FungiblesError::Other(value), + } + } +} diff --git a/pop-api/src/v0/fungibles/events.rs b/pop-api/src/v0/fungibles/events.rs new file mode 100644 index 00000000..b0639e10 --- /dev/null +++ b/pop-api/src/v0/fungibles/events.rs @@ -0,0 +1,82 @@ +/// A set of events for use in smart contracts interacting with the fungibles API. +/// +/// The `Transfer` and `Approval` events conform to the PSP-22 standard. The other events +/// (`Create`, `StartDestroy`, `SetMetadata`, `ClearMetadata`) are provided for convenience. +/// +/// These events are not emitted by the API itself but can be used in your contracts to +/// track token operations. Be mindful of the costs associated with emitting events. +/// +/// For more details, refer to [ink! events](https://use.ink/basics/events). +use super::*; + +/// Event emitted when allowance by `owner` to `spender` changes. +#[ink::event] +pub struct Approval { + /// The owner providing the allowance. + #[ink(topic)] + pub owner: AccountId, + /// The beneficiary of the allowance. + #[ink(topic)] + pub spender: AccountId, + /// The new allowance amount. + pub value: u128, +} + +/// Event emitted when transfer of tokens occurs. +#[ink::event] +pub struct Transfer { + /// The source of the transfer. `None` when minting. + #[ink(topic)] + pub from: Option, + /// The recipient of the transfer. `None` when burning. + #[ink(topic)] + pub to: Option, + /// The amount transferred (or minted/burned). + pub value: u128, +} + +/// Event emitted when a token is created. +#[ink::event] +pub struct Created { + /// The token identifier. + #[ink(topic)] + pub id: TokenId, + /// The creator of the token. + #[ink(topic)] + pub creator: AccountId, + /// The administrator of the token. + #[ink(topic)] + pub admin: AccountId, +} + +/// Event emitted when a token is in the process of being destroyed. +#[ink::event] +pub struct DestroyStarted { + /// The token. + #[ink(topic)] + pub token: TokenId, +} + +/// Event emitted when new metadata is set for a token. +#[ink::event] +pub struct MetadataSet { + /// The token. + #[ink(topic)] + pub token: TokenId, + /// The name of the token. + #[ink(topic)] + pub name: Vec, + /// The symbol of the token. + #[ink(topic)] + pub symbol: Vec, + /// The decimals of the token. + pub decimals: u8, +} + +/// Event emitted when metadata is cleared for a token. +#[ink::event] +pub struct MetadataCleared { + /// The token. + #[ink(topic)] + pub token: TokenId, +} diff --git a/pop-api/src/v0/fungibles/interfaces.rs b/pop-api/src/v0/fungibles/interfaces.rs new file mode 100644 index 00000000..6023ce37 --- /dev/null +++ b/pop-api/src/v0/fungibles/interfaces.rs @@ -0,0 +1,215 @@ +use super::*; + +pub type Result = core::result::Result; + +#[ink::trait_definition] +pub trait Psp22 { + /// Returns the total token supply. + #[ink(message)] + fn total_supply(&self) -> Balance; + + /// Returns the account balance for the specified `owner`. + /// + /// # Parameters + /// - `owner` - The account whose balance is being queried. + /// + /// Returns `0` if the account is non-existent. + #[ink(message)] + fn balance_of(&self, owner: AccountId) -> Balance; + + /// Returns the allowance for a `spender` approved by an `owner`. + /// + /// # Parameters + /// - `owner` - The account that owns the tokens. + /// - `spender` - The account that is allowed to spend the tokens. + /// + /// Returns `0` if no allowance has been set. + #[ink(message)] + fn allowance(&self, owner: AccountId, spender: AccountId) -> Balance; + + /// Transfers `value` amount of tokens from the caller's account to account `to` + /// with additional `data` in unspecified format. + /// + /// # Parameters + /// - `to` - The recipient account. + /// - `value` - The number of tokens to transfer. + /// - `data` - Additional data in unspecified format. + /// + /// # Events + /// On success a `Transfer` event is emitted. + /// + /// No-op if the caller and `to` is the same address or `value` is zero, returns success + /// and no events are emitted. + /// + /// # Errors + /// Reverts with `InsufficientBalance` if the `value` exceeds the caller's balance. + #[ink(message)] + fn transfer(&mut self, to: AccountId, value: Balance, data: Vec) -> Result<()>; + + /// Transfers `value` tokens on behalf of `from` to the account `to` + /// with additional `data` in unspecified format. + /// + /// # Parameters + /// - `from` - The account from which the token balance will be withdrawn. + /// - `to` - The recipient account. + /// - `value` - The number of tokens to transfer. + /// + /// If `from` and the caller are different addresses, the caller must be allowed + /// by `from` to spend at least `value` tokens. + /// + /// # Events + /// On success a `Transfer` event is emitted. + /// + /// No-op if `from` and `to` is the same address or `value` is zero, returns success + /// and no events are emitted. + /// + /// If `from` and the caller are different addresses, a successful transfer results + /// in decreased allowance by `from` to the caller and an `Approval` event with + /// the new allowance amount is emitted. + /// + /// # Errors + /// Reverts with `InsufficientBalance` if the `value` exceeds the balance of the account `from`. + /// + /// Reverts with `InsufficientAllowance` if `from` and the caller are different addresses and + /// the `value` exceeds the allowance granted by `from` to the caller. + /// + /// If conditions for both `InsufficientBalance` and `InsufficientAllowance` errors are met, + /// reverts with `InsufficientAllowance`. + #[ink(message)] + fn transfer_from( + &mut self, + from: AccountId, + to: AccountId, + value: Balance, + data: Vec, + ) -> Result<()>; + + /// Approves `spender` to spend `value` amount of tokens on behalf of the caller. + /// + /// Successive calls of this method overwrite previous values. + /// + /// # Parameters + /// - `spender` - The account that is allowed to spend the tokens. + /// - `value` - The number of tokens to approve. + /// + /// # Events + /// An `Approval` event is emitted. + /// + /// No-op if the caller and `spender` is the same address, returns success and no events are emitted. + #[ink(message)] + fn approve(&mut self, spender: AccountId, value: Balance) -> Result<()>; + + /// Increases the allowance of `spender` by `value` amount of tokens. + /// + /// # Parameters + /// - `spender` - The account that is allowed to spend the tokens. + /// - `value` - The number of tokens to increase the allowance by. + /// + /// # Events + /// An `Approval` event with the new allowance amount is emitted. + /// + /// No-op if the caller and `spender` is the same address or `value` is zero, returns success + /// and no events are emitted. + #[ink(message)] + fn increase_allowance(&mut self, spender: AccountId, value: Balance) -> Result<()>; + + /// Decreases the allowance of `spender` by `value` amount of tokens. + /// + /// # Parameters + /// - `spender` - The account that is allowed to spend the tokens. + /// - `value` - The number of tokens to decrease the allowance by. + /// + /// # Events + /// An `Approval` event with the new allowance amount is emitted. + /// + /// No-op if the caller and `spender` is the same address or `value` is zero, returns success + /// and no events are emitted. + /// + /// # Errors + /// Reverts with `InsufficientAllowance` if `spender` and the caller are different addresses and + /// the `value` exceeds the allowance granted by the caller to `spender`. + #[ink(message)] + fn decrease_allowance(&mut self, spender: AccountId, value: Balance) -> Result<()>; +} + +/// The PSP22 Metadata trait. +#[ink::trait_definition] +pub trait Psp22Managable { + #[ink(message)] + fn create(&mut self, id: TokenId, admin: AccountId, min_balance: Balance) -> Result<()>; + + #[ink(message)] + fn start_destroy(&mut self, token: TokenId) -> Result<()>; + + #[ink(message)] + fn set_metadata( + &mut self, + token: TokenId, + name: Vec, + symbol: Vec, + decimals: u8, + ) -> Result<()>; + + #[ink(message)] + fn clear_metadata(&mut self, token: TokenId) -> Result<()>; + + #[ink(message)] + fn token_exists(&self, token: TokenId) -> Result; +} + +/// The PSP22 Metadata trait. +#[ink::trait_definition] +pub trait Psp22Metadata { + /// Returns the token name. + #[ink(message)] + fn token_name(&self) -> Option>; + + /// Returns the token symbol. + #[ink(message)] + fn token_symbol(&self) -> Option>; + + /// Returns the token decimals. + #[ink(message)] + fn token_decimals(&self) -> u8; +} + +/// The PSP22 Mintable trait. +#[ink::trait_definition] +pub trait Psp22Mintable { + /// Creates `value` amount of tokens and assigns them to `account`, increasing the total supply. + /// + /// # Parameters + /// - `account` - The account to be credited with the created tokens. + /// - `value` - The number of tokens to mint. + /// + /// # Events + /// On success a `Transfer` event is emitted with `None` sender. + /// + /// No-op if `value` is zero, returns success and no events are emitted. + /// + /// # Errors + /// Reverts with `Custom (max supply exceeded)` if the total supply increased by + /// `value` exceeds maximal value of `u128` type. + #[ink(message)] + fn mint(&mut self, account: AccountId, amount: Balance) -> Result<()>; +} + +/// The PSP22 Burnable trait. +#[ink::trait_definition] +pub trait Psp22Burnable { + /// Destroys `value` amount of tokens from `account`, reducing the total supply. + /// + /// # Parameters + /// - `account` - The account from which the tokens will be destroyed. + /// - `value` - The number of tokens to destroy. + /// + /// # Events + /// On success a `Transfer` event is emitted with `None` recipient. + /// + /// No-op if `value` is zero, returns success and no events are emitted. + /// + /// # Errors + /// Reverts with `InsufficientBalance` if the `value` exceeds the caller's balance. + #[ink(message)] + fn burn(&mut self, account: AccountId, amount: Balance) -> Result<()>; +} diff --git a/pop-api/src/v0/fungibles/mod.rs b/pop-api/src/v0/fungibles/mod.rs new file mode 100644 index 00000000..e8d4e81d --- /dev/null +++ b/pop-api/src/v0/fungibles/mod.rs @@ -0,0 +1,343 @@ +//! The `fungibles` module provides an API for interacting and managing fungible tokens. +//! +//! The API includes the following interfaces: +//! 1. PSP-22 +//! 2. PSP-22 Metadata +//! 3. Management +//! 4. PSP-22 Mintable & Burnable +pub mod errors; +pub mod events; +pub mod interfaces; +#[cfg(test)] +mod tests; + +use crate::{ + constants::{ASSETS, BALANCES, FUNGIBLES}, + primitives::{AccountId, Balance, TokenId}, + ChainExtensionMethodApi, StatusCode, +}; +use constants::*; +pub use errors::*; +pub use events::*; +use ink::prelude::vec::Vec; +pub use interfaces::*; +pub use management::*; +pub use metadata::*; + +// Helper method to build a dispatch call. +// +// Parameters: +// - 'dispatchable': The index of the dispatchable function within the module. +fn build_dispatch(dispatchable: u8) -> ChainExtensionMethodApi { + crate::v0::build_dispatch(FUNGIBLES, dispatchable) +} + +// Helper method to build a call to read state. +// +// Parameters: +// - 'state_query': The index of the runtime state query. +fn build_read_state(state_query: u8) -> ChainExtensionMethodApi { + crate::v0::build_read_state(FUNGIBLES, state_query) +} + +mod constants { + /// 1. PSP-22 Interface: + pub(super) const TOTAL_SUPPLY: u8 = 0; + pub(super) const BALANCE_OF: u8 = 1; + pub(super) const ALLOWANCE: u8 = 2; + pub(super) const TRANSFER: u8 = 3; + pub(super) const TRANSFER_FROM: u8 = 4; + pub(super) const APPROVE: u8 = 5; + pub(super) const INCREASE_ALLOWANCE: u8 = 6; + pub(super) const DECREASE_ALLOWANCE: u8 = 7; + + /// 2. PSP-22 Metadata Interface: + pub(super) const TOKEN_NAME: u8 = 8; + pub(super) const TOKEN_SYMBOL: u8 = 9; + pub(super) const TOKEN_DECIMALS: u8 = 10; + + /// 3. Asset Management: + pub(super) const CREATE: u8 = 11; + pub(super) const START_DESTROY: u8 = 12; + pub(super) const SET_METADATA: u8 = 16; + pub(super) const CLEAR_METADATA: u8 = 17; + pub(super) const TOKEN_EXISTS: u8 = 18; + + /// 4. PSP-22 Mintable & Burnable interface: + pub(super) const MINT: u8 = 19; + pub(super) const BURN: u8 = 20; +} + +/// Returns the total token supply for a specified token. +/// +/// # Parameters +/// - `token` - The token. +#[inline] +pub fn total_supply(token: TokenId) -> Result { + build_read_state(TOTAL_SUPPLY) + .input::() + .output::, true>() + .handle_error_code::() + .call(&(token)) +} + +/// Returns the account balance for a specified `token` and `owner`. Returns `0` if +/// the account is non-existent. +/// +/// # Parameters +/// - `token` - The token. +/// - `owner` - The account whose balance is being queried. +#[inline] +pub fn balance_of(token: TokenId, owner: AccountId) -> Result { + build_read_state(BALANCE_OF) + .input::<(TokenId, AccountId)>() + .output::, true>() + .handle_error_code::() + .call(&(token, owner)) +} + +/// Returns the allowance for a `spender` approved by an `owner`, for a specified `token`. Returns +/// `0` if no allowance has been set. +/// +/// # Parameters +/// - `token` - The token. +/// - `owner` - The account that owns the tokens. +/// - `spender` - The account that is allowed to spend the tokens. +#[inline] +pub fn allowance(token: TokenId, owner: AccountId, spender: AccountId) -> Result { + build_read_state(ALLOWANCE) + .input::<(TokenId, AccountId, AccountId)>() + .output::, true>() + .handle_error_code::() + .call(&(token, owner, spender)) +} + +/// Transfers `value` amount of tokens from the caller's account to account `to`. +/// +/// # Parameters +/// - `token` - The token to transfer. +/// - `to` - The recipient account. +/// - `value` - The number of tokens to transfer. +#[inline] +pub fn transfer(token: TokenId, to: AccountId, value: Balance) -> Result<()> { + build_dispatch(TRANSFER) + .input::<(TokenId, AccountId, Balance)>() + .output::, true>() + .handle_error_code::() + .call(&(token, to, value)) +} + +/// Transfers `value` amount tokens on behalf of `from` to account `to`. +/// +/// # Parameters +/// - `token` - The token to transfer. +/// - `from` - The account from which the token balance will be withdrawn. +/// - `to` - The recipient account. +/// - `value` - The number of tokens to transfer. +#[inline] +pub fn transfer_from(token: TokenId, from: AccountId, to: AccountId, value: Balance) -> Result<()> { + build_dispatch(TRANSFER_FROM) + .input::<(TokenId, AccountId, AccountId, Balance)>() + .output::, true>() + .handle_error_code::() + .call(&(token, from, to, value)) +} + +/// Approves `spender` to spend `value` amount of tokens on behalf of the caller. +/// +/// # Parameters +/// - `token` - The token to approve. +/// - `spender` - The account that is allowed to spend the tokens. +/// - `value` - The number of tokens to approve. +#[inline] +pub fn approve(token: TokenId, spender: AccountId, value: Balance) -> Result<()> { + build_dispatch(APPROVE) + .input::<(TokenId, AccountId, Balance)>() + .output::, true>() + .handle_error_code::() + .call(&(token, spender, value)) +} + +/// Increases the allowance of `spender` by `value` amount of tokens. +/// +/// # Parameters +/// - `token` - The token to have an allowance increased. +/// - `spender` - The account that is allowed to spend the tokens. +/// - `value` - The number of tokens to increase the allowance by. +#[inline] +pub fn increase_allowance(token: TokenId, spender: AccountId, value: Balance) -> Result<()> { + build_dispatch(INCREASE_ALLOWANCE) + .input::<(TokenId, AccountId, Balance)>() + .output::, true>() + .handle_error_code::() + .call(&(token, spender, value)) +} + +/// Decreases the allowance of `spender` by `value` amount of tokens. +/// +/// # Parameters +/// - `token` - The token to have an allowance decreased. +/// - `spender` - The account that is allowed to spend the tokens. +/// - `value` - The number of tokens to decrease the allowance by. +#[inline] +pub fn decrease_allowance(token: TokenId, spender: AccountId, value: Balance) -> Result<()> { + build_dispatch(DECREASE_ALLOWANCE) + .input::<(TokenId, AccountId, Balance)>() + .output::, true>() + .handle_error_code::() + .call(&(token, spender, value)) +} + +/// Creates `value` amount of tokens and assigns them to `account`, increasing the total supply. +/// +/// # Parameters +/// - `token` - The token to mint. +/// - `account` - The account to be credited with the created tokens. +/// - `value` - The number of tokens to mint. +#[inline] +pub fn mint(token: TokenId, account: AccountId, value: Balance) -> Result<()> { + build_dispatch(MINT) + .input::<(TokenId, AccountId, Balance)>() + .output::, true>() + .handle_error_code::() + .call(&(token, account, value)) +} + +/// Destroys `value` amount of tokens from `account`, reducing the total supply. +/// +/// # Parameters +/// - `token` - the token to burn. +/// - `account` - The account from which the tokens will be destroyed. +/// - `value` - The number of tokens to destroy. +#[inline] +pub fn burn(token: TokenId, account: AccountId, value: Balance) -> Result<()> { + build_dispatch(BURN) + .input::<(TokenId, AccountId, Balance)>() + .output::, true>() + .handle_error_code::() + .call(&(token, account, value)) +} + +/// The PSP-22 compliant interface for querying metadata. +pub mod metadata { + use super::*; + + /// Returns the name of the specified token. + /// + /// # Parameters + /// - `token` - The token. + #[inline] + pub fn token_name(token: TokenId) -> Result> { + build_read_state(TOKEN_NAME) + .input::() + .output::>, true>() + .handle_error_code::() + .call(&(token)) + } + + /// Returns the symbol for the specified token. + /// + /// # Parameters + /// - `token` - The token. + #[inline] + pub fn token_symbol(token: TokenId) -> Result> { + build_read_state(TOKEN_SYMBOL) + .input::() + .output::>, true>() + .handle_error_code::() + .call(&(token)) + } + + /// Returns the decimals for the specified token. + /// + /// # Parameters + /// - `token` - The token. + #[inline] + pub fn token_decimals(token: TokenId) -> Result { + build_read_state(TOKEN_DECIMALS) + .input::() + .output::, true>() + .handle_error_code::() + .call(&(token)) + } +} + +/// The interface for creating, managing and destroying fungible tokens. +pub mod management { + use super::*; + + /// Create a new token with a given identifier. + /// + /// # Parameters + /// - `id` - The identifier of the token. + /// - `admin` - The account that will administer the token. + /// - `min_balance` - The minimum balance required for accounts holding this token. + #[inline] + pub fn create(id: TokenId, admin: AccountId, min_balance: Balance) -> Result<()> { + build_dispatch(CREATE) + .input::<(TokenId, AccountId, Balance)>() + .output::, true>() + .handle_error_code::() + .call(&(id, admin, min_balance)) + } + + /// Start the process of destroying a token. + /// + /// # Parameters + /// - `token` - The token to be destroyed. + #[inline] + pub fn start_destroy(token: TokenId) -> Result<()> { + build_dispatch(START_DESTROY) + .input::() + .output::, true>() + .handle_error_code::() + .call(&(token)) + } + + /// Set the metadata for a token. + /// + /// # Parameters + /// - `token`: The token to update. + /// - `name`: The user friendly name of this token. + /// - `symbol`: The exchange symbol for this token. + /// - `decimals`: The number of decimals this token uses to represent one unit. + #[inline] + pub fn set_metadata( + token: TokenId, + name: Vec, + symbol: Vec, + decimals: u8, + ) -> Result<()> { + build_dispatch(SET_METADATA) + .input::<(TokenId, Vec, Vec, u8)>() + .output::, true>() + .handle_error_code::() + .call(&(token, name, symbol, decimals)) + } + + /// Clear the metadata for a token. + /// + /// # Parameters + /// - `token` - The token to update + #[inline] + pub fn clear_metadata(token: TokenId) -> Result<()> { + build_dispatch(CLEAR_METADATA) + .input::() + .output::, true>() + .handle_error_code::() + .call(&(token)) + } + + /// Checks if a specified token exists. + /// + /// # Parameters + /// - `token` - The token. + #[inline] + pub fn token_exists(token: TokenId) -> Result { + build_read_state(TOKEN_EXISTS) + .input::() + .output::, true>() + .handle_error_code::() + .call(&(token)) + } +} diff --git a/pop-api/src/v0/fungibles/tests.rs b/pop-api/src/v0/fungibles/tests.rs new file mode 100644 index 00000000..128cf4cb --- /dev/null +++ b/pop-api/src/v0/fungibles/tests.rs @@ -0,0 +1,99 @@ +use super::FungiblesError; +use crate::{ + constants::{ASSETS, BALANCES}, + primitives::{ + ArithmeticError::*, + Error::{self, *}, + TokenError::*, + TransactionalError::*, + }, + StatusCode, +}; +use ink::scale::{Decode, Encode}; + +fn error_into_status_code(error: Error) -> StatusCode { + let mut encoded_error = error.encode(); + encoded_error.resize(4, 0); + let value = + u32::from_le_bytes(encoded_error.try_into().expect("qed, resized to 4 bytes line above")); + value.into() +} + +fn into_fungibles_error(error: Error) -> FungiblesError { + let status_code: StatusCode = error_into_status_code(error); + status_code.into() +} + +// If we ever want to change the conversion from bytes to `u32`. +#[test] +fn status_code_vs_encoded() { + assert_eq!(u32::decode(&mut &[3u8, 10, 2, 0][..]).unwrap(), 133635u32); + assert_eq!(u32::decode(&mut &[3u8, 52, 0, 0][..]).unwrap(), 13315u32); + assert_eq!(u32::decode(&mut &[3u8, 52, 1, 0][..]).unwrap(), 78851u32); + assert_eq!(u32::decode(&mut &[3u8, 52, 2, 0][..]).unwrap(), 144387u32); + assert_eq!(u32::decode(&mut &[3u8, 52, 3, 0][..]).unwrap(), 209923u32); + assert_eq!(u32::decode(&mut &[3u8, 52, 5, 0][..]).unwrap(), 340995u32); + assert_eq!(u32::decode(&mut &[3u8, 52, 7, 0][..]).unwrap(), 472067u32); + assert_eq!(u32::decode(&mut &[3u8, 52, 10, 0][..]).unwrap(), 668675u32); +} + +#[test] +fn converting_status_code_into_fungibles_error_works() { + let other_errors = vec![ + Other, + CannotLookup, + BadOrigin, + // `ModuleError` other than assets module. + Module { index: 2, error: [5, 0] }, + ConsumerRemaining, + NoProviders, + TooManyConsumers, + Token(OnlyProvider), + Arithmetic(Overflow), + Transactional(NoLayer), + Exhausted, + Corruption, + Unavailable, + RootNotAllowed, + Unknown { dispatch_error_index: 5, error_index: 5, error: 1 }, + DecodingFailed, + ]; + for error in other_errors { + let status_code: StatusCode = error_into_status_code(error); + let fungibles_error: FungiblesError = status_code.into(); + assert_eq!(fungibles_error, FungiblesError::Other(status_code)) + } + + assert_eq!( + into_fungibles_error(Module { index: BALANCES, error: [2, 0] }), + FungiblesError::NoBalance + ); + assert_eq!( + into_fungibles_error(Module { index: ASSETS, error: [0, 0] }), + FungiblesError::NoAccount + ); + assert_eq!( + into_fungibles_error(Module { index: ASSETS, error: [1, 0] }), + FungiblesError::NoPermission + ); + assert_eq!( + into_fungibles_error(Module { index: ASSETS, error: [2, 0] }), + FungiblesError::Unknown + ); + assert_eq!( + into_fungibles_error(Module { index: ASSETS, error: [3, 0] }), + FungiblesError::InUse + ); + assert_eq!( + into_fungibles_error(Module { index: ASSETS, error: [5, 0] }), + FungiblesError::MinBalanceZero + ); + assert_eq!( + into_fungibles_error(Module { index: ASSETS, error: [7, 0] }), + FungiblesError::InsufficientAllowance + ); + assert_eq!( + into_fungibles_error(Module { index: ASSETS, error: [10, 0] }), + FungiblesError::NotLive + ); +} From 4ead643455b4fbf90b0d3bbfef7279557e4e38e3 Mon Sep 17 00:00:00 2001 From: chungquantin <56880684+chungquantin@users.noreply.github.com> Date: Wed, 18 Sep 2024 16:45:48 +0800 Subject: [PATCH 090/112] refactor: fungible example --- pop-api/examples/fungibles/lib.rs | 297 +++++++++++++++++-------- pop-api/src/v0/fungibles/errors.rs | 30 +++ pop-api/src/v0/fungibles/interfaces.rs | 99 +++------ 3 files changed, 262 insertions(+), 164 deletions(-) diff --git a/pop-api/examples/fungibles/lib.rs b/pop-api/examples/fungibles/lib.rs index 2148e967..0b660ee6 100644 --- a/pop-api/examples/fungibles/lib.rs +++ b/pop-api/examples/fungibles/lib.rs @@ -1,159 +1,274 @@ #![cfg_attr(not(feature = "std"), no_std, no_main)] -use ink::prelude::vec::Vec; +use ink::prelude::{string::String, vec::Vec}; use pop_api::{ primitives::TokenId, - v0::fungibles::{self as api}, - StatusCode, + v0::fungibles::{ + self as api, + events::{Approval, Created, Transfer}, + traits::{Psp22, Psp22Burnable, Psp22Metadata, Psp22Mintable}, + PSP22Error, + }, }; -#[cfg(test)] -mod tests; - -type PopApiResult = core::result::Result; - #[ink::contract] mod fungibles { use super::*; #[ink(storage)] - #[derive(Default)] - pub struct Fungibles; + pub struct Fungibles { + id: TokenId, + } impl Fungibles { + fn emit_created_event(&mut self, id: u32, creator: AccountId, admin: AccountId) { + self.env().emit_event(Created { id, creator, admin }); + } + + fn emit_transfer_event( + &mut self, + from: Option, + to: Option, + value: Balance, + ) { + self.env().emit_event(Transfer { from, to, value }); + } + + fn emit_approval_event(&mut self, owner: AccountId, spender: AccountId, value: Balance) { + self.env().emit_event(Approval { owner, spender, value }); + } + + /// Instantiate the contract and wrap around an existing token. + /// + /// # Parameters + /// * - `token` - The token. + #[ink(constructor, payable)] + pub fn new_existing(id: TokenId) -> Result { + // Make sure token exists. + if !api::token_exists(id).unwrap_or_default() { + return Err(PSP22Error::Custom(String::from("Unknown"))); + } + let contract = Self { id }; + Ok(contract) + } + + /// Instantiate the contract and create a new token. The token identifier will be stored + /// in contract's storage. + /// + /// # Parameters + /// * - `id` - The identifier of the token. + /// * - `admin` - The account that will administer the token. + /// * - `min_balance` - The minimum balance required for accounts holding this token. #[ink(constructor, payable)] - pub fn new() -> Self { - Default::default() + pub fn new( + id: TokenId, + admin: AccountId, + min_balance: Balance, + ) -> Result { + api::create(id, admin, min_balance).map_err(PSP22Error::from)?; + let mut contract = Self { id }; + contract.emit_created_event(id, contract.env().account_id(), admin); + Ok(contract) } + } + impl Psp22 for Fungibles { + /// Returns the total token supply. #[ink(message)] - pub fn mint( - &mut self, - token: TokenId, - account: AccountId, - amount: Balance, - ) -> PopApiResult<()> { - api::mint(token, account, amount) + fn total_supply(&self) -> Balance { + api::total_supply(self.id).unwrap_or_default() } + /// Returns the account balance for the specified `owner` #[ink(message)] - pub fn burn( - &mut self, - token: TokenId, - account: AccountId, - amount: Balance, - ) -> PopApiResult<()> { - api::burn(token, account, amount) + fn balance_of(&self, owner: AccountId) -> Balance { + api::balance_of(self.id, owner).unwrap_or_default() } + /// Returns the amount which `spender` is still allowed to withdraw from `owner` #[ink(message)] - pub fn transfer(&mut self, token: TokenId, to: AccountId, value: Balance) -> PopApiResult<()> { - api::transfer(token, to, value) + fn allowance(&self, owner: AccountId, spender: AccountId) -> Balance { + api::allowance(self.id, owner, spender).unwrap_or_default() } + /// Transfers `value` amount of tokens from the caller's account to account `to` + /// with additional `data` in unspecified format. #[ink(message)] - pub fn transfer_from( + fn transfer( &mut self, - token: TokenId, - from: AccountId, to: AccountId, value: Balance, _data: Vec, - ) -> PopApiResult<()> { - api::transfer_from(token, from, to, value) + ) -> Result<(), PSP22Error> { + let caller = self.env().caller(); + // No-op if the caller and `to` is the same address or `value` is zero, returns success + // and no events are emitted. + if caller == to || value == 0 { + return Ok(()); + } + + // Reverts with `InsufficientBalance` if the `value` exceeds the caller's balance. + if value > self.env().balance() { + return Err(PSP22Error::InsufficientBalance); + } + + api::transfer(self.id, to, value).map_err(PSP22Error::from)?; + self.emit_transfer_event(Some(caller), Some(to), value); + Ok(()) } + /// Transfers `value` tokens on the behalf of `from` to the account `to` + /// with additional `data` in unspecified format. #[ink(message)] - pub fn approve( + fn transfer_from( &mut self, - token: TokenId, - spender: AccountId, + from: AccountId, + to: AccountId, value: Balance, - ) -> PopApiResult<()> { - api::approve(token, spender, value) + _data: Vec, + ) -> Result<(), PSP22Error> { + let caller = self.env().caller(); + // No-op if `from` and `to` is the same address or `value` is zero, returns success and + // no events are emitted. + if from == to || value == 0 { + return Ok(()); + } + + // Reverts with `InsufficientBalance` if the `value` exceeds the balance of the account + // `from`. + let allowance = self.allowance(from, caller); + if allowance < value { + return Err(PSP22Error::InsufficientAllowance); + } + + // Reverts with `InsufficientAllowance` if `from` and the caller are different addresses + // and the `value` exceeds the allowance granted by `from` to the caller. + let from_balance = self.balance_of(from); + if from_balance < value { + return Err(PSP22Error::InsufficientBalance); + } + + // If `from` and the caller are different addresses, a successful transfer results + // in decreased allowance by `from` to the caller and an `Approval` event with + // the new allowance amount is emitted. + api::transfer_from(self.id, from, to, value).map_err(PSP22Error::from)?; + // Emit events. + self.emit_transfer_event(Some(caller), Some(to), value); + let allowance = self.allowance(from, to).saturating_sub(value); + self.emit_approval_event(from, caller, allowance); + Ok(()) } + /// Allows `spender` to withdraw from the caller's account multiple times, up to + /// the total amount of `value`. #[ink(message)] - pub fn increase_allowance( - &mut self, - token: TokenId, - spender: AccountId, - value: Balance, - ) -> PopApiResult<()> { - api::increase_allowance(token, spender, value) + fn approve(&mut self, spender: AccountId, value: Balance) -> Result<(), PSP22Error> { + let caller = self.env().caller(); + // No-op if the caller and `spender` is the same address, returns success and no events + // are emitted. + if caller == spender { + return Ok(()); + } + + api::approve(self.id, spender, value).map_err(PSP22Error::from)?; + self.emit_approval_event(caller, spender, value); + Ok(()) } + /// Increases by `value` the allowance granted to `spender` by the caller. #[ink(message)] - pub fn decrease_allowance( + fn increase_allowance( &mut self, - token: TokenId, spender: AccountId, value: Balance, - ) -> PopApiResult<()> { - api::decrease_allowance(token, spender, value) - } + ) -> Result<(), PSP22Error> { + let caller = self.env().caller(); + // No-op if the caller and `spender` is the same address or `value` is zero, returns success + // and no events are emitted. + if caller == spender || value == 0 { + return Ok(()); + } - #[ink(message, payable)] - pub fn create( - &self, - id: TokenId, - admin: AccountId, - min_balance: Balance, - ) -> PopApiResult<()> { - api::create(id, admin, min_balance)?; - self.env().emit_event(api::events::Created { id, creator: admin, admin }); + api::increase_allowance(self.id, spender, value).map_err(PSP22Error::from)?; + let allowance = self.allowance(caller, spender).saturating_add(value); + self.emit_approval_event(caller, spender, allowance); Ok(()) } + /// Decreases by `value` the allowance granted to `spender` by the caller. #[ink(message)] - pub fn set_metadata( - &self, - token: TokenId, - name: Vec, - symbol: Vec, - decimals: u8, - ) -> PopApiResult<()> { - api::set_metadata(token, name, symbol, decimals) - } - - #[ink(message)] - pub fn total_supply(&self, token: TokenId) -> PopApiResult { - api::total_supply(token) - } + fn decrease_allowance( + &mut self, + spender: AccountId, + value: Balance, + ) -> Result<(), PSP22Error> { + let caller = self.env().caller(); + // No-op if the caller and `spender` is the same address or `value` is zero, returns success + // and no events are emitted. + if caller == spender || value == 0 { + return Ok(()); + } + // Reverts with `InsufficientAllowance` if `spender` and the caller are different addresses and + // the `value` exceeds the allowance granted by the caller to `spender`. + let allowance = self.allowance(caller, spender); + if allowance < value { + return Err(PSP22Error::InsufficientAllowance); + } - #[ink(message)] - pub fn balance_of(&self, token: TokenId, owner: AccountId) -> PopApiResult { - api::balance_of(token, owner) + api::decrease_allowance(self.id, spender, value).map_err(PSP22Error::from)?; + let allowance = allowance.saturating_sub(value); + self.emit_approval_event(caller, spender, allowance); + Ok(()) } + } + impl Psp22Metadata for Fungibles { + /// Returns the token name. #[ink(message)] - pub fn allowance( - &self, - token: TokenId, - owner: AccountId, - spender: AccountId, - ) -> PopApiResult { - api::allowance(token, owner, spender) + fn token_name(&self) -> Option { + api::token_name(self.id).ok().and_then(|v| String::from_utf8(v).ok()) } + /// Returns the token symbol. #[ink(message)] - pub fn token_name(&self, token: TokenId) -> PopApiResult> { - api::token_name(token) + fn token_symbol(&self) -> Option { + api::token_symbol(self.id).ok().and_then(|v| String::from_utf8(v).ok()) } + /// Returns the token decimals. #[ink(message)] - pub fn token_symbol(&self, token: TokenId) -> PopApiResult> { - api::token_symbol(token) + fn token_decimals(&self) -> u8 { + api::token_decimals(self.id).unwrap_or_default() } + } + impl Psp22Mintable for Fungibles { + /// Mints `value` tokens to the senders account. #[ink(message)] - pub fn token_decimals(&self, token: TokenId) -> PopApiResult { - api::token_decimals(token) + fn mint(&mut self, account: AccountId, value: Balance) -> Result<(), PSP22Error> { + if value == 0 { + return Ok(()); + } + api::mint(self.id, account, value).map_err(PSP22Error::from)?; + self.emit_transfer_event(None, Some(account), value); + Ok(()) } + } + impl Psp22Burnable for Fungibles { + /// Burns `value` tokens from the senders account. #[ink(message)] - pub fn token_exists(&self, token: TokenId) -> PopApiResult { - api::token_exists(token) + fn burn(&mut self, account: AccountId, value: Balance) -> Result<(), PSP22Error> { + if value == 0 { + return Ok(()); + } + let balance = self.balance_of(account); + if balance < value { + return Err(PSP22Error::InsufficientBalance); + } + api::burn(self.id, account, value).map_err(PSP22Error::from)?; + self.emit_transfer_event(Some(account), None, value); + Ok(()) } } } diff --git a/pop-api/src/v0/fungibles/errors.rs b/pop-api/src/v0/fungibles/errors.rs index b29127e5..872e8d64 100644 --- a/pop-api/src/v0/fungibles/errors.rs +++ b/pop-api/src/v0/fungibles/errors.rs @@ -61,3 +61,33 @@ impl From for FungiblesError { } } } + +/// The PSP22 error. +#[derive(Debug, PartialEq, Eq)] +#[ink::scale_derive(Encode, Decode, TypeInfo)] +pub enum PSP22Error { + /// Custom error type for implementation-based errors. + Custom(String), + /// Returned when an account does not have enough tokens to complete the operation. + InsufficientBalance, + /// Returned if there is not enough allowance to complete the operation. + InsufficientAllowance, + /// Returned if recipient's address is zero. + ZeroRecipientAddress, + /// Returned if sender's address is zero. + ZeroSenderAddress, + /// Returned if a safe transfer check failed. + SafeTransferCheckFailed(String), +} + +impl From for PSP22Error { + /// Converts a `StatusCode` to a `PSP22Error`. + fn from(value: StatusCode) -> Self { + let encoded = value.0.to_le_bytes(); + match encoded { + [_, ASSETS, 3, _] => PSP22Error::Custom(String::from("Unknown")), + [_, ASSETS, 7, _] => PSP22Error::InsufficientAllowance, + _ => PSP22Error::Custom(String::from("Other")), + } + } +} diff --git a/pop-api/src/v0/fungibles/interfaces.rs b/pop-api/src/v0/fungibles/interfaces.rs index 6023ce37..5b52504a 100644 --- a/pop-api/src/v0/fungibles/interfaces.rs +++ b/pop-api/src/v0/fungibles/interfaces.rs @@ -12,8 +12,6 @@ pub trait Psp22 { /// /// # Parameters /// - `owner` - The account whose balance is being queried. - /// - /// Returns `0` if the account is non-existent. #[ink(message)] fn balance_of(&self, owner: AccountId) -> Balance; @@ -22,8 +20,6 @@ pub trait Psp22 { /// # Parameters /// - `owner` - The account that owns the tokens. /// - `spender` - The account that is allowed to spend the tokens. - /// - /// Returns `0` if no allowance has been set. #[ink(message)] fn allowance(&self, owner: AccountId, spender: AccountId) -> Balance; @@ -34,15 +30,6 @@ pub trait Psp22 { /// - `to` - The recipient account. /// - `value` - The number of tokens to transfer. /// - `data` - Additional data in unspecified format. - /// - /// # Events - /// On success a `Transfer` event is emitted. - /// - /// No-op if the caller and `to` is the same address or `value` is zero, returns success - /// and no events are emitted. - /// - /// # Errors - /// Reverts with `InsufficientBalance` if the `value` exceeds the caller's balance. #[ink(message)] fn transfer(&mut self, to: AccountId, value: Balance, data: Vec) -> Result<()>; @@ -53,28 +40,6 @@ pub trait Psp22 { /// - `from` - The account from which the token balance will be withdrawn. /// - `to` - The recipient account. /// - `value` - The number of tokens to transfer. - /// - /// If `from` and the caller are different addresses, the caller must be allowed - /// by `from` to spend at least `value` tokens. - /// - /// # Events - /// On success a `Transfer` event is emitted. - /// - /// No-op if `from` and `to` is the same address or `value` is zero, returns success - /// and no events are emitted. - /// - /// If `from` and the caller are different addresses, a successful transfer results - /// in decreased allowance by `from` to the caller and an `Approval` event with - /// the new allowance amount is emitted. - /// - /// # Errors - /// Reverts with `InsufficientBalance` if the `value` exceeds the balance of the account `from`. - /// - /// Reverts with `InsufficientAllowance` if `from` and the caller are different addresses and - /// the `value` exceeds the allowance granted by `from` to the caller. - /// - /// If conditions for both `InsufficientBalance` and `InsufficientAllowance` errors are met, - /// reverts with `InsufficientAllowance`. #[ink(message)] fn transfer_from( &mut self, @@ -91,11 +56,6 @@ pub trait Psp22 { /// # Parameters /// - `spender` - The account that is allowed to spend the tokens. /// - `value` - The number of tokens to approve. - /// - /// # Events - /// An `Approval` event is emitted. - /// - /// No-op if the caller and `spender` is the same address, returns success and no events are emitted. #[ink(message)] fn approve(&mut self, spender: AccountId, value: Balance) -> Result<()>; @@ -104,12 +64,6 @@ pub trait Psp22 { /// # Parameters /// - `spender` - The account that is allowed to spend the tokens. /// - `value` - The number of tokens to increase the allowance by. - /// - /// # Events - /// An `Approval` event with the new allowance amount is emitted. - /// - /// No-op if the caller and `spender` is the same address or `value` is zero, returns success - /// and no events are emitted. #[ink(message)] fn increase_allowance(&mut self, spender: AccountId, value: Balance) -> Result<()>; @@ -118,16 +72,6 @@ pub trait Psp22 { /// # Parameters /// - `spender` - The account that is allowed to spend the tokens. /// - `value` - The number of tokens to decrease the allowance by. - /// - /// # Events - /// An `Approval` event with the new allowance amount is emitted. - /// - /// No-op if the caller and `spender` is the same address or `value` is zero, returns success - /// and no events are emitted. - /// - /// # Errors - /// Reverts with `InsufficientAllowance` if `spender` and the caller are different addresses and - /// the `value` exceeds the allowance granted by the caller to `spender`. #[ink(message)] fn decrease_allowance(&mut self, spender: AccountId, value: Balance) -> Result<()>; } @@ -135,12 +79,30 @@ pub trait Psp22 { /// The PSP22 Metadata trait. #[ink::trait_definition] pub trait Psp22Managable { + /// Creates a new token with the specified `id`, assigns `admin` as the administrator, + /// and sets a minimum balance requirement. + /// + /// # Parameters + /// - `id`: The unique identifier for the token to be created. + /// - `admin`: The account that will have administrative privileges over the token. + /// - `min_balance`: The minimum balance required to hold the token. #[ink(message)] fn create(&mut self, id: TokenId, admin: AccountId, min_balance: Balance) -> Result<()>; + /// Initiates the process to destroy the specified `token`. + /// + /// # Parameters + /// - `token`: The identifier of the token to be destroyed. #[ink(message)] fn start_destroy(&mut self, token: TokenId) -> Result<()>; + /// Sets metadata for the specified `token`, including its name, symbol, and decimal places. + /// + /// # Parameters + /// - `token`: The identifier of the token to set metadata for. + /// - `name`: The name of the token. + /// - `symbol`: The symbol representing the token. + /// - `decimals`: The number of decimal places the token uses. #[ink(message)] fn set_metadata( &mut self, @@ -150,9 +112,17 @@ pub trait Psp22Managable { decimals: u8, ) -> Result<()>; + /// Clears the metadata for the specified `token`. + /// + /// # Parameters + /// - `token`: The identifier of the token to clear metadata for. #[ink(message)] fn clear_metadata(&mut self, token: TokenId) -> Result<()>; + /// Checks whether a token with the specified `token` identifier exists. + /// + /// # Parameters + /// - `token`: The identifier of the token to check for existence. #[ink(message)] fn token_exists(&self, token: TokenId) -> Result; } @@ -181,15 +151,6 @@ pub trait Psp22Mintable { /// # Parameters /// - `account` - The account to be credited with the created tokens. /// - `value` - The number of tokens to mint. - /// - /// # Events - /// On success a `Transfer` event is emitted with `None` sender. - /// - /// No-op if `value` is zero, returns success and no events are emitted. - /// - /// # Errors - /// Reverts with `Custom (max supply exceeded)` if the total supply increased by - /// `value` exceeds maximal value of `u128` type. #[ink(message)] fn mint(&mut self, account: AccountId, amount: Balance) -> Result<()>; } @@ -202,14 +163,6 @@ pub trait Psp22Burnable { /// # Parameters /// - `account` - The account from which the tokens will be destroyed. /// - `value` - The number of tokens to destroy. - /// - /// # Events - /// On success a `Transfer` event is emitted with `None` recipient. - /// - /// No-op if `value` is zero, returns success and no events are emitted. - /// - /// # Errors - /// Reverts with `InsufficientBalance` if the `value` exceeds the caller's balance. #[ink(message)] fn burn(&mut self, account: AccountId, amount: Balance) -> Result<()>; } From 12d1af4376392dbba9981aa8f71cda845872df64 Mon Sep 17 00:00:00 2001 From: chungquantin <56880684+chungquantin@users.noreply.github.com> Date: Wed, 18 Sep 2024 17:39:13 +0800 Subject: [PATCH 091/112] feat: refactor example contract to follow spec --- pop-api/src/v0/fungibles/interfaces.rs | 28 +++++---- pop-api/src/v0/fungibles/mod.rs | 81 ++++++++++++++------------ 2 files changed, 58 insertions(+), 51 deletions(-) diff --git a/pop-api/src/v0/fungibles/interfaces.rs b/pop-api/src/v0/fungibles/interfaces.rs index 5b52504a..a4b48a4c 100644 --- a/pop-api/src/v0/fungibles/interfaces.rs +++ b/pop-api/src/v0/fungibles/interfaces.rs @@ -1,7 +1,5 @@ use super::*; -pub type Result = core::result::Result; - #[ink::trait_definition] pub trait Psp22 { /// Returns the total token supply. @@ -31,7 +29,7 @@ pub trait Psp22 { /// - `value` - The number of tokens to transfer. /// - `data` - Additional data in unspecified format. #[ink(message)] - fn transfer(&mut self, to: AccountId, value: Balance, data: Vec) -> Result<()>; + fn transfer(&mut self, to: AccountId, value: Balance, data: Vec) -> PSP22Result<()>; /// Transfers `value` tokens on behalf of `from` to the account `to` /// with additional `data` in unspecified format. @@ -47,7 +45,7 @@ pub trait Psp22 { to: AccountId, value: Balance, data: Vec, - ) -> Result<()>; + ) -> PSP22Result<()>; /// Approves `spender` to spend `value` amount of tokens on behalf of the caller. /// @@ -57,7 +55,7 @@ pub trait Psp22 { /// - `spender` - The account that is allowed to spend the tokens. /// - `value` - The number of tokens to approve. #[ink(message)] - fn approve(&mut self, spender: AccountId, value: Balance) -> Result<()>; + fn approve(&mut self, spender: AccountId, value: Balance) -> PSP22Result<()>; /// Increases the allowance of `spender` by `value` amount of tokens. /// @@ -65,7 +63,7 @@ pub trait Psp22 { /// - `spender` - The account that is allowed to spend the tokens. /// - `value` - The number of tokens to increase the allowance by. #[ink(message)] - fn increase_allowance(&mut self, spender: AccountId, value: Balance) -> Result<()>; + fn increase_allowance(&mut self, spender: AccountId, value: Balance) -> PSP22Result<()>; /// Decreases the allowance of `spender` by `value` amount of tokens. /// @@ -73,12 +71,12 @@ pub trait Psp22 { /// - `spender` - The account that is allowed to spend the tokens. /// - `value` - The number of tokens to decrease the allowance by. #[ink(message)] - fn decrease_allowance(&mut self, spender: AccountId, value: Balance) -> Result<()>; + fn decrease_allowance(&mut self, spender: AccountId, value: Balance) -> PSP22Result<()>; } /// The PSP22 Metadata trait. #[ink::trait_definition] -pub trait Psp22Managable { +pub trait Management { /// Creates a new token with the specified `id`, assigns `admin` as the administrator, /// and sets a minimum balance requirement. /// @@ -87,14 +85,14 @@ pub trait Psp22Managable { /// - `admin`: The account that will have administrative privileges over the token. /// - `min_balance`: The minimum balance required to hold the token. #[ink(message)] - fn create(&mut self, id: TokenId, admin: AccountId, min_balance: Balance) -> Result<()>; + fn create(&mut self, id: TokenId, admin: AccountId, min_balance: Balance) -> PSP22Result<()>; /// Initiates the process to destroy the specified `token`. /// /// # Parameters /// - `token`: The identifier of the token to be destroyed. #[ink(message)] - fn start_destroy(&mut self, token: TokenId) -> Result<()>; + fn start_destroy(&mut self, token: TokenId) -> PSP22Result<()>; /// Sets metadata for the specified `token`, including its name, symbol, and decimal places. /// @@ -110,21 +108,21 @@ pub trait Psp22Managable { name: Vec, symbol: Vec, decimals: u8, - ) -> Result<()>; + ) -> PSP22Result<()>; /// Clears the metadata for the specified `token`. /// /// # Parameters /// - `token`: The identifier of the token to clear metadata for. #[ink(message)] - fn clear_metadata(&mut self, token: TokenId) -> Result<()>; + fn clear_metadata(&mut self, token: TokenId) -> PSP22Result<()>; /// Checks whether a token with the specified `token` identifier exists. /// /// # Parameters /// - `token`: The identifier of the token to check for existence. #[ink(message)] - fn token_exists(&self, token: TokenId) -> Result; + fn token_exists(&self, token: TokenId) -> PSP22Result; } /// The PSP22 Metadata trait. @@ -152,7 +150,7 @@ pub trait Psp22Mintable { /// - `account` - The account to be credited with the created tokens. /// - `value` - The number of tokens to mint. #[ink(message)] - fn mint(&mut self, account: AccountId, amount: Balance) -> Result<()>; + fn mint(&mut self, account: AccountId, amount: Balance) -> PSP22Result<()>; } /// The PSP22 Burnable trait. @@ -164,5 +162,5 @@ pub trait Psp22Burnable { /// - `account` - The account from which the tokens will be destroyed. /// - `value` - The number of tokens to destroy. #[ink(message)] - fn burn(&mut self, account: AccountId, amount: Balance) -> Result<()>; + fn burn(&mut self, account: AccountId, amount: Balance) -> PSP22Result<()>; } diff --git a/pop-api/src/v0/fungibles/mod.rs b/pop-api/src/v0/fungibles/mod.rs index e8d4e81d..da731819 100644 --- a/pop-api/src/v0/fungibles/mod.rs +++ b/pop-api/src/v0/fungibles/mod.rs @@ -17,6 +17,7 @@ use crate::{ ChainExtensionMethodApi, StatusCode, }; use constants::*; +use core::result::Result; pub use errors::*; pub use events::*; use ink::prelude::vec::Vec; @@ -24,6 +25,9 @@ pub use interfaces::*; pub use management::*; pub use metadata::*; +pub type PSP22Result = Result; +pub type PopApiResult = Result; + // Helper method to build a dispatch call. // // Parameters: @@ -73,10 +77,10 @@ mod constants { /// # Parameters /// - `token` - The token. #[inline] -pub fn total_supply(token: TokenId) -> Result { +pub fn total_supply(token: TokenId) -> PopApiResult { build_read_state(TOTAL_SUPPLY) .input::() - .output::, true>() + .output::, true>() .handle_error_code::() .call(&(token)) } @@ -88,10 +92,10 @@ pub fn total_supply(token: TokenId) -> Result { /// - `token` - The token. /// - `owner` - The account whose balance is being queried. #[inline] -pub fn balance_of(token: TokenId, owner: AccountId) -> Result { +pub fn balance_of(token: TokenId, owner: AccountId) -> PopApiResult { build_read_state(BALANCE_OF) .input::<(TokenId, AccountId)>() - .output::, true>() + .output::, true>() .handle_error_code::() .call(&(token, owner)) } @@ -104,10 +108,10 @@ pub fn balance_of(token: TokenId, owner: AccountId) -> Result { /// - `owner` - The account that owns the tokens. /// - `spender` - The account that is allowed to spend the tokens. #[inline] -pub fn allowance(token: TokenId, owner: AccountId, spender: AccountId) -> Result { +pub fn allowance(token: TokenId, owner: AccountId, spender: AccountId) -> PopApiResult { build_read_state(ALLOWANCE) .input::<(TokenId, AccountId, AccountId)>() - .output::, true>() + .output::, true>() .handle_error_code::() .call(&(token, owner, spender)) } @@ -119,10 +123,10 @@ pub fn allowance(token: TokenId, owner: AccountId, spender: AccountId) -> Result /// - `to` - The recipient account. /// - `value` - The number of tokens to transfer. #[inline] -pub fn transfer(token: TokenId, to: AccountId, value: Balance) -> Result<()> { +pub fn transfer(token: TokenId, to: AccountId, value: Balance) -> PopApiResult<()> { build_dispatch(TRANSFER) .input::<(TokenId, AccountId, Balance)>() - .output::, true>() + .output::, true>() .handle_error_code::() .call(&(token, to, value)) } @@ -135,10 +139,15 @@ pub fn transfer(token: TokenId, to: AccountId, value: Balance) -> Result<()> { /// - `to` - The recipient account. /// - `value` - The number of tokens to transfer. #[inline] -pub fn transfer_from(token: TokenId, from: AccountId, to: AccountId, value: Balance) -> Result<()> { +pub fn transfer_from( + token: TokenId, + from: AccountId, + to: AccountId, + value: Balance, +) -> PopApiResult<()> { build_dispatch(TRANSFER_FROM) .input::<(TokenId, AccountId, AccountId, Balance)>() - .output::, true>() + .output::, true>() .handle_error_code::() .call(&(token, from, to, value)) } @@ -150,10 +159,10 @@ pub fn transfer_from(token: TokenId, from: AccountId, to: AccountId, value: Bala /// - `spender` - The account that is allowed to spend the tokens. /// - `value` - The number of tokens to approve. #[inline] -pub fn approve(token: TokenId, spender: AccountId, value: Balance) -> Result<()> { +pub fn approve(token: TokenId, spender: AccountId, value: Balance) -> PopApiResult<()> { build_dispatch(APPROVE) .input::<(TokenId, AccountId, Balance)>() - .output::, true>() + .output::, true>() .handle_error_code::() .call(&(token, spender, value)) } @@ -165,10 +174,10 @@ pub fn approve(token: TokenId, spender: AccountId, value: Balance) -> Result<()> /// - `spender` - The account that is allowed to spend the tokens. /// - `value` - The number of tokens to increase the allowance by. #[inline] -pub fn increase_allowance(token: TokenId, spender: AccountId, value: Balance) -> Result<()> { +pub fn increase_allowance(token: TokenId, spender: AccountId, value: Balance) -> PopApiResult<()> { build_dispatch(INCREASE_ALLOWANCE) .input::<(TokenId, AccountId, Balance)>() - .output::, true>() + .output::, true>() .handle_error_code::() .call(&(token, spender, value)) } @@ -180,10 +189,10 @@ pub fn increase_allowance(token: TokenId, spender: AccountId, value: Balance) -> /// - `spender` - The account that is allowed to spend the tokens. /// - `value` - The number of tokens to decrease the allowance by. #[inline] -pub fn decrease_allowance(token: TokenId, spender: AccountId, value: Balance) -> Result<()> { +pub fn decrease_allowance(token: TokenId, spender: AccountId, value: Balance) -> PopApiResult<()> { build_dispatch(DECREASE_ALLOWANCE) .input::<(TokenId, AccountId, Balance)>() - .output::, true>() + .output::, true>() .handle_error_code::() .call(&(token, spender, value)) } @@ -195,10 +204,10 @@ pub fn decrease_allowance(token: TokenId, spender: AccountId, value: Balance) -> /// - `account` - The account to be credited with the created tokens. /// - `value` - The number of tokens to mint. #[inline] -pub fn mint(token: TokenId, account: AccountId, value: Balance) -> Result<()> { +pub fn mint(token: TokenId, account: AccountId, value: Balance) -> PopApiResult<()> { build_dispatch(MINT) .input::<(TokenId, AccountId, Balance)>() - .output::, true>() + .output::, true>() .handle_error_code::() .call(&(token, account, value)) } @@ -210,10 +219,10 @@ pub fn mint(token: TokenId, account: AccountId, value: Balance) -> Result<()> { /// - `account` - The account from which the tokens will be destroyed. /// - `value` - The number of tokens to destroy. #[inline] -pub fn burn(token: TokenId, account: AccountId, value: Balance) -> Result<()> { +pub fn burn(token: TokenId, account: AccountId, value: Balance) -> PopApiResult<()> { build_dispatch(BURN) .input::<(TokenId, AccountId, Balance)>() - .output::, true>() + .output::, true>() .handle_error_code::() .call(&(token, account, value)) } @@ -227,10 +236,10 @@ pub mod metadata { /// # Parameters /// - `token` - The token. #[inline] - pub fn token_name(token: TokenId) -> Result> { + pub fn token_name(token: TokenId) -> PopApiResult> { build_read_state(TOKEN_NAME) .input::() - .output::>, true>() + .output::>, true>() .handle_error_code::() .call(&(token)) } @@ -240,10 +249,10 @@ pub mod metadata { /// # Parameters /// - `token` - The token. #[inline] - pub fn token_symbol(token: TokenId) -> Result> { + pub fn token_symbol(token: TokenId) -> PopApiResult> { build_read_state(TOKEN_SYMBOL) .input::() - .output::>, true>() + .output::>, true>() .handle_error_code::() .call(&(token)) } @@ -253,10 +262,10 @@ pub mod metadata { /// # Parameters /// - `token` - The token. #[inline] - pub fn token_decimals(token: TokenId) -> Result { + pub fn token_decimals(token: TokenId) -> PopApiResult { build_read_state(TOKEN_DECIMALS) .input::() - .output::, true>() + .output::, true>() .handle_error_code::() .call(&(token)) } @@ -273,10 +282,10 @@ pub mod management { /// - `admin` - The account that will administer the token. /// - `min_balance` - The minimum balance required for accounts holding this token. #[inline] - pub fn create(id: TokenId, admin: AccountId, min_balance: Balance) -> Result<()> { + pub fn create(id: TokenId, admin: AccountId, min_balance: Balance) -> PopApiResult<()> { build_dispatch(CREATE) .input::<(TokenId, AccountId, Balance)>() - .output::, true>() + .output::, true>() .handle_error_code::() .call(&(id, admin, min_balance)) } @@ -286,10 +295,10 @@ pub mod management { /// # Parameters /// - `token` - The token to be destroyed. #[inline] - pub fn start_destroy(token: TokenId) -> Result<()> { + pub fn start_destroy(token: TokenId) -> PopApiResult<()> { build_dispatch(START_DESTROY) .input::() - .output::, true>() + .output::, true>() .handle_error_code::() .call(&(token)) } @@ -307,10 +316,10 @@ pub mod management { name: Vec, symbol: Vec, decimals: u8, - ) -> Result<()> { + ) -> PopApiResult<()> { build_dispatch(SET_METADATA) .input::<(TokenId, Vec, Vec, u8)>() - .output::, true>() + .output::, true>() .handle_error_code::() .call(&(token, name, symbol, decimals)) } @@ -320,10 +329,10 @@ pub mod management { /// # Parameters /// - `token` - The token to update #[inline] - pub fn clear_metadata(token: TokenId) -> Result<()> { + pub fn clear_metadata(token: TokenId) -> PopApiResult<()> { build_dispatch(CLEAR_METADATA) .input::() - .output::, true>() + .output::, true>() .handle_error_code::() .call(&(token)) } @@ -333,10 +342,10 @@ pub mod management { /// # Parameters /// - `token` - The token. #[inline] - pub fn token_exists(token: TokenId) -> Result { + pub fn token_exists(token: TokenId) -> PopApiResult { build_read_state(TOKEN_EXISTS) .input::() - .output::, true>() + .output::, true>() .handle_error_code::() .call(&(token)) } From 24afd1522dab8c34d97c395327ee72ba38f0f012 Mon Sep 17 00:00:00 2001 From: chungquantin <56880684+chungquantin@users.noreply.github.com> Date: Wed, 18 Sep 2024 17:59:19 +0800 Subject: [PATCH 092/112] test: psp22error --- pop-api/src/v0/fungibles/tests.rs | 44 ++++++++++++++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) diff --git a/pop-api/src/v0/fungibles/tests.rs b/pop-api/src/v0/fungibles/tests.rs index 128cf4cb..55b832e4 100644 --- a/pop-api/src/v0/fungibles/tests.rs +++ b/pop-api/src/v0/fungibles/tests.rs @@ -1,4 +1,4 @@ -use super::FungiblesError; +use super::{FungiblesError, PSP22Error}; use crate::{ constants::{ASSETS, BALANCES}, primitives::{ @@ -24,6 +24,11 @@ fn into_fungibles_error(error: Error) -> FungiblesError { status_code.into() } +fn into_psp22_error(error: Error) -> PSP22Error { + let status_code: StatusCode = error_into_status_code(error); + status_code.into() +} + // If we ever want to change the conversion from bytes to `u32`. #[test] fn status_code_vs_encoded() { @@ -97,3 +102,40 @@ fn converting_status_code_into_fungibles_error_works() { FungiblesError::NotLive ); } + +#[test] +fn converting_status_code_into_psp22_error_works() { + let other_errors = vec![ + Other, + CannotLookup, + BadOrigin, + // `ModuleError` other than assets module. + Module { index: 2, error: [5, 0] }, + ConsumerRemaining, + NoProviders, + TooManyConsumers, + Token(OnlyProvider), + Arithmetic(Overflow), + Transactional(NoLayer), + Exhausted, + Corruption, + Unavailable, + RootNotAllowed, + Unknown { dispatch_error_index: 5, error_index: 5, error: 1 }, + DecodingFailed, + ]; + for error in other_errors { + let status_code: StatusCode = error_into_status_code(error); + let fungibles_error: PSP22Error = status_code.into(); + assert_eq!(fungibles_error, PSP22Error::Custom(String::from("Other"))) + } + + assert_eq!( + into_psp22_error(Module { index: ASSETS, error: [3, 0] }), + PSP22Error::Custom(String::from("Unknown")) + ); + assert_eq!( + into_psp22_error(Module { index: ASSETS, error: [7, 0] }), + PSP22Error::InsufficientAllowance + ); +} From 8ecf6d955ce88eae329268099be803be85dd2859 Mon Sep 17 00:00:00 2001 From: chungquantin <56880684+chungquantin@users.noreply.github.com> Date: Wed, 18 Sep 2024 18:27:19 +0800 Subject: [PATCH 093/112] fix: missing String --- pop-api/src/v0/fungibles/errors.rs | 1 + pop-api/src/v0/fungibles/tests.rs | 1 + 2 files changed, 2 insertions(+) diff --git a/pop-api/src/v0/fungibles/errors.rs b/pop-api/src/v0/fungibles/errors.rs index 872e8d64..486077c8 100644 --- a/pop-api/src/v0/fungibles/errors.rs +++ b/pop-api/src/v0/fungibles/errors.rs @@ -1,4 +1,5 @@ use super::*; +use ink::prelude::string::String; /// Represents various errors related to fungible tokens. /// diff --git a/pop-api/src/v0/fungibles/tests.rs b/pop-api/src/v0/fungibles/tests.rs index 55b832e4..bac16335 100644 --- a/pop-api/src/v0/fungibles/tests.rs +++ b/pop-api/src/v0/fungibles/tests.rs @@ -9,6 +9,7 @@ use crate::{ }, StatusCode, }; +use ink::prelude::string::String; use ink::scale::{Decode, Encode}; fn error_into_status_code(error: Error) -> StatusCode { From 6f521f4f14ce4512f1fd778ebdbaea8344df945d Mon Sep 17 00:00:00 2001 From: chungquantin <56880684+chungquantin@users.noreply.github.com> Date: Thu, 19 Sep 2024 09:41:13 +0800 Subject: [PATCH 094/112] fix: resolve comments --- pop-api/src/v0/fungibles/errors.rs | 149 ++++++++++++++++++ pop-api/src/v0/fungibles/events.rs | 20 +-- pop-api/src/v0/fungibles/mod.rs | 103 ++++++------ pop-api/src/v0/fungibles/tests.rs | 142 ----------------- .../v0/fungibles/{interfaces.rs => traits.rs} | 52 +----- 5 files changed, 211 insertions(+), 255 deletions(-) delete mode 100644 pop-api/src/v0/fungibles/tests.rs rename pop-api/src/v0/fungibles/{interfaces.rs => traits.rs} (68%) diff --git a/pop-api/src/v0/fungibles/errors.rs b/pop-api/src/v0/fungibles/errors.rs index 486077c8..c8dae082 100644 --- a/pop-api/src/v0/fungibles/errors.rs +++ b/pop-api/src/v0/fungibles/errors.rs @@ -11,6 +11,7 @@ use ink::prelude::string::String; /// operations. The `Other` variant serves as a catch-all for any unexpected errors. For more /// detailed debugging, the `Other` variant can be converted into the richer `Error` type defined in /// the primitives crate. +/// NOTE: The `FungiblesError` is WIP #[derive(Debug, PartialEq, Eq)] #[ink::scale_derive(Encode, Decode, TypeInfo)] pub enum FungiblesError { @@ -64,6 +65,7 @@ impl From for FungiblesError { } /// The PSP22 error. +/// TODO: Issue https://github.com/r0gue-io/pop-node/issues/298 #[derive(Debug, PartialEq, Eq)] #[ink::scale_derive(Encode, Decode, TypeInfo)] pub enum PSP22Error { @@ -92,3 +94,150 @@ impl From for PSP22Error { } } } + +#[cfg(test)] +mod tests { + use super::{FungiblesError, PSP22Error}; + use crate::{ + constants::{ASSETS, BALANCES}, + primitives::{ + ArithmeticError::*, + Error::{self, *}, + TokenError::*, + TransactionalError::*, + }, + StatusCode, + }; + use ink::prelude::string::String; + use ink::scale::{Decode, Encode}; + + fn error_into_status_code(error: Error) -> StatusCode { + let mut encoded_error = error.encode(); + encoded_error.resize(4, 0); + let value = u32::from_le_bytes( + encoded_error.try_into().expect("qed, resized to 4 bytes line above"), + ); + value.into() + } + + fn into_fungibles_error(error: Error) -> FungiblesError { + let status_code: StatusCode = error_into_status_code(error); + status_code.into() + } + + fn into_psp22_error(error: Error) -> PSP22Error { + let status_code: StatusCode = error_into_status_code(error); + status_code.into() + } + + // If we ever want to change the conversion from bytes to `u32`. + #[test] + fn status_code_vs_encoded() { + assert_eq!(u32::decode(&mut &[3u8, 10, 2, 0][..]).unwrap(), 133635u32); + assert_eq!(u32::decode(&mut &[3u8, 52, 0, 0][..]).unwrap(), 13315u32); + assert_eq!(u32::decode(&mut &[3u8, 52, 1, 0][..]).unwrap(), 78851u32); + assert_eq!(u32::decode(&mut &[3u8, 52, 2, 0][..]).unwrap(), 144387u32); + assert_eq!(u32::decode(&mut &[3u8, 52, 3, 0][..]).unwrap(), 209923u32); + assert_eq!(u32::decode(&mut &[3u8, 52, 5, 0][..]).unwrap(), 340995u32); + assert_eq!(u32::decode(&mut &[3u8, 52, 7, 0][..]).unwrap(), 472067u32); + assert_eq!(u32::decode(&mut &[3u8, 52, 10, 0][..]).unwrap(), 668675u32); + } + + #[test] + fn converting_status_code_into_fungibles_error_works() { + let other_errors = vec![ + Other, + CannotLookup, + BadOrigin, + // `ModuleError` other than assets module. + Module { index: 2, error: [5, 0] }, + ConsumerRemaining, + NoProviders, + TooManyConsumers, + Token(OnlyProvider), + Arithmetic(Overflow), + Transactional(NoLayer), + Exhausted, + Corruption, + Unavailable, + RootNotAllowed, + Unknown { dispatch_error_index: 5, error_index: 5, error: 1 }, + DecodingFailed, + ]; + for error in other_errors { + let status_code: StatusCode = error_into_status_code(error); + let fungibles_error: FungiblesError = status_code.into(); + assert_eq!(fungibles_error, FungiblesError::Other(status_code)) + } + + assert_eq!( + into_fungibles_error(Module { index: BALANCES, error: [2, 0] }), + FungiblesError::NoBalance + ); + assert_eq!( + into_fungibles_error(Module { index: ASSETS, error: [0, 0] }), + FungiblesError::NoAccount + ); + assert_eq!( + into_fungibles_error(Module { index: ASSETS, error: [1, 0] }), + FungiblesError::NoPermission + ); + assert_eq!( + into_fungibles_error(Module { index: ASSETS, error: [2, 0] }), + FungiblesError::Unknown + ); + assert_eq!( + into_fungibles_error(Module { index: ASSETS, error: [3, 0] }), + FungiblesError::InUse + ); + assert_eq!( + into_fungibles_error(Module { index: ASSETS, error: [5, 0] }), + FungiblesError::MinBalanceZero + ); + assert_eq!( + into_fungibles_error(Module { index: ASSETS, error: [7, 0] }), + FungiblesError::InsufficientAllowance + ); + assert_eq!( + into_fungibles_error(Module { index: ASSETS, error: [10, 0] }), + FungiblesError::NotLive + ); + } + + #[test] + fn converting_status_code_into_psp22_error_works() { + let other_errors = vec![ + Other, + CannotLookup, + BadOrigin, + // `ModuleError` other than assets module. + Module { index: 2, error: [5, 0] }, + ConsumerRemaining, + NoProviders, + TooManyConsumers, + Token(OnlyProvider), + Arithmetic(Overflow), + Transactional(NoLayer), + Exhausted, + Corruption, + Unavailable, + RootNotAllowed, + Unknown { dispatch_error_index: 5, error_index: 5, error: 1 }, + DecodingFailed, + ]; + for error in other_errors { + let status_code: StatusCode = error_into_status_code(error); + let fungibles_error: PSP22Error = status_code.into(); + assert_eq!(fungibles_error, PSP22Error::Custom(String::from("Other"))) + } + + assert_eq!( + into_psp22_error(Module { index: ASSETS, error: [3, 0] }), + PSP22Error::Custom(String::from("Unknown")) + ); + assert_eq!( + into_psp22_error(Module { index: ASSETS, error: [7, 0] }), + PSP22Error::InsufficientAllowance + ); + } +} diff --git a/pop-api/src/v0/fungibles/events.rs b/pop-api/src/v0/fungibles/events.rs index b0639e10..a018ac59 100644 --- a/pop-api/src/v0/fungibles/events.rs +++ b/pop-api/src/v0/fungibles/events.rs @@ -1,15 +1,16 @@ -/// A set of events for use in smart contracts interacting with the fungibles API. -/// -/// The `Transfer` and `Approval` events conform to the PSP-22 standard. The other events -/// (`Create`, `StartDestroy`, `SetMetadata`, `ClearMetadata`) are provided for convenience. -/// -/// These events are not emitted by the API itself but can be used in your contracts to -/// track token operations. Be mindful of the costs associated with emitting events. -/// -/// For more details, refer to [ink! events](https://use.ink/basics/events). +//! A set of events for use in smart contracts interacting with the fungibles API. +//! +//! The `Transfer` and `Approval` events conform to the PSP-22 standard. The other events +//! (`Create`, `StartDestroy`, `SetMetadata`, `ClearMetadata`) are provided for convenience. +//! +//! These events are not emitted by the API itself but can be used in your contracts to +//! track token operations. Be mindful of the costs associated with emitting events. +//! +//! For more details, refer to [ink! events](https://use.ink/basics/events). use super::*; /// Event emitted when allowance by `owner` to `spender` changes. +// Differing style: event name abides by the PSP22 standard. #[ink::event] pub struct Approval { /// The owner providing the allowance. @@ -23,6 +24,7 @@ pub struct Approval { } /// Event emitted when transfer of tokens occurs. +// Differing style: event name abides by the PSP22 standard. #[ink::event] pub struct Transfer { /// The source of the transfer. `None` when minting. diff --git a/pop-api/src/v0/fungibles/mod.rs b/pop-api/src/v0/fungibles/mod.rs index da731819..e864f690 100644 --- a/pop-api/src/v0/fungibles/mod.rs +++ b/pop-api/src/v0/fungibles/mod.rs @@ -1,15 +1,10 @@ //! The `fungibles` module provides an API for interacting and managing fungible tokens. //! -//! The API includes the following interfaces: +//! The API includes the following traits: //! 1. PSP-22 //! 2. PSP-22 Metadata //! 3. Management //! 4. PSP-22 Mintable & Burnable -pub mod errors; -pub mod events; -pub mod interfaces; -#[cfg(test)] -mod tests; use crate::{ constants::{ASSETS, BALANCES, FUNGIBLES}, @@ -17,60 +12,18 @@ use crate::{ ChainExtensionMethodApi, StatusCode, }; use constants::*; -use core::result::Result; pub use errors::*; pub use events::*; use ink::prelude::vec::Vec; -pub use interfaces::*; pub use management::*; pub use metadata::*; +pub use traits::*; -pub type PSP22Result = Result; -pub type PopApiResult = Result; - -// Helper method to build a dispatch call. -// -// Parameters: -// - 'dispatchable': The index of the dispatchable function within the module. -fn build_dispatch(dispatchable: u8) -> ChainExtensionMethodApi { - crate::v0::build_dispatch(FUNGIBLES, dispatchable) -} - -// Helper method to build a call to read state. -// -// Parameters: -// - 'state_query': The index of the runtime state query. -fn build_read_state(state_query: u8) -> ChainExtensionMethodApi { - crate::v0::build_read_state(FUNGIBLES, state_query) -} - -mod constants { - /// 1. PSP-22 Interface: - pub(super) const TOTAL_SUPPLY: u8 = 0; - pub(super) const BALANCE_OF: u8 = 1; - pub(super) const ALLOWANCE: u8 = 2; - pub(super) const TRANSFER: u8 = 3; - pub(super) const TRANSFER_FROM: u8 = 4; - pub(super) const APPROVE: u8 = 5; - pub(super) const INCREASE_ALLOWANCE: u8 = 6; - pub(super) const DECREASE_ALLOWANCE: u8 = 7; - - /// 2. PSP-22 Metadata Interface: - pub(super) const TOKEN_NAME: u8 = 8; - pub(super) const TOKEN_SYMBOL: u8 = 9; - pub(super) const TOKEN_DECIMALS: u8 = 10; +pub mod errors; +pub mod events; +pub mod traits; - /// 3. Asset Management: - pub(super) const CREATE: u8 = 11; - pub(super) const START_DESTROY: u8 = 12; - pub(super) const SET_METADATA: u8 = 16; - pub(super) const CLEAR_METADATA: u8 = 17; - pub(super) const TOKEN_EXISTS: u8 = 18; - - /// 4. PSP-22 Mintable & Burnable interface: - pub(super) const MINT: u8 = 19; - pub(super) const BURN: u8 = 20; -} +pub type PSP22Result = core::result::Result; /// Returns the total token supply for a specified token. /// @@ -350,3 +303,47 @@ pub mod management { .call(&(token)) } } + +mod constants { + /// 1. PSP-22 Interface: + pub(super) const TOTAL_SUPPLY: u8 = 0; + pub(super) const BALANCE_OF: u8 = 1; + pub(super) const ALLOWANCE: u8 = 2; + pub(super) const TRANSFER: u8 = 3; + pub(super) const TRANSFER_FROM: u8 = 4; + pub(super) const APPROVE: u8 = 5; + pub(super) const INCREASE_ALLOWANCE: u8 = 6; + pub(super) const DECREASE_ALLOWANCE: u8 = 7; + + /// 2. PSP-22 Metadata Interface: + pub(super) const TOKEN_NAME: u8 = 8; + pub(super) const TOKEN_SYMBOL: u8 = 9; + pub(super) const TOKEN_DECIMALS: u8 = 10; + + /// 3. Asset Management: + pub(super) const CREATE: u8 = 11; + pub(super) const START_DESTROY: u8 = 12; + pub(super) const SET_METADATA: u8 = 16; + pub(super) const CLEAR_METADATA: u8 = 17; + pub(super) const TOKEN_EXISTS: u8 = 18; + + /// 4. PSP-22 Mintable & Burnable interface: + pub(super) const MINT: u8 = 19; + pub(super) const BURN: u8 = 20; +} + +// Helper method to build a dispatch call. +// +// Parameters: +// - 'dispatchable': The index of the dispatchable function within the module. +fn build_dispatch(dispatchable: u8) -> ChainExtensionMethodApi { + crate::v0::build_dispatch(FUNGIBLES, dispatchable) +} + +// Helper method to build a call to read state. +// +// Parameters: +// - 'state_query': The index of the runtime state query. +fn build_read_state(state_query: u8) -> ChainExtensionMethodApi { + crate::v0::build_read_state(FUNGIBLES, state_query) +} diff --git a/pop-api/src/v0/fungibles/tests.rs b/pop-api/src/v0/fungibles/tests.rs deleted file mode 100644 index bac16335..00000000 --- a/pop-api/src/v0/fungibles/tests.rs +++ /dev/null @@ -1,142 +0,0 @@ -use super::{FungiblesError, PSP22Error}; -use crate::{ - constants::{ASSETS, BALANCES}, - primitives::{ - ArithmeticError::*, - Error::{self, *}, - TokenError::*, - TransactionalError::*, - }, - StatusCode, -}; -use ink::prelude::string::String; -use ink::scale::{Decode, Encode}; - -fn error_into_status_code(error: Error) -> StatusCode { - let mut encoded_error = error.encode(); - encoded_error.resize(4, 0); - let value = - u32::from_le_bytes(encoded_error.try_into().expect("qed, resized to 4 bytes line above")); - value.into() -} - -fn into_fungibles_error(error: Error) -> FungiblesError { - let status_code: StatusCode = error_into_status_code(error); - status_code.into() -} - -fn into_psp22_error(error: Error) -> PSP22Error { - let status_code: StatusCode = error_into_status_code(error); - status_code.into() -} - -// If we ever want to change the conversion from bytes to `u32`. -#[test] -fn status_code_vs_encoded() { - assert_eq!(u32::decode(&mut &[3u8, 10, 2, 0][..]).unwrap(), 133635u32); - assert_eq!(u32::decode(&mut &[3u8, 52, 0, 0][..]).unwrap(), 13315u32); - assert_eq!(u32::decode(&mut &[3u8, 52, 1, 0][..]).unwrap(), 78851u32); - assert_eq!(u32::decode(&mut &[3u8, 52, 2, 0][..]).unwrap(), 144387u32); - assert_eq!(u32::decode(&mut &[3u8, 52, 3, 0][..]).unwrap(), 209923u32); - assert_eq!(u32::decode(&mut &[3u8, 52, 5, 0][..]).unwrap(), 340995u32); - assert_eq!(u32::decode(&mut &[3u8, 52, 7, 0][..]).unwrap(), 472067u32); - assert_eq!(u32::decode(&mut &[3u8, 52, 10, 0][..]).unwrap(), 668675u32); -} - -#[test] -fn converting_status_code_into_fungibles_error_works() { - let other_errors = vec![ - Other, - CannotLookup, - BadOrigin, - // `ModuleError` other than assets module. - Module { index: 2, error: [5, 0] }, - ConsumerRemaining, - NoProviders, - TooManyConsumers, - Token(OnlyProvider), - Arithmetic(Overflow), - Transactional(NoLayer), - Exhausted, - Corruption, - Unavailable, - RootNotAllowed, - Unknown { dispatch_error_index: 5, error_index: 5, error: 1 }, - DecodingFailed, - ]; - for error in other_errors { - let status_code: StatusCode = error_into_status_code(error); - let fungibles_error: FungiblesError = status_code.into(); - assert_eq!(fungibles_error, FungiblesError::Other(status_code)) - } - - assert_eq!( - into_fungibles_error(Module { index: BALANCES, error: [2, 0] }), - FungiblesError::NoBalance - ); - assert_eq!( - into_fungibles_error(Module { index: ASSETS, error: [0, 0] }), - FungiblesError::NoAccount - ); - assert_eq!( - into_fungibles_error(Module { index: ASSETS, error: [1, 0] }), - FungiblesError::NoPermission - ); - assert_eq!( - into_fungibles_error(Module { index: ASSETS, error: [2, 0] }), - FungiblesError::Unknown - ); - assert_eq!( - into_fungibles_error(Module { index: ASSETS, error: [3, 0] }), - FungiblesError::InUse - ); - assert_eq!( - into_fungibles_error(Module { index: ASSETS, error: [5, 0] }), - FungiblesError::MinBalanceZero - ); - assert_eq!( - into_fungibles_error(Module { index: ASSETS, error: [7, 0] }), - FungiblesError::InsufficientAllowance - ); - assert_eq!( - into_fungibles_error(Module { index: ASSETS, error: [10, 0] }), - FungiblesError::NotLive - ); -} - -#[test] -fn converting_status_code_into_psp22_error_works() { - let other_errors = vec![ - Other, - CannotLookup, - BadOrigin, - // `ModuleError` other than assets module. - Module { index: 2, error: [5, 0] }, - ConsumerRemaining, - NoProviders, - TooManyConsumers, - Token(OnlyProvider), - Arithmetic(Overflow), - Transactional(NoLayer), - Exhausted, - Corruption, - Unavailable, - RootNotAllowed, - Unknown { dispatch_error_index: 5, error_index: 5, error: 1 }, - DecodingFailed, - ]; - for error in other_errors { - let status_code: StatusCode = error_into_status_code(error); - let fungibles_error: PSP22Error = status_code.into(); - assert_eq!(fungibles_error, PSP22Error::Custom(String::from("Other"))) - } - - assert_eq!( - into_psp22_error(Module { index: ASSETS, error: [3, 0] }), - PSP22Error::Custom(String::from("Unknown")) - ); - assert_eq!( - into_psp22_error(Module { index: ASSETS, error: [7, 0] }), - PSP22Error::InsufficientAllowance - ); -} diff --git a/pop-api/src/v0/fungibles/interfaces.rs b/pop-api/src/v0/fungibles/traits.rs similarity index 68% rename from pop-api/src/v0/fungibles/interfaces.rs rename to pop-api/src/v0/fungibles/traits.rs index a4b48a4c..74ef742a 100644 --- a/pop-api/src/v0/fungibles/interfaces.rs +++ b/pop-api/src/v0/fungibles/traits.rs @@ -38,6 +38,7 @@ pub trait Psp22 { /// - `from` - The account from which the token balance will be withdrawn. /// - `to` - The recipient account. /// - `value` - The number of tokens to transfer. + /// - `data` - Additional data with unspecified format. #[ink(message)] fn transfer_from( &mut self, @@ -74,57 +75,6 @@ pub trait Psp22 { fn decrease_allowance(&mut self, spender: AccountId, value: Balance) -> PSP22Result<()>; } -/// The PSP22 Metadata trait. -#[ink::trait_definition] -pub trait Management { - /// Creates a new token with the specified `id`, assigns `admin` as the administrator, - /// and sets a minimum balance requirement. - /// - /// # Parameters - /// - `id`: The unique identifier for the token to be created. - /// - `admin`: The account that will have administrative privileges over the token. - /// - `min_balance`: The minimum balance required to hold the token. - #[ink(message)] - fn create(&mut self, id: TokenId, admin: AccountId, min_balance: Balance) -> PSP22Result<()>; - - /// Initiates the process to destroy the specified `token`. - /// - /// # Parameters - /// - `token`: The identifier of the token to be destroyed. - #[ink(message)] - fn start_destroy(&mut self, token: TokenId) -> PSP22Result<()>; - - /// Sets metadata for the specified `token`, including its name, symbol, and decimal places. - /// - /// # Parameters - /// - `token`: The identifier of the token to set metadata for. - /// - `name`: The name of the token. - /// - `symbol`: The symbol representing the token. - /// - `decimals`: The number of decimal places the token uses. - #[ink(message)] - fn set_metadata( - &mut self, - token: TokenId, - name: Vec, - symbol: Vec, - decimals: u8, - ) -> PSP22Result<()>; - - /// Clears the metadata for the specified `token`. - /// - /// # Parameters - /// - `token`: The identifier of the token to clear metadata for. - #[ink(message)] - fn clear_metadata(&mut self, token: TokenId) -> PSP22Result<()>; - - /// Checks whether a token with the specified `token` identifier exists. - /// - /// # Parameters - /// - `token`: The identifier of the token to check for existence. - #[ink(message)] - fn token_exists(&self, token: TokenId) -> PSP22Result; -} - /// The PSP22 Metadata trait. #[ink::trait_definition] pub trait Psp22Metadata { From 7ce5d52e29f031949cce67e41db4be77ef552068 Mon Sep 17 00:00:00 2001 From: chungquantin <56880684+chungquantin@users.noreply.github.com> Date: Thu, 19 Sep 2024 09:46:14 +0800 Subject: [PATCH 095/112] fix: add mod comment --- pop-api/src/v0/fungibles/errors.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/pop-api/src/v0/fungibles/errors.rs b/pop-api/src/v0/fungibles/errors.rs index c8dae082..30d98285 100644 --- a/pop-api/src/v0/fungibles/errors.rs +++ b/pop-api/src/v0/fungibles/errors.rs @@ -1,3 +1,4 @@ +//! A set of errors for use in smart contracts to manage the returned errors. use super::*; use ink::prelude::string::String; From b29cf17b10d731b5081811cf6d08de93bf7f53e0 Mon Sep 17 00:00:00 2001 From: chungquantin <56880684+chungquantin@users.noreply.github.com> Date: Thu, 19 Sep 2024 21:37:49 +0700 Subject: [PATCH 096/112] fix: result type --- pop-api/src/v0/fungibles/mod.rs | 79 +++++++++++++++------------------ 1 file changed, 37 insertions(+), 42 deletions(-) diff --git a/pop-api/src/v0/fungibles/mod.rs b/pop-api/src/v0/fungibles/mod.rs index e864f690..fe6c685e 100644 --- a/pop-api/src/v0/fungibles/mod.rs +++ b/pop-api/src/v0/fungibles/mod.rs @@ -9,7 +9,7 @@ use crate::{ constants::{ASSETS, BALANCES, FUNGIBLES}, primitives::{AccountId, Balance, TokenId}, - ChainExtensionMethodApi, StatusCode, + ChainExtensionMethodApi, Result, StatusCode, }; use constants::*; pub use errors::*; @@ -30,10 +30,10 @@ pub type PSP22Result = core::result::Result; /// # Parameters /// - `token` - The token. #[inline] -pub fn total_supply(token: TokenId) -> PopApiResult { +pub fn total_supply(token: TokenId) -> Result { build_read_state(TOTAL_SUPPLY) .input::() - .output::, true>() + .output::, true>() .handle_error_code::() .call(&(token)) } @@ -45,10 +45,10 @@ pub fn total_supply(token: TokenId) -> PopApiResult { /// - `token` - The token. /// - `owner` - The account whose balance is being queried. #[inline] -pub fn balance_of(token: TokenId, owner: AccountId) -> PopApiResult { +pub fn balance_of(token: TokenId, owner: AccountId) -> Result { build_read_state(BALANCE_OF) .input::<(TokenId, AccountId)>() - .output::, true>() + .output::, true>() .handle_error_code::() .call(&(token, owner)) } @@ -61,10 +61,10 @@ pub fn balance_of(token: TokenId, owner: AccountId) -> PopApiResult { /// - `owner` - The account that owns the tokens. /// - `spender` - The account that is allowed to spend the tokens. #[inline] -pub fn allowance(token: TokenId, owner: AccountId, spender: AccountId) -> PopApiResult { +pub fn allowance(token: TokenId, owner: AccountId, spender: AccountId) -> Result { build_read_state(ALLOWANCE) .input::<(TokenId, AccountId, AccountId)>() - .output::, true>() + .output::, true>() .handle_error_code::() .call(&(token, owner, spender)) } @@ -76,10 +76,10 @@ pub fn allowance(token: TokenId, owner: AccountId, spender: AccountId) -> PopApi /// - `to` - The recipient account. /// - `value` - The number of tokens to transfer. #[inline] -pub fn transfer(token: TokenId, to: AccountId, value: Balance) -> PopApiResult<()> { +pub fn transfer(token: TokenId, to: AccountId, value: Balance) -> Result<()> { build_dispatch(TRANSFER) .input::<(TokenId, AccountId, Balance)>() - .output::, true>() + .output::, true>() .handle_error_code::() .call(&(token, to, value)) } @@ -92,15 +92,10 @@ pub fn transfer(token: TokenId, to: AccountId, value: Balance) -> PopApiResult<( /// - `to` - The recipient account. /// - `value` - The number of tokens to transfer. #[inline] -pub fn transfer_from( - token: TokenId, - from: AccountId, - to: AccountId, - value: Balance, -) -> PopApiResult<()> { +pub fn transfer_from(token: TokenId, from: AccountId, to: AccountId, value: Balance) -> Result<()> { build_dispatch(TRANSFER_FROM) .input::<(TokenId, AccountId, AccountId, Balance)>() - .output::, true>() + .output::, true>() .handle_error_code::() .call(&(token, from, to, value)) } @@ -112,10 +107,10 @@ pub fn transfer_from( /// - `spender` - The account that is allowed to spend the tokens. /// - `value` - The number of tokens to approve. #[inline] -pub fn approve(token: TokenId, spender: AccountId, value: Balance) -> PopApiResult<()> { +pub fn approve(token: TokenId, spender: AccountId, value: Balance) -> Result<()> { build_dispatch(APPROVE) .input::<(TokenId, AccountId, Balance)>() - .output::, true>() + .output::, true>() .handle_error_code::() .call(&(token, spender, value)) } @@ -127,10 +122,10 @@ pub fn approve(token: TokenId, spender: AccountId, value: Balance) -> PopApiResu /// - `spender` - The account that is allowed to spend the tokens. /// - `value` - The number of tokens to increase the allowance by. #[inline] -pub fn increase_allowance(token: TokenId, spender: AccountId, value: Balance) -> PopApiResult<()> { +pub fn increase_allowance(token: TokenId, spender: AccountId, value: Balance) -> Result<()> { build_dispatch(INCREASE_ALLOWANCE) .input::<(TokenId, AccountId, Balance)>() - .output::, true>() + .output::, true>() .handle_error_code::() .call(&(token, spender, value)) } @@ -142,10 +137,10 @@ pub fn increase_allowance(token: TokenId, spender: AccountId, value: Balance) -> /// - `spender` - The account that is allowed to spend the tokens. /// - `value` - The number of tokens to decrease the allowance by. #[inline] -pub fn decrease_allowance(token: TokenId, spender: AccountId, value: Balance) -> PopApiResult<()> { +pub fn decrease_allowance(token: TokenId, spender: AccountId, value: Balance) -> Result<()> { build_dispatch(DECREASE_ALLOWANCE) .input::<(TokenId, AccountId, Balance)>() - .output::, true>() + .output::, true>() .handle_error_code::() .call(&(token, spender, value)) } @@ -157,10 +152,10 @@ pub fn decrease_allowance(token: TokenId, spender: AccountId, value: Balance) -> /// - `account` - The account to be credited with the created tokens. /// - `value` - The number of tokens to mint. #[inline] -pub fn mint(token: TokenId, account: AccountId, value: Balance) -> PopApiResult<()> { +pub fn mint(token: TokenId, account: AccountId, value: Balance) -> Result<()> { build_dispatch(MINT) .input::<(TokenId, AccountId, Balance)>() - .output::, true>() + .output::, true>() .handle_error_code::() .call(&(token, account, value)) } @@ -172,10 +167,10 @@ pub fn mint(token: TokenId, account: AccountId, value: Balance) -> PopApiResult< /// - `account` - The account from which the tokens will be destroyed. /// - `value` - The number of tokens to destroy. #[inline] -pub fn burn(token: TokenId, account: AccountId, value: Balance) -> PopApiResult<()> { +pub fn burn(token: TokenId, account: AccountId, value: Balance) -> Result<()> { build_dispatch(BURN) .input::<(TokenId, AccountId, Balance)>() - .output::, true>() + .output::, true>() .handle_error_code::() .call(&(token, account, value)) } @@ -189,10 +184,10 @@ pub mod metadata { /// # Parameters /// - `token` - The token. #[inline] - pub fn token_name(token: TokenId) -> PopApiResult> { + pub fn token_name(token: TokenId) -> Result> { build_read_state(TOKEN_NAME) .input::() - .output::>, true>() + .output::>, true>() .handle_error_code::() .call(&(token)) } @@ -202,10 +197,10 @@ pub mod metadata { /// # Parameters /// - `token` - The token. #[inline] - pub fn token_symbol(token: TokenId) -> PopApiResult> { + pub fn token_symbol(token: TokenId) -> Result> { build_read_state(TOKEN_SYMBOL) .input::() - .output::>, true>() + .output::>, true>() .handle_error_code::() .call(&(token)) } @@ -215,10 +210,10 @@ pub mod metadata { /// # Parameters /// - `token` - The token. #[inline] - pub fn token_decimals(token: TokenId) -> PopApiResult { + pub fn token_decimals(token: TokenId) -> Result { build_read_state(TOKEN_DECIMALS) .input::() - .output::, true>() + .output::, true>() .handle_error_code::() .call(&(token)) } @@ -235,10 +230,10 @@ pub mod management { /// - `admin` - The account that will administer the token. /// - `min_balance` - The minimum balance required for accounts holding this token. #[inline] - pub fn create(id: TokenId, admin: AccountId, min_balance: Balance) -> PopApiResult<()> { + pub fn create(id: TokenId, admin: AccountId, min_balance: Balance) -> Result<()> { build_dispatch(CREATE) .input::<(TokenId, AccountId, Balance)>() - .output::, true>() + .output::, true>() .handle_error_code::() .call(&(id, admin, min_balance)) } @@ -248,10 +243,10 @@ pub mod management { /// # Parameters /// - `token` - The token to be destroyed. #[inline] - pub fn start_destroy(token: TokenId) -> PopApiResult<()> { + pub fn start_destroy(token: TokenId) -> Result<()> { build_dispatch(START_DESTROY) .input::() - .output::, true>() + .output::, true>() .handle_error_code::() .call(&(token)) } @@ -269,10 +264,10 @@ pub mod management { name: Vec, symbol: Vec, decimals: u8, - ) -> PopApiResult<()> { + ) -> Result<()> { build_dispatch(SET_METADATA) .input::<(TokenId, Vec, Vec, u8)>() - .output::, true>() + .output::, true>() .handle_error_code::() .call(&(token, name, symbol, decimals)) } @@ -282,10 +277,10 @@ pub mod management { /// # Parameters /// - `token` - The token to update #[inline] - pub fn clear_metadata(token: TokenId) -> PopApiResult<()> { + pub fn clear_metadata(token: TokenId) -> Result<()> { build_dispatch(CLEAR_METADATA) .input::() - .output::, true>() + .output::, true>() .handle_error_code::() .call(&(token)) } @@ -295,10 +290,10 @@ pub mod management { /// # Parameters /// - `token` - The token. #[inline] - pub fn token_exists(token: TokenId) -> PopApiResult { + pub fn token_exists(token: TokenId) -> Result { build_read_state(TOKEN_EXISTS) .input::() - .output::, true>() + .output::, true>() .handle_error_code::() .call(&(token)) } From 933c62e80491f291b07812993e11fcd7c346eb56 Mon Sep 17 00:00:00 2001 From: chungquantin <56880684+chungquantin@users.noreply.github.com> Date: Thu, 19 Sep 2024 22:22:09 +0700 Subject: [PATCH 097/112] fix: update PSP22Metadata --- pop-api/src/v0/fungibles/traits.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pop-api/src/v0/fungibles/traits.rs b/pop-api/src/v0/fungibles/traits.rs index 74ef742a..01f25710 100644 --- a/pop-api/src/v0/fungibles/traits.rs +++ b/pop-api/src/v0/fungibles/traits.rs @@ -80,11 +80,11 @@ pub trait Psp22 { pub trait Psp22Metadata { /// Returns the token name. #[ink(message)] - fn token_name(&self) -> Option>; + fn token_name(&self) -> Option; /// Returns the token symbol. #[ink(message)] - fn token_symbol(&self) -> Option>; + fn token_symbol(&self) -> Option; /// Returns the token decimals. #[ink(message)] From de809068c982ae0a256999306832acd44f3c388d Mon Sep 17 00:00:00 2001 From: chungquantin <56880684+chungquantin@users.noreply.github.com> Date: Thu, 19 Sep 2024 22:25:06 +0700 Subject: [PATCH 098/112] fix: add comment for Psp22 trait --- pop-api/src/v0/fungibles/traits.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/pop-api/src/v0/fungibles/traits.rs b/pop-api/src/v0/fungibles/traits.rs index 01f25710..0d9d2d29 100644 --- a/pop-api/src/v0/fungibles/traits.rs +++ b/pop-api/src/v0/fungibles/traits.rs @@ -1,5 +1,6 @@ use super::*; +/// The PSP22 trait. #[ink::trait_definition] pub trait Psp22 { /// Returns the total token supply. From 8717adb1fb7376888e566d0aedaa58563f7daac6 Mon Sep 17 00:00:00 2001 From: chungquantin <56880684+chungquantin@users.noreply.github.com> Date: Thu, 19 Sep 2024 23:13:42 +0700 Subject: [PATCH 099/112] fix: resolve comments --- pop-api/src/v0/fungibles/errors.rs | 4 ++-- pop-api/src/v0/fungibles/events.rs | 1 + pop-api/src/v0/fungibles/mod.rs | 10 ++++------ pop-api/src/v0/fungibles/traits.rs | 15 ++++++++------- 4 files changed, 15 insertions(+), 15 deletions(-) diff --git a/pop-api/src/v0/fungibles/errors.rs b/pop-api/src/v0/fungibles/errors.rs index 30d98285..e76c4bcc 100644 --- a/pop-api/src/v0/fungibles/errors.rs +++ b/pop-api/src/v0/fungibles/errors.rs @@ -1,4 +1,4 @@ -//! A set of errors for use in smart contracts to manage the returned errors. +//! A set of errors for use in smart contracts that interact with the fungibles api. This includes errors compliant to standards. use super::*; use ink::prelude::string::String; @@ -66,7 +66,7 @@ impl From for FungiblesError { } /// The PSP22 error. -/// TODO: Issue https://github.com/r0gue-io/pop-node/issues/298 +// TODO: Issue https://github.com/r0gue-io/pop-node/issues/298 #[derive(Debug, PartialEq, Eq)] #[ink::scale_derive(Encode, Decode, TypeInfo)] pub enum PSP22Error { diff --git a/pop-api/src/v0/fungibles/events.rs b/pop-api/src/v0/fungibles/events.rs index a018ac59..130ead65 100644 --- a/pop-api/src/v0/fungibles/events.rs +++ b/pop-api/src/v0/fungibles/events.rs @@ -7,6 +7,7 @@ //! track token operations. Be mindful of the costs associated with emitting events. //! //! For more details, refer to [ink! events](https://use.ink/basics/events). + use super::*; /// Event emitted when allowance by `owner` to `spender` changes. diff --git a/pop-api/src/v0/fungibles/mod.rs b/pop-api/src/v0/fungibles/mod.rs index fe6c685e..77f5f32c 100644 --- a/pop-api/src/v0/fungibles/mod.rs +++ b/pop-api/src/v0/fungibles/mod.rs @@ -23,8 +23,6 @@ pub mod errors; pub mod events; pub mod traits; -pub type PSP22Result = core::result::Result; - /// Returns the total token supply for a specified token. /// /// # Parameters @@ -300,7 +298,7 @@ pub mod management { } mod constants { - /// 1. PSP-22 Interface: + /// 1. PSP-22 pub(super) const TOTAL_SUPPLY: u8 = 0; pub(super) const BALANCE_OF: u8 = 1; pub(super) const ALLOWANCE: u8 = 2; @@ -310,19 +308,19 @@ mod constants { pub(super) const INCREASE_ALLOWANCE: u8 = 6; pub(super) const DECREASE_ALLOWANCE: u8 = 7; - /// 2. PSP-22 Metadata Interface: + /// 2. PSP-22 Metadata pub(super) const TOKEN_NAME: u8 = 8; pub(super) const TOKEN_SYMBOL: u8 = 9; pub(super) const TOKEN_DECIMALS: u8 = 10; - /// 3. Asset Management: + /// 3. Management pub(super) const CREATE: u8 = 11; pub(super) const START_DESTROY: u8 = 12; pub(super) const SET_METADATA: u8 = 16; pub(super) const CLEAR_METADATA: u8 = 17; pub(super) const TOKEN_EXISTS: u8 = 18; - /// 4. PSP-22 Mintable & Burnable interface: + /// 4. PSP-22 Mintable & Burnable pub(super) const MINT: u8 = 19; pub(super) const BURN: u8 = 20; } diff --git a/pop-api/src/v0/fungibles/traits.rs b/pop-api/src/v0/fungibles/traits.rs index 0d9d2d29..0220d363 100644 --- a/pop-api/src/v0/fungibles/traits.rs +++ b/pop-api/src/v0/fungibles/traits.rs @@ -1,3 +1,4 @@ +/// A set of traits that implement the PSP22 token standard. use super::*; /// The PSP22 trait. @@ -30,7 +31,7 @@ pub trait Psp22 { /// - `value` - The number of tokens to transfer. /// - `data` - Additional data in unspecified format. #[ink(message)] - fn transfer(&mut self, to: AccountId, value: Balance, data: Vec) -> PSP22Result<()>; + fn transfer(&mut self, to: AccountId, value: Balance, data: Vec) -> Result<(), PSP22Error>; /// Transfers `value` tokens on behalf of `from` to the account `to` /// with additional `data` in unspecified format. @@ -47,7 +48,7 @@ pub trait Psp22 { to: AccountId, value: Balance, data: Vec, - ) -> PSP22Result<()>; + ) -> Result<(), PSP22Error>; /// Approves `spender` to spend `value` amount of tokens on behalf of the caller. /// @@ -57,7 +58,7 @@ pub trait Psp22 { /// - `spender` - The account that is allowed to spend the tokens. /// - `value` - The number of tokens to approve. #[ink(message)] - fn approve(&mut self, spender: AccountId, value: Balance) -> PSP22Result<()>; + fn approve(&mut self, spender: AccountId, value: Balance) -> Result<(), PSP22Error>; /// Increases the allowance of `spender` by `value` amount of tokens. /// @@ -65,7 +66,7 @@ pub trait Psp22 { /// - `spender` - The account that is allowed to spend the tokens. /// - `value` - The number of tokens to increase the allowance by. #[ink(message)] - fn increase_allowance(&mut self, spender: AccountId, value: Balance) -> PSP22Result<()>; + fn increase_allowance(&mut self, spender: AccountId, value: Balance) -> Result<(), PSP22Error>; /// Decreases the allowance of `spender` by `value` amount of tokens. /// @@ -73,7 +74,7 @@ pub trait Psp22 { /// - `spender` - The account that is allowed to spend the tokens. /// - `value` - The number of tokens to decrease the allowance by. #[ink(message)] - fn decrease_allowance(&mut self, spender: AccountId, value: Balance) -> PSP22Result<()>; + fn decrease_allowance(&mut self, spender: AccountId, value: Balance) -> Result<(), PSP22Error>; } /// The PSP22 Metadata trait. @@ -101,7 +102,7 @@ pub trait Psp22Mintable { /// - `account` - The account to be credited with the created tokens. /// - `value` - The number of tokens to mint. #[ink(message)] - fn mint(&mut self, account: AccountId, amount: Balance) -> PSP22Result<()>; + fn mint(&mut self, account: AccountId, value: Balance) -> Result<(), PSP22Error>; } /// The PSP22 Burnable trait. @@ -113,5 +114,5 @@ pub trait Psp22Burnable { /// - `account` - The account from which the tokens will be destroyed. /// - `value` - The number of tokens to destroy. #[ink(message)] - fn burn(&mut self, account: AccountId, amount: Balance) -> PSP22Result<()>; + fn burn(&mut self, account: AccountId, value: Balance) -> Result<(), PSP22Error>; } From 8ae2c0000da19032a8cfd7b131702e03e247b041 Mon Sep 17 00:00:00 2001 From: chungquantin <56880684+chungquantin@users.noreply.github.com> Date: Thu, 19 Sep 2024 23:18:36 +0700 Subject: [PATCH 100/112] fix: api integration tests --- pop-api/src/v0/fungibles/traits.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/pop-api/src/v0/fungibles/traits.rs b/pop-api/src/v0/fungibles/traits.rs index 0220d363..9bcf2e8d 100644 --- a/pop-api/src/v0/fungibles/traits.rs +++ b/pop-api/src/v0/fungibles/traits.rs @@ -1,5 +1,8 @@ -/// A set of traits that implement the PSP22 token standard. +//! A set of traits that implement the PSP22 token standard. + use super::*; +use ink::prelude::string::String; +use std::result::Result; /// The PSP22 trait. #[ink::trait_definition] From 97417e3431459d8141d8b6271190250f655b3d8c Mon Sep 17 00:00:00 2001 From: chungquantin <56880684+chungquantin@users.noreply.github.com> Date: Thu, 19 Sep 2024 23:49:26 +0700 Subject: [PATCH 101/112] fix: result type --- pop-api/src/v0/fungibles/traits.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pop-api/src/v0/fungibles/traits.rs b/pop-api/src/v0/fungibles/traits.rs index 9bcf2e8d..caa4c68d 100644 --- a/pop-api/src/v0/fungibles/traits.rs +++ b/pop-api/src/v0/fungibles/traits.rs @@ -1,8 +1,8 @@ //! A set of traits that implement the PSP22 token standard. use super::*; +use core::result::Result; use ink::prelude::string::String; -use std::result::Result; /// The PSP22 trait. #[ink::trait_definition] From 204ee060ae44fee7359020e0c513716b4b205ef9 Mon Sep 17 00:00:00 2001 From: chungquantin <56880684+chungquantin@users.noreply.github.com> Date: Thu, 19 Sep 2024 23:13:42 +0700 Subject: [PATCH 102/112] fix: resolve comments --- pop-api/src/v0/fungibles/traits.rs | 383 ++++++++++++++++++++--------- 1 file changed, 268 insertions(+), 115 deletions(-) diff --git a/pop-api/src/v0/fungibles/traits.rs b/pop-api/src/v0/fungibles/traits.rs index caa4c68d..0b660ee6 100644 --- a/pop-api/src/v0/fungibles/traits.rs +++ b/pop-api/src/v0/fungibles/traits.rs @@ -1,121 +1,274 @@ -//! A set of traits that implement the PSP22 token standard. - -use super::*; -use core::result::Result; -use ink::prelude::string::String; - -/// The PSP22 trait. -#[ink::trait_definition] -pub trait Psp22 { - /// Returns the total token supply. - #[ink(message)] - fn total_supply(&self) -> Balance; - - /// Returns the account balance for the specified `owner`. - /// - /// # Parameters - /// - `owner` - The account whose balance is being queried. - #[ink(message)] - fn balance_of(&self, owner: AccountId) -> Balance; - - /// Returns the allowance for a `spender` approved by an `owner`. - /// - /// # Parameters - /// - `owner` - The account that owns the tokens. - /// - `spender` - The account that is allowed to spend the tokens. - #[ink(message)] - fn allowance(&self, owner: AccountId, spender: AccountId) -> Balance; - - /// Transfers `value` amount of tokens from the caller's account to account `to` - /// with additional `data` in unspecified format. - /// - /// # Parameters - /// - `to` - The recipient account. - /// - `value` - The number of tokens to transfer. - /// - `data` - Additional data in unspecified format. - #[ink(message)] - fn transfer(&mut self, to: AccountId, value: Balance, data: Vec) -> Result<(), PSP22Error>; - - /// Transfers `value` tokens on behalf of `from` to the account `to` - /// with additional `data` in unspecified format. - /// - /// # Parameters - /// - `from` - The account from which the token balance will be withdrawn. - /// - `to` - The recipient account. - /// - `value` - The number of tokens to transfer. - /// - `data` - Additional data with unspecified format. - #[ink(message)] - fn transfer_from( - &mut self, - from: AccountId, - to: AccountId, - value: Balance, - data: Vec, - ) -> Result<(), PSP22Error>; - - /// Approves `spender` to spend `value` amount of tokens on behalf of the caller. - /// - /// Successive calls of this method overwrite previous values. - /// - /// # Parameters - /// - `spender` - The account that is allowed to spend the tokens. - /// - `value` - The number of tokens to approve. - #[ink(message)] - fn approve(&mut self, spender: AccountId, value: Balance) -> Result<(), PSP22Error>; - - /// Increases the allowance of `spender` by `value` amount of tokens. - /// - /// # Parameters - /// - `spender` - The account that is allowed to spend the tokens. - /// - `value` - The number of tokens to increase the allowance by. - #[ink(message)] - fn increase_allowance(&mut self, spender: AccountId, value: Balance) -> Result<(), PSP22Error>; - - /// Decreases the allowance of `spender` by `value` amount of tokens. - /// - /// # Parameters - /// - `spender` - The account that is allowed to spend the tokens. - /// - `value` - The number of tokens to decrease the allowance by. - #[ink(message)] - fn decrease_allowance(&mut self, spender: AccountId, value: Balance) -> Result<(), PSP22Error>; -} +#![cfg_attr(not(feature = "std"), no_std, no_main)] -/// The PSP22 Metadata trait. -#[ink::trait_definition] -pub trait Psp22Metadata { - /// Returns the token name. - #[ink(message)] - fn token_name(&self) -> Option; +use ink::prelude::{string::String, vec::Vec}; +use pop_api::{ + primitives::TokenId, + v0::fungibles::{ + self as api, + events::{Approval, Created, Transfer}, + traits::{Psp22, Psp22Burnable, Psp22Metadata, Psp22Mintable}, + PSP22Error, + }, +}; - /// Returns the token symbol. - #[ink(message)] - fn token_symbol(&self) -> Option; +#[ink::contract] +mod fungibles { + use super::*; - /// Returns the token decimals. - #[ink(message)] - fn token_decimals(&self) -> u8; -} + #[ink(storage)] + pub struct Fungibles { + id: TokenId, + } -/// The PSP22 Mintable trait. -#[ink::trait_definition] -pub trait Psp22Mintable { - /// Creates `value` amount of tokens and assigns them to `account`, increasing the total supply. - /// - /// # Parameters - /// - `account` - The account to be credited with the created tokens. - /// - `value` - The number of tokens to mint. - #[ink(message)] - fn mint(&mut self, account: AccountId, value: Balance) -> Result<(), PSP22Error>; -} + impl Fungibles { + fn emit_created_event(&mut self, id: u32, creator: AccountId, admin: AccountId) { + self.env().emit_event(Created { id, creator, admin }); + } + + fn emit_transfer_event( + &mut self, + from: Option, + to: Option, + value: Balance, + ) { + self.env().emit_event(Transfer { from, to, value }); + } + + fn emit_approval_event(&mut self, owner: AccountId, spender: AccountId, value: Balance) { + self.env().emit_event(Approval { owner, spender, value }); + } + + /// Instantiate the contract and wrap around an existing token. + /// + /// # Parameters + /// * - `token` - The token. + #[ink(constructor, payable)] + pub fn new_existing(id: TokenId) -> Result { + // Make sure token exists. + if !api::token_exists(id).unwrap_or_default() { + return Err(PSP22Error::Custom(String::from("Unknown"))); + } + let contract = Self { id }; + Ok(contract) + } + + /// Instantiate the contract and create a new token. The token identifier will be stored + /// in contract's storage. + /// + /// # Parameters + /// * - `id` - The identifier of the token. + /// * - `admin` - The account that will administer the token. + /// * - `min_balance` - The minimum balance required for accounts holding this token. + #[ink(constructor, payable)] + pub fn new( + id: TokenId, + admin: AccountId, + min_balance: Balance, + ) -> Result { + api::create(id, admin, min_balance).map_err(PSP22Error::from)?; + let mut contract = Self { id }; + contract.emit_created_event(id, contract.env().account_id(), admin); + Ok(contract) + } + } + + impl Psp22 for Fungibles { + /// Returns the total token supply. + #[ink(message)] + fn total_supply(&self) -> Balance { + api::total_supply(self.id).unwrap_or_default() + } + + /// Returns the account balance for the specified `owner` + #[ink(message)] + fn balance_of(&self, owner: AccountId) -> Balance { + api::balance_of(self.id, owner).unwrap_or_default() + } + + /// Returns the amount which `spender` is still allowed to withdraw from `owner` + #[ink(message)] + fn allowance(&self, owner: AccountId, spender: AccountId) -> Balance { + api::allowance(self.id, owner, spender).unwrap_or_default() + } + + /// Transfers `value` amount of tokens from the caller's account to account `to` + /// with additional `data` in unspecified format. + #[ink(message)] + fn transfer( + &mut self, + to: AccountId, + value: Balance, + _data: Vec, + ) -> Result<(), PSP22Error> { + let caller = self.env().caller(); + // No-op if the caller and `to` is the same address or `value` is zero, returns success + // and no events are emitted. + if caller == to || value == 0 { + return Ok(()); + } + + // Reverts with `InsufficientBalance` if the `value` exceeds the caller's balance. + if value > self.env().balance() { + return Err(PSP22Error::InsufficientBalance); + } + + api::transfer(self.id, to, value).map_err(PSP22Error::from)?; + self.emit_transfer_event(Some(caller), Some(to), value); + Ok(()) + } + + /// Transfers `value` tokens on the behalf of `from` to the account `to` + /// with additional `data` in unspecified format. + #[ink(message)] + fn transfer_from( + &mut self, + from: AccountId, + to: AccountId, + value: Balance, + _data: Vec, + ) -> Result<(), PSP22Error> { + let caller = self.env().caller(); + // No-op if `from` and `to` is the same address or `value` is zero, returns success and + // no events are emitted. + if from == to || value == 0 { + return Ok(()); + } + + // Reverts with `InsufficientBalance` if the `value` exceeds the balance of the account + // `from`. + let allowance = self.allowance(from, caller); + if allowance < value { + return Err(PSP22Error::InsufficientAllowance); + } + + // Reverts with `InsufficientAllowance` if `from` and the caller are different addresses + // and the `value` exceeds the allowance granted by `from` to the caller. + let from_balance = self.balance_of(from); + if from_balance < value { + return Err(PSP22Error::InsufficientBalance); + } + + // If `from` and the caller are different addresses, a successful transfer results + // in decreased allowance by `from` to the caller and an `Approval` event with + // the new allowance amount is emitted. + api::transfer_from(self.id, from, to, value).map_err(PSP22Error::from)?; + // Emit events. + self.emit_transfer_event(Some(caller), Some(to), value); + let allowance = self.allowance(from, to).saturating_sub(value); + self.emit_approval_event(from, caller, allowance); + Ok(()) + } + + /// Allows `spender` to withdraw from the caller's account multiple times, up to + /// the total amount of `value`. + #[ink(message)] + fn approve(&mut self, spender: AccountId, value: Balance) -> Result<(), PSP22Error> { + let caller = self.env().caller(); + // No-op if the caller and `spender` is the same address, returns success and no events + // are emitted. + if caller == spender { + return Ok(()); + } + + api::approve(self.id, spender, value).map_err(PSP22Error::from)?; + self.emit_approval_event(caller, spender, value); + Ok(()) + } + + /// Increases by `value` the allowance granted to `spender` by the caller. + #[ink(message)] + fn increase_allowance( + &mut self, + spender: AccountId, + value: Balance, + ) -> Result<(), PSP22Error> { + let caller = self.env().caller(); + // No-op if the caller and `spender` is the same address or `value` is zero, returns success + // and no events are emitted. + if caller == spender || value == 0 { + return Ok(()); + } + + api::increase_allowance(self.id, spender, value).map_err(PSP22Error::from)?; + let allowance = self.allowance(caller, spender).saturating_add(value); + self.emit_approval_event(caller, spender, allowance); + Ok(()) + } + + /// Decreases by `value` the allowance granted to `spender` by the caller. + #[ink(message)] + fn decrease_allowance( + &mut self, + spender: AccountId, + value: Balance, + ) -> Result<(), PSP22Error> { + let caller = self.env().caller(); + // No-op if the caller and `spender` is the same address or `value` is zero, returns success + // and no events are emitted. + if caller == spender || value == 0 { + return Ok(()); + } + // Reverts with `InsufficientAllowance` if `spender` and the caller are different addresses and + // the `value` exceeds the allowance granted by the caller to `spender`. + let allowance = self.allowance(caller, spender); + if allowance < value { + return Err(PSP22Error::InsufficientAllowance); + } + + api::decrease_allowance(self.id, spender, value).map_err(PSP22Error::from)?; + let allowance = allowance.saturating_sub(value); + self.emit_approval_event(caller, spender, allowance); + Ok(()) + } + } + + impl Psp22Metadata for Fungibles { + /// Returns the token name. + #[ink(message)] + fn token_name(&self) -> Option { + api::token_name(self.id).ok().and_then(|v| String::from_utf8(v).ok()) + } + + /// Returns the token symbol. + #[ink(message)] + fn token_symbol(&self) -> Option { + api::token_symbol(self.id).ok().and_then(|v| String::from_utf8(v).ok()) + } + + /// Returns the token decimals. + #[ink(message)] + fn token_decimals(&self) -> u8 { + api::token_decimals(self.id).unwrap_or_default() + } + } + + impl Psp22Mintable for Fungibles { + /// Mints `value` tokens to the senders account. + #[ink(message)] + fn mint(&mut self, account: AccountId, value: Balance) -> Result<(), PSP22Error> { + if value == 0 { + return Ok(()); + } + api::mint(self.id, account, value).map_err(PSP22Error::from)?; + self.emit_transfer_event(None, Some(account), value); + Ok(()) + } + } -/// The PSP22 Burnable trait. -#[ink::trait_definition] -pub trait Psp22Burnable { - /// Destroys `value` amount of tokens from `account`, reducing the total supply. - /// - /// # Parameters - /// - `account` - The account from which the tokens will be destroyed. - /// - `value` - The number of tokens to destroy. - #[ink(message)] - fn burn(&mut self, account: AccountId, value: Balance) -> Result<(), PSP22Error>; + impl Psp22Burnable for Fungibles { + /// Burns `value` tokens from the senders account. + #[ink(message)] + fn burn(&mut self, account: AccountId, value: Balance) -> Result<(), PSP22Error> { + if value == 0 { + return Ok(()); + } + let balance = self.balance_of(account); + if balance < value { + return Err(PSP22Error::InsufficientBalance); + } + api::burn(self.id, account, value).map_err(PSP22Error::from)?; + self.emit_transfer_event(Some(account), None, value); + Ok(()) + } + } } From 867cc283f1561c6bd73f011c1a38edd43f95701b Mon Sep 17 00:00:00 2001 From: chungquantin <56880684+chungquantin@users.noreply.github.com> Date: Fri, 20 Sep 2024 18:03:11 +0700 Subject: [PATCH 103/112] feat: drink test for example contract --- pop-api/examples/fungibles/Cargo.toml | 1 + pop-api/examples/fungibles/lib.rs | 24 +-- pop-api/examples/fungibles/tests.rs | 209 +++++++++++--------------- pop-api/src/v0/fungibles/errors.rs | 13 +- pop-api/src/v0/fungibles/mod.rs | 11 +- pop-api/src/v0/fungibles/traits.rs | 4 +- 6 files changed, 122 insertions(+), 140 deletions(-) diff --git a/pop-api/examples/fungibles/Cargo.toml b/pop-api/examples/fungibles/Cargo.toml index 075ea943..c06bc0f5 100644 --- a/pop-api/examples/fungibles/Cargo.toml +++ b/pop-api/examples/fungibles/Cargo.toml @@ -20,6 +20,7 @@ scale-info = { version = "2.6", default-features = false, features = [ drink = { path = "../../../../pop-drink/drink" } env_logger = { version = "0.11.3" } pop-sandbox = { path = "../../../pop-sandbox", default-features = false } +serde_json = "1.0.114" [lib] path = "lib.rs" diff --git a/pop-api/examples/fungibles/lib.rs b/pop-api/examples/fungibles/lib.rs index 0b660ee6..e3457e18 100644 --- a/pop-api/examples/fungibles/lib.rs +++ b/pop-api/examples/fungibles/lib.rs @@ -11,6 +11,9 @@ use pop_api::{ }, }; +#[cfg(test)] +mod tests; + #[ink::contract] mod fungibles { use super::*; @@ -62,12 +65,14 @@ mod fungibles { #[ink(constructor, payable)] pub fn new( id: TokenId, - admin: AccountId, + // TODO: If admin is different than the contract address, `NoPermission` thrown for mint, burn + // _admin: AccountId, min_balance: Balance, ) -> Result { - api::create(id, admin, min_balance).map_err(PSP22Error::from)?; let mut contract = Self { id }; - contract.emit_created_event(id, contract.env().account_id(), admin); + let contract_id = contract.env().account_id(); + api::create(id, contract_id, min_balance).map_err(PSP22Error::from)?; + contract.emit_created_event(id, contract_id, contract_id); Ok(contract) } } @@ -183,8 +188,8 @@ mod fungibles { value: Balance, ) -> Result<(), PSP22Error> { let caller = self.env().caller(); - // No-op if the caller and `spender` is the same address or `value` is zero, returns success - // and no events are emitted. + // No-op if the caller and `spender` is the same address or `value` is zero, returns + // success and no events are emitted. if caller == spender || value == 0 { return Ok(()); } @@ -203,13 +208,14 @@ mod fungibles { value: Balance, ) -> Result<(), PSP22Error> { let caller = self.env().caller(); - // No-op if the caller and `spender` is the same address or `value` is zero, returns success - // and no events are emitted. + // No-op if the caller and `spender` is the same address or `value` is zero, returns + // success and no events are emitted. if caller == spender || value == 0 { return Ok(()); } - // Reverts with `InsufficientAllowance` if `spender` and the caller are different addresses and - // the `value` exceeds the allowance granted by the caller to `spender`. + // Reverts with `InsufficientAllowance` if `spender` and the caller are different + // addresses and the `value` exceeds the allowance granted by the caller to + // `spender`. let allowance = self.allowance(caller, spender); if allowance < value { return Err(PSP22Error::InsufficientAllowance); diff --git a/pop-api/examples/fungibles/tests.rs b/pop-api/examples/fungibles/tests.rs index 216b9de3..89d4298e 100644 --- a/pop-api/examples/fungibles/tests.rs +++ b/pop-api/examples/fungibles/tests.rs @@ -1,15 +1,14 @@ -use drink::session::{Session, NO_ARGS, NO_SALT}; +use drink::session::{error::SessionError, Session, NO_ARGS, NO_SALT}; use pop_api::{ - primitives::TokenId, - v0::fungibles::{self as api}, + primitives::{AccountId, TokenId}, + v0::fungibles::{self as api, PSP22Error}, }; use pop_sandbox::{AccountId32, Balance, Sandbox, ALICE, BOB, INIT_VALUE}; use scale::{Decode, Encode}; use super::*; -const TOKEN_A: TokenId = 1; -const TOKEN_B: TokenId = 2; +const TOKEN_ID: TokenId = 1; #[drink::contract_bundle_provider] enum BundleProvider {} @@ -20,8 +19,8 @@ mod test_methods { use super::*; // Decode slice of bytes to `pop-api` AccountId. - pub(super) fn account_id_from_slice(s: &[u8; 32]) -> pop_api::primitives::AccountId { - pop_api::primitives::AccountId::decode(&mut &s[..]).expect("Should be decoded to AccountId") + pub(super) fn account_id_from_slice(s: &[u8; 32]) -> AccountId { + AccountId::decode(&mut &s[..]).expect("Should be decoded to AccountId") } // Call a contract method and decode the returned data. @@ -42,175 +41,143 @@ mod test_methods { assert_eq!(last_event, event.as_slice()); } - pub(super) fn mint( + // Test methods for deployment with constructor function. + + pub(super) fn deploy_with_new_constructor( session: &mut Session, - token: TokenId, - account: AccountId32, - amount: Balance, - ) -> Result<(), Box> { - Ok(session.call( - "mint", - &vec![token.to_string(), account.to_string(), amount.to_string()], - None, - )??) + id: TokenId, + min_balance: Balance, + ) -> Result { + session.deploy_bundle( + BundleProvider::local()?, + "new", + &[id.to_string(), min_balance.to_string()], + NO_SALT, + Some(INIT_VALUE), + ) } - pub(super) fn burn( + // Test methods for `PSP22`.` + + pub(super) fn total_supply( session: &mut Session, - token: TokenId, - account: AccountId32, - amount: Balance, - ) -> Result<(), Box> { - Ok(session.call( - "burn", - &vec![token.to_string(), account.to_string(), amount.to_string()], - None, - )??) + ) -> Result> { + Ok(decoded_call::(session, "Psp22::total_supply", vec![], None)?) + } + + pub(super) fn balance_of( + session: &mut Session, + owner: AccountId32, + ) -> Result> { + Ok(decoded_call::(session, "Psp22::balance_of", vec![owner.to_string()], None)?) } pub(super) fn transfer( session: &mut Session, - token: TokenId, to: AccountId32, amount: Balance, ) -> Result<(), Box> { + let data = serde_json::to_string::<[u8; 0]>(&[]).unwrap(); Ok(session.call( - "transfer", - &vec![token.to_string(), to.to_string(), amount.to_string()], + "Psp22::transfer", + &vec![to.to_string(), amount.to_string(), data], None, )??) } - pub(super) fn create( + // Test methods for `PSP22Metadata``. + + pub(super) fn token_name( session: &mut Session, - id: TokenId, - admin: AccountId32, - min_balance: Balance, - ) -> Result<(), Box> { - Ok(session.call( - "create", - &vec![id.to_string(), admin.to_string(), min_balance.to_string()], - None, - )??) + ) -> Result> { + Ok(decoded_call::(session, "Psp22Metadata::token_name", vec![], None)?) } - pub(super) fn token_exist( + pub(super) fn token_symbol( session: &mut Session, - token: TokenId, - ) -> Result, Box> { - Ok(decoded_call::>(session, "token_exists", vec![token.to_string()], None)?) + ) -> Result> { + Ok(decoded_call::(session, "Psp22Metadata::token_symbol", vec![], None)?) } - pub(super) fn total_supply( + pub(super) fn token_decimals( session: &mut Session, - token: TokenId, - ) -> Result, Box> { - Ok(decoded_call::>( - session, - "total_supply", - vec![token.to_string()], - None, - )?) + ) -> Result> { + Ok(decoded_call::(session, "Psp22Metadata::token_decimals", vec![], None)?) } - pub(super) fn balance_of( + // Test methods for `PSP22Mintable``. + + pub(super) fn mint( session: &mut Session, - token: TokenId, - owner: AccountId32, - ) -> Result, Box> { - Ok(decoded_call::>( - session, - "balance_of", - vec![token.to_string(), owner.to_string()], + account: AccountId32, + amount: Balance, + ) -> Result<(), Box> { + Ok(session.call( + "Psp22Mintable::mint", + &vec![account.to_string(), amount.to_string()], None, - )?) + )??) } -} -#[drink::test(sandbox = Sandbox)] -fn test_create_multiple_token_works( - mut session: Session, -) -> Result<(), Box> { - let _ = env_logger::try_init(); - let contract_bundle = BundleProvider::local()?; - // Deploy a contract. - session.deploy_bundle(contract_bundle, "new", NO_ARGS, NO_SALT, Some(INIT_VALUE))?; - // Create new tokens. - create(&mut session, TOKEN_A, ALICE, 1_000)?; - - assert_event( - &mut session, - api::events::Created { - id: TOKEN_A, - admin: account_id_from_slice(ALICE.as_ref()), - creator: account_id_from_slice(ALICE.as_ref()), - } - .encode(), - ); - - create(&mut session, TOKEN_B, ALICE, 2_000)?; - // Check that the token is created successfully. - assert_eq!(token_exist(&mut session, TOKEN_A)?, Ok(true)); - assert_eq!(token_exist(&mut session, TOKEN_B)?, Ok(true)); - Ok(()) + // Test methods for `PSP22MPsp22Burnablentable``. + + pub(super) fn burn( + session: &mut Session, + account: AccountId32, + amount: Balance, + ) -> Result<(), Box> { + Ok(session.call( + "Psp22Burnable::burn", + &vec![account.to_string(), amount.to_string()], + None, + )??) + } } #[drink::test(sandbox = Sandbox)] fn test_mint_token_works(mut session: Session) -> Result<(), Box> { let _ = env_logger::try_init(); - let contract_bundle = BundleProvider::local()?; - // Deploy a contract. - let contract_address = - session.deploy_bundle(contract_bundle, "new", NO_ARGS, NO_SALT, Some(INIT_VALUE))?; - // Create a new token. - create(&mut session, TOKEN_A, contract_address, 10_000)?; + // Deploy a new contract. + let contract_address = deploy_with_new_constructor(&mut session, 1, 10_000)?; // Mint tokens. const AMOUNT: Balance = 12_000; - mint(&mut session, TOKEN_A, ALICE, AMOUNT)?; - mint(&mut session, TOKEN_A, BOB, AMOUNT)?; + mint(&mut session, ALICE, AMOUNT)?; + mint(&mut session, BOB, AMOUNT)?; // Check if the tokens were minted with the right amount. - assert_eq!(total_supply(&mut session, TOKEN_A)?, Ok(AMOUNT * 2)); - assert_eq!(balance_of(&mut session, TOKEN_A, ALICE)?, Ok(AMOUNT)); - assert_eq!(balance_of(&mut session, TOKEN_A, BOB)?, Ok(AMOUNT)); + assert_eq!(total_supply(&mut session)?, AMOUNT * 2); + assert_eq!(balance_of(&mut session, ALICE)?, AMOUNT); + assert_eq!(balance_of(&mut session, BOB)?, AMOUNT); Ok(()) } #[drink::test(sandbox = Sandbox)] fn test_burn_token_works(mut session: Session) -> Result<(), Box> { let _ = env_logger::try_init(); - let contract_bundle = BundleProvider::local()?; - // Deploy a contract. - let contract_address = - session.deploy_bundle(contract_bundle, "new", NO_ARGS, NO_SALT, Some(INIT_VALUE))?; - // Create a new token. - create(&mut session, TOKEN_A, contract_address, 10_000)?; + // Deploy a new contract. + let contract_address = deploy_with_new_constructor(&mut session, TOKEN_ID, 10_000)?; // Mint tokens. const AMOUNT: Balance = 12_000; - mint(&mut session, TOKEN_A, ALICE, AMOUNT)?; + mint(&mut session, ALICE, AMOUNT)?; // Burn tokens. - burn(&mut session, TOKEN_A, ALICE, 1)?; - assert_eq!(total_supply(&mut session, TOKEN_A)?, Ok(AMOUNT - 1)); - assert_eq!(balance_of(&mut session, TOKEN_A, ALICE)?, Ok(AMOUNT - 1)); + burn(&mut session, ALICE, 1)?; + assert_eq!(total_supply(&mut session)?, AMOUNT - 1); + assert_eq!(balance_of(&mut session, ALICE)?, AMOUNT - 1); Ok(()) } #[drink::test(sandbox = Sandbox)] fn test_transfer_token_works(mut session: Session) -> Result<(), Box> { let _ = env_logger::try_init(); - let contract_bundle = BundleProvider::local()?; - // Deploy a contract. - let contract_address = - session.deploy_bundle(contract_bundle, "new", NO_ARGS, NO_SALT, Some(INIT_VALUE))?; - // Create a new token. - create(&mut session, TOKEN_A, contract_address.clone(), 10_000)?; + // Deploy a new contract. + let contract_address = deploy_with_new_constructor(&mut session, TOKEN_ID, 10_000)?; // Mint tokens. const AMOUNT: Balance = 12_000; const TRANSFERED: Balance = 500; - mint(&mut session, TOKEN_A, contract_address.clone(), AMOUNT)?; - mint(&mut session, TOKEN_A, BOB, AMOUNT)?; + mint(&mut session, contract_address.clone(), AMOUNT)?; + mint(&mut session, BOB, AMOUNT)?; // Transfer tokens. - transfer(&mut session, TOKEN_A, BOB, TRANSFERED)?; - assert_eq!(balance_of(&mut session, TOKEN_A, contract_address)?, Ok(AMOUNT - TRANSFERED)); - assert_eq!(balance_of(&mut session, TOKEN_A, BOB)?, Ok(AMOUNT + TRANSFERED)); + transfer(&mut session, BOB, TRANSFERED)?; + assert_eq!(balance_of(&mut session, contract_address)?, AMOUNT - TRANSFERED); + assert_eq!(balance_of(&mut session, BOB)?, AMOUNT + TRANSFERED); Ok(()) } diff --git a/pop-api/src/v0/fungibles/errors.rs b/pop-api/src/v0/fungibles/errors.rs index 313107b4..a6df4348 100644 --- a/pop-api/src/v0/fungibles/errors.rs +++ b/pop-api/src/v0/fungibles/errors.rs @@ -1,8 +1,10 @@ -//! A set of errors for use in smart contracts that interact with the fungibles api. This includes errors compliant to standards. +//! A set of errors for use in smart contracts that interact with the fungibles api. This includes +//! errors compliant to standards. -use super::*; use ink::prelude::string::String; +use super::*; + /// Represents various errors related to fungible tokens. /// /// The `FungiblesError` provides a detailed and specific set of error types that can occur when @@ -99,6 +101,11 @@ impl From for PSP22Error { #[cfg(test)] mod tests { + use ink::{ + prelude::string::String, + scale::{Decode, Encode}, + }; + use super::{FungiblesError, PSP22Error}; use crate::{ constants::{ASSETS, BALANCES}, @@ -110,8 +117,6 @@ mod tests { }, StatusCode, }; - use ink::prelude::string::String; - use ink::scale::{Decode, Encode}; fn error_into_status_code(error: Error) -> StatusCode { let mut encoded_error = error.encode(); diff --git a/pop-api/src/v0/fungibles/mod.rs b/pop-api/src/v0/fungibles/mod.rs index 77f5f32c..7d1594c0 100644 --- a/pop-api/src/v0/fungibles/mod.rs +++ b/pop-api/src/v0/fungibles/mod.rs @@ -6,11 +6,6 @@ //! 3. Management //! 4. PSP-22 Mintable & Burnable -use crate::{ - constants::{ASSETS, BALANCES, FUNGIBLES}, - primitives::{AccountId, Balance, TokenId}, - ChainExtensionMethodApi, Result, StatusCode, -}; use constants::*; pub use errors::*; pub use events::*; @@ -19,6 +14,12 @@ pub use management::*; pub use metadata::*; pub use traits::*; +use crate::{ + constants::{ASSETS, BALANCES, FUNGIBLES}, + primitives::{AccountId, Balance, TokenId}, + ChainExtensionMethodApi, Result, StatusCode, +}; + pub mod errors; pub mod events; pub mod traits; diff --git a/pop-api/src/v0/fungibles/traits.rs b/pop-api/src/v0/fungibles/traits.rs index caa4c68d..6d7bda79 100644 --- a/pop-api/src/v0/fungibles/traits.rs +++ b/pop-api/src/v0/fungibles/traits.rs @@ -1,9 +1,11 @@ //! A set of traits that implement the PSP22 token standard. -use super::*; use core::result::Result; + use ink::prelude::string::String; +use super::*; + /// The PSP22 trait. #[ink::trait_definition] pub trait Psp22 { From 7dc60472c409f4834353271d8bf801c4de3baa8b Mon Sep 17 00:00:00 2001 From: chungquantin <56880684+chungquantin@users.noreply.github.com> Date: Fri, 20 Sep 2024 19:14:41 +0700 Subject: [PATCH 104/112] refactor: add helpers module --- pop-api/examples/fungibles/helpers.rs | 128 ++++++++++++++++++ pop-api/examples/fungibles/lib.rs | 2 + pop-api/examples/fungibles/tests.rs | 182 ++++++++------------------ 3 files changed, 182 insertions(+), 130 deletions(-) create mode 100644 pop-api/examples/fungibles/helpers.rs diff --git a/pop-api/examples/fungibles/helpers.rs b/pop-api/examples/fungibles/helpers.rs new file mode 100644 index 00000000..5cf1d616 --- /dev/null +++ b/pop-api/examples/fungibles/helpers.rs @@ -0,0 +1,128 @@ +// A set of helper methods to test the contract calls. + +use drink::session::{bundle::ContractBundle, error::SessionError, Session, NO_SALT}; +use pop_api::primitives::{AccountId, TokenId}; +use pop_sandbox::{AccountId32, Balance, Sandbox, INIT_VALUE}; +use scale::{Decode, Encode}; + +use super::*; + +// Decode slice of bytes to `pop-api` AccountId. +pub(super) fn account_id_from_slice(s: &[u8; 32]) -> AccountId { + AccountId::decode(&mut &s[..]).expect("Should be decoded to AccountId") +} + +// Call a contract method and decode the returned data. +pub(super) fn decoded_call( + session: &mut Session, + func_name: &str, + input: Vec, + endowment: Option, +) -> Result> { + session.call(func_name, &input, endowment)??; + Ok(session.record().last_call_return_decoded::()??) +} + +// Check if the event emitted correctly. +pub(super) fn assert_event(session: &mut Session, event: Vec) { + let contract_events = session.record().last_event_batch().contract_events(); + let last_event = contract_events.last().unwrap().to_vec(); + assert_eq!(last_event, event.as_slice()); +} + +// Test methods for deployment with constructor function. + +pub(super) fn deploy_with_new_constructor( + session: &mut Session, + bundle: ContractBundle, + id: TokenId, + min_balance: Balance, +) -> Result { + session.deploy_bundle( + bundle, + "new", + &[id.to_string(), min_balance.to_string()], + NO_SALT, + Some(INIT_VALUE), + ) +} + +pub(super) fn deploy_with_new_existing_constructor( + session: &mut Session, + bundle: ContractBundle, + id: TokenId, +) -> Result { + session.deploy_bundle(bundle, "new_existing", &[id.to_string()], NO_SALT, Some(INIT_VALUE)) +} + +// Test methods for `PSP22`.` + +pub(super) fn total_supply( + session: &mut Session, +) -> Result> { + Ok(decoded_call::(session, "Psp22::total_supply", vec![], None)?) +} + +pub(super) fn balance_of( + session: &mut Session, + owner: AccountId32, +) -> Result> { + Ok(decoded_call::(session, "Psp22::balance_of", vec![owner.to_string()], None)?) +} + +pub(super) fn transfer( + session: &mut Session, + to: AccountId32, + amount: Balance, +) -> Result<(), Box> { + let data = serde_json::to_string::<[u8; 0]>(&[]).unwrap(); + Ok(session.call("Psp22::transfer", &vec![to.to_string(), amount.to_string(), data], None)??) +} + +// Test methods for `PSP22Metadata``. + +pub(super) fn token_name( + session: &mut Session, +) -> Result> { + Ok(decoded_call::(session, "Psp22Metadata::token_name", vec![], None)?) +} + +pub(super) fn token_symbol( + session: &mut Session, +) -> Result> { + Ok(decoded_call::(session, "Psp22Metadata::token_symbol", vec![], None)?) +} + +pub(super) fn token_decimals( + session: &mut Session, +) -> Result> { + Ok(decoded_call::(session, "Psp22Metadata::token_decimals", vec![], None)?) +} + +// Test methods for `PSP22Mintable``. + +pub(super) fn mint( + session: &mut Session, + account: AccountId32, + amount: Balance, +) -> Result<(), Box> { + Ok(session.call( + "Psp22Mintable::mint", + &vec![account.to_string(), amount.to_string()], + None, + )??) +} + +// Test methods for `PSP22MPsp22Burnablentable``. + +pub(super) fn burn( + session: &mut Session, + account: AccountId32, + amount: Balance, +) -> Result<(), Box> { + Ok(session.call( + "Psp22Burnable::burn", + &vec![account.to_string(), amount.to_string()], + None, + )??) +} diff --git a/pop-api/examples/fungibles/lib.rs b/pop-api/examples/fungibles/lib.rs index e3457e18..b13542bb 100644 --- a/pop-api/examples/fungibles/lib.rs +++ b/pop-api/examples/fungibles/lib.rs @@ -11,6 +11,8 @@ use pop_api::{ }, }; +#[cfg(test)] +mod helpers; #[cfg(test)] mod tests; diff --git a/pop-api/examples/fungibles/tests.rs b/pop-api/examples/fungibles/tests.rs index 89d4298e..28093336 100644 --- a/pop-api/examples/fungibles/tests.rs +++ b/pop-api/examples/fungibles/tests.rs @@ -1,144 +1,56 @@ -use drink::session::{error::SessionError, Session, NO_ARGS, NO_SALT}; -use pop_api::{ - primitives::{AccountId, TokenId}, - v0::fungibles::{self as api, PSP22Error}, -}; -use pop_sandbox::{AccountId32, Balance, Sandbox, ALICE, BOB, INIT_VALUE}; -use scale::{Decode, Encode}; +use drink::{sandbox_api::assets_api::AssetsAPI, session::Session}; +use helpers::*; +use pop_api::primitives::TokenId; +use pop_sandbox::{Balance, Sandbox, ALICE, BOB}; use super::*; const TOKEN_ID: TokenId = 1; +const TOKEN_MIN_BALANCE: Balance = 10_000; #[drink::contract_bundle_provider] enum BundleProvider {} -use test_methods::*; -// Utility methods to test the contract calls. -mod test_methods { - use super::*; - - // Decode slice of bytes to `pop-api` AccountId. - pub(super) fn account_id_from_slice(s: &[u8; 32]) -> AccountId { - AccountId::decode(&mut &s[..]).expect("Should be decoded to AccountId") - } - - // Call a contract method and decode the returned data. - pub(super) fn decoded_call( - session: &mut Session, - func_name: &str, - input: Vec, - endowment: Option, - ) -> Result> { - session.call(func_name, &input, endowment)??; - Ok(session.record().last_call_return_decoded::()??) - } - - // Check if the event emitted correctly. - pub(super) fn assert_event(session: &mut Session, event: Vec) { - let contract_events = session.record().last_event_batch().contract_events(); - let last_event = contract_events.last().unwrap().to_vec(); - assert_eq!(last_event, event.as_slice()); - } - - // Test methods for deployment with constructor function. - - pub(super) fn deploy_with_new_constructor( - session: &mut Session, - id: TokenId, - min_balance: Balance, - ) -> Result { - session.deploy_bundle( - BundleProvider::local()?, - "new", - &[id.to_string(), min_balance.to_string()], - NO_SALT, - Some(INIT_VALUE), - ) - } - - // Test methods for `PSP22`.` - - pub(super) fn total_supply( - session: &mut Session, - ) -> Result> { - Ok(decoded_call::(session, "Psp22::total_supply", vec![], None)?) - } - - pub(super) fn balance_of( - session: &mut Session, - owner: AccountId32, - ) -> Result> { - Ok(decoded_call::(session, "Psp22::balance_of", vec![owner.to_string()], None)?) - } - - pub(super) fn transfer( - session: &mut Session, - to: AccountId32, - amount: Balance, - ) -> Result<(), Box> { - let data = serde_json::to_string::<[u8; 0]>(&[]).unwrap(); - Ok(session.call( - "Psp22::transfer", - &vec![to.to_string(), amount.to_string(), data], - None, - )??) - } - - // Test methods for `PSP22Metadata``. - - pub(super) fn token_name( - session: &mut Session, - ) -> Result> { - Ok(decoded_call::(session, "Psp22Metadata::token_name", vec![], None)?) - } - - pub(super) fn token_symbol( - session: &mut Session, - ) -> Result> { - Ok(decoded_call::(session, "Psp22Metadata::token_symbol", vec![], None)?) - } - - pub(super) fn token_decimals( - session: &mut Session, - ) -> Result> { - Ok(decoded_call::(session, "Psp22Metadata::token_decimals", vec![], None)?) - } - - // Test methods for `PSP22Mintable``. - - pub(super) fn mint( - session: &mut Session, - account: AccountId32, - amount: Balance, - ) -> Result<(), Box> { - Ok(session.call( - "Psp22Mintable::mint", - &vec![account.to_string(), amount.to_string()], - None, - )??) - } +#[drink::test(sandbox = Sandbox)] +fn new_constructor_works(mut session: Session) -> Result<(), Box> { + let _ = env_logger::try_init(); + // Deploy a new contract. + deploy_with_new_constructor( + &mut session, + BundleProvider::local()?, + TOKEN_ID, + TOKEN_MIN_BALANCE, + )?; + // Check if token exists after the deployment. + assert!(session.sandbox().asset_exists(&TOKEN_ID)); + // Check if `Created` event is emitted. + Ok(()) +} - // Test methods for `PSP22MPsp22Burnablentable``. +#[drink::test(sandbox = Sandbox)] +fn new_existing_constructor_works(mut session: Session) -> Result<(), Box> { + let _ = env_logger::try_init(); - pub(super) fn burn( - session: &mut Session, - account: AccountId32, - amount: Balance, - ) -> Result<(), Box> { - Ok(session.call( - "Psp22Burnable::burn", - &vec![account.to_string(), amount.to_string()], - None, - )??) - } + // Create token. + let actor = session.get_actor(); + session.sandbox().create(&TOKEN_ID, &actor, TOKEN_MIN_BALANCE).unwrap(); + // Deploy a new contract. + deploy_with_new_existing_constructor(&mut session, BundleProvider::local()?, TOKEN_ID)?; + // Check if token is created successfully. + assert!(session.sandbox().asset_exists(&TOKEN_ID)); + Ok(()) } #[drink::test(sandbox = Sandbox)] -fn test_mint_token_works(mut session: Session) -> Result<(), Box> { +fn mint_works(mut session: Session) -> Result<(), Box> { let _ = env_logger::try_init(); // Deploy a new contract. - let contract_address = deploy_with_new_constructor(&mut session, 1, 10_000)?; + let contract_address = deploy_with_new_constructor( + &mut session, + BundleProvider::local()?, + TOKEN_ID, + TOKEN_MIN_BALANCE, + )?; // Mint tokens. const AMOUNT: Balance = 12_000; mint(&mut session, ALICE, AMOUNT)?; @@ -151,10 +63,15 @@ fn test_mint_token_works(mut session: Session) -> Result<(), Box Result<(), Box> { +fn burn_works(mut session: Session) -> Result<(), Box> { let _ = env_logger::try_init(); // Deploy a new contract. - let contract_address = deploy_with_new_constructor(&mut session, TOKEN_ID, 10_000)?; + let contract_address = deploy_with_new_constructor( + &mut session, + BundleProvider::local()?, + TOKEN_ID, + TOKEN_MIN_BALANCE, + )?; // Mint tokens. const AMOUNT: Balance = 12_000; mint(&mut session, ALICE, AMOUNT)?; @@ -166,10 +83,15 @@ fn test_burn_token_works(mut session: Session) -> Result<(), Box Result<(), Box> { +fn transfer_works(mut session: Session) -> Result<(), Box> { let _ = env_logger::try_init(); // Deploy a new contract. - let contract_address = deploy_with_new_constructor(&mut session, TOKEN_ID, 10_000)?; + let contract_address = deploy_with_new_constructor( + &mut session, + BundleProvider::local()?, + TOKEN_ID, + TOKEN_MIN_BALANCE, + )?; // Mint tokens. const AMOUNT: Balance = 12_000; const TRANSFERED: Balance = 500; From b433c6783ba08ed28f309426f9c73712712aba99 Mon Sep 17 00:00:00 2001 From: chungquantin <56880684+chungquantin@users.noreply.github.com> Date: Fri, 20 Sep 2024 20:19:47 +0700 Subject: [PATCH 105/112] feat: add event assertions --- pop-api/examples/fungibles/helpers.rs | 8 +++- pop-api/examples/fungibles/lib.rs | 2 +- pop-api/examples/fungibles/tests.rs | 57 ++++++++++++++++++++------- 3 files changed, 50 insertions(+), 17 deletions(-) diff --git a/pop-api/examples/fungibles/helpers.rs b/pop-api/examples/fungibles/helpers.rs index 5cf1d616..027528df 100644 --- a/pop-api/examples/fungibles/helpers.rs +++ b/pop-api/examples/fungibles/helpers.rs @@ -7,11 +7,17 @@ use scale::{Decode, Encode}; use super::*; -// Decode slice of bytes to `pop-api` AccountId. +/// This is used to resolve type mismatches between the `AccountId` in the quasi testing environment and the +/// contract environment. pub(super) fn account_id_from_slice(s: &[u8; 32]) -> AccountId { AccountId::decode(&mut &s[..]).expect("Should be decoded to AccountId") } +/// Get the last event from pallet contracts. +pub(super) fn last_contract_event(session: &Session) -> Option> { + session.record().last_event_batch().contract_events().last().cloned() +} + // Call a contract method and decode the returned data. pub(super) fn decoded_call( session: &mut Session, diff --git a/pop-api/examples/fungibles/lib.rs b/pop-api/examples/fungibles/lib.rs index b13542bb..d7dc7d95 100644 --- a/pop-api/examples/fungibles/lib.rs +++ b/pop-api/examples/fungibles/lib.rs @@ -115,7 +115,7 @@ mod fungibles { } // Reverts with `InsufficientBalance` if the `value` exceeds the caller's balance. - if value > self.env().balance() { + if value > self.balance_of(caller) { return Err(PSP22Error::InsufficientBalance); } diff --git a/pop-api/examples/fungibles/tests.rs b/pop-api/examples/fungibles/tests.rs index 28093336..027f02c6 100644 --- a/pop-api/examples/fungibles/tests.rs +++ b/pop-api/examples/fungibles/tests.rs @@ -1,7 +1,11 @@ use drink::{sandbox_api::assets_api::AssetsAPI, session::Session}; use helpers::*; -use pop_api::primitives::TokenId; +use pop_api::{ + primitives::TokenId, + v0::fungibles::events::{Approval, Created, Transfer}, +}; use pop_sandbox::{Balance, Sandbox, ALICE, BOB}; +use scale::Encode; use super::*; @@ -15,15 +19,18 @@ enum BundleProvider {} fn new_constructor_works(mut session: Session) -> Result<(), Box> { let _ = env_logger::try_init(); // Deploy a new contract. - deploy_with_new_constructor( + let contract = deploy_with_new_constructor( &mut session, BundleProvider::local()?, TOKEN_ID, TOKEN_MIN_BALANCE, )?; - // Check if token exists after the deployment. + // Token exists after the deployment. assert!(session.sandbox().asset_exists(&TOKEN_ID)); - // Check if `Created` event is emitted. + let contract = account_id_from_slice(contract.as_ref()); + // Successfully emit event. + let expected = Created { id: TOKEN_ID, creator: contract, admin: contract }.encode(); + assert_eq!(last_contract_event(&session).unwrap(), expected.as_slice()); Ok(()) } @@ -36,8 +43,10 @@ fn new_existing_constructor_works(mut session: Session) -> Result<(), Box Result<(), Box Result<(), Box> { let _ = env_logger::try_init(); // Deploy a new contract. - let contract_address = deploy_with_new_constructor( + deploy_with_new_constructor( &mut session, BundleProvider::local()?, TOKEN_ID, @@ -54,11 +63,14 @@ fn mint_works(mut session: Session) -> Result<(), Box> { // Mint tokens. const AMOUNT: Balance = 12_000; mint(&mut session, ALICE, AMOUNT)?; - mint(&mut session, BOB, AMOUNT)?; - // Check if the tokens were minted with the right amount. - assert_eq!(total_supply(&mut session)?, AMOUNT * 2); + // Successfully emit event. + let expected = + Transfer { from: None, to: Some(account_id_from_slice(ALICE.as_ref())), value: AMOUNT } + .encode(); + assert_eq!(last_contract_event(&session).unwrap(), expected.as_slice()); + // Tokens were minted with the right amount. + assert_eq!(total_supply(&mut session)?, AMOUNT); assert_eq!(balance_of(&mut session, ALICE)?, AMOUNT); - assert_eq!(balance_of(&mut session, BOB)?, AMOUNT); Ok(()) } @@ -66,7 +78,7 @@ fn mint_works(mut session: Session) -> Result<(), Box> { fn burn_works(mut session: Session) -> Result<(), Box> { let _ = env_logger::try_init(); // Deploy a new contract. - let contract_address = deploy_with_new_constructor( + deploy_with_new_constructor( &mut session, BundleProvider::local()?, TOKEN_ID, @@ -77,6 +89,11 @@ fn burn_works(mut session: Session) -> Result<(), Box> { mint(&mut session, ALICE, AMOUNT)?; // Burn tokens. burn(&mut session, ALICE, 1)?; + // Successfully emit event. + let expected = + Transfer { from: Some(account_id_from_slice(ALICE.as_ref())), to: None, value: 1 }.encode(); + assert_eq!(last_contract_event(&session).unwrap(), expected.as_slice()); + assert_eq!(total_supply(&mut session)?, AMOUNT - 1); assert_eq!(balance_of(&mut session, ALICE)?, AMOUNT - 1); Ok(()) @@ -86,7 +103,7 @@ fn burn_works(mut session: Session) -> Result<(), Box> { fn transfer_works(mut session: Session) -> Result<(), Box> { let _ = env_logger::try_init(); // Deploy a new contract. - let contract_address = deploy_with_new_constructor( + let contract = deploy_with_new_constructor( &mut session, BundleProvider::local()?, TOKEN_ID, @@ -95,11 +112,21 @@ fn transfer_works(mut session: Session) -> Result<(), Box // Mint tokens. const AMOUNT: Balance = 12_000; const TRANSFERED: Balance = 500; - mint(&mut session, contract_address.clone(), AMOUNT)?; + mint(&mut session, contract.clone(), AMOUNT)?; mint(&mut session, BOB, AMOUNT)?; - // Transfer tokens. + // Transfer tokens from `contract` to `account`. + session.set_actor(contract.clone()); transfer(&mut session, BOB, TRANSFERED)?; - assert_eq!(balance_of(&mut session, contract_address)?, AMOUNT - TRANSFERED); + // Successfully emit event. + let expected = Transfer { + from: Some(account_id_from_slice(contract.clone().as_ref())), + to: Some(account_id_from_slice(BOB.as_ref())), + value: TRANSFERED, + } + .encode(); + assert_eq!(last_contract_event(&session).unwrap(), expected.as_slice()); + + assert_eq!(balance_of(&mut session, contract)?, AMOUNT - TRANSFERED); assert_eq!(balance_of(&mut session, BOB)?, AMOUNT + TRANSFERED); Ok(()) } From e018e34777e0359a63e525b243ac3e75aeb97c6d Mon Sep 17 00:00:00 2001 From: chungquantin <56880684+chungquantin@users.noreply.github.com> Date: Fri, 20 Sep 2024 22:37:49 +0700 Subject: [PATCH 106/112] test: event assertion --- pop-api/examples/fungibles/Cargo.toml | 9 ++- pop-api/examples/fungibles/helpers.rs | 41 +++++----- pop-api/examples/fungibles/tests.rs | 110 +++++++++++++++++++++++--- 3 files changed, 123 insertions(+), 37 deletions(-) diff --git a/pop-api/examples/fungibles/Cargo.toml b/pop-api/examples/fungibles/Cargo.toml index c06bc0f5..a2960895 100644 --- a/pop-api/examples/fungibles/Cargo.toml +++ b/pop-api/examples/fungibles/Cargo.toml @@ -17,11 +17,16 @@ scale-info = { version = "2.6", default-features = false, features = [ ], optional = true } [dev-dependencies] -drink = { path = "../../../../pop-drink/drink" } env_logger = { version = "0.11.3" } -pop-sandbox = { path = "../../../pop-sandbox", default-features = false } serde_json = "1.0.114" +# Local +drink = { path = "../../../../pop-drink/drink" } +pop-sandbox = { path = "../../../pop-sandbox", default-features = false } + +# Substrate +frame-support = { version = "36.0.0", default-features = false } + [lib] path = "lib.rs" diff --git a/pop-api/examples/fungibles/helpers.rs b/pop-api/examples/fungibles/helpers.rs index 027528df..506904b5 100644 --- a/pop-api/examples/fungibles/helpers.rs +++ b/pop-api/examples/fungibles/helpers.rs @@ -1,6 +1,9 @@ // A set of helper methods to test the contract calls. -use drink::session::{bundle::ContractBundle, error::SessionError, Session, NO_SALT}; +use drink::{ + session::{bundle::ContractBundle, error::SessionError, Session, NO_SALT}, + DispatchError, +}; use pop_api::primitives::{AccountId, TokenId}; use pop_sandbox::{AccountId32, Balance, Sandbox, INIT_VALUE}; use scale::{Decode, Encode}; @@ -18,6 +21,11 @@ pub(super) fn last_contract_event(session: &Session) -> Option> session.record().last_event_batch().contract_events().last().cloned() } +/// Get the last contract execution result. +pub(super) fn last_contract_error(session: &Session) -> Option { + session.record().last_call_result().result.clone().err() +} + // Call a contract method and decode the returned data. pub(super) fn decoded_call( session: &mut Session, @@ -63,17 +71,12 @@ pub(super) fn deploy_with_new_existing_constructor( // Test methods for `PSP22`.` -pub(super) fn total_supply( - session: &mut Session, -) -> Result> { - Ok(decoded_call::(session, "Psp22::total_supply", vec![], None)?) +pub(super) fn total_supply(session: &mut Session) -> Balance { + decoded_call::(session, "Psp22::total_supply", vec![], None).unwrap() } -pub(super) fn balance_of( - session: &mut Session, - owner: AccountId32, -) -> Result> { - Ok(decoded_call::(session, "Psp22::balance_of", vec![owner.to_string()], None)?) +pub(super) fn balance_of(session: &mut Session, owner: AccountId32) -> Balance { + decoded_call::(session, "Psp22::balance_of", vec![owner.to_string()], None).unwrap() } pub(super) fn transfer( @@ -87,22 +90,16 @@ pub(super) fn transfer( // Test methods for `PSP22Metadata``. -pub(super) fn token_name( - session: &mut Session, -) -> Result> { - Ok(decoded_call::(session, "Psp22Metadata::token_name", vec![], None)?) +pub(super) fn token_name(session: &mut Session) -> String { + decoded_call::(session, "Psp22Metadata::token_name", vec![], None).unwrap() } -pub(super) fn token_symbol( - session: &mut Session, -) -> Result> { - Ok(decoded_call::(session, "Psp22Metadata::token_symbol", vec![], None)?) +pub(super) fn token_symbol(session: &mut Session) -> String { + decoded_call::(session, "Psp22Metadata::token_symbol", vec![], None).unwrap() } -pub(super) fn token_decimals( - session: &mut Session, -) -> Result> { - Ok(decoded_call::(session, "Psp22Metadata::token_decimals", vec![], None)?) +pub(super) fn token_decimals(session: &mut Session) -> u8 { + decoded_call::(session, "Psp22Metadata::token_decimals", vec![], None).unwrap() } // Test methods for `PSP22Mintable``. diff --git a/pop-api/examples/fungibles/tests.rs b/pop-api/examples/fungibles/tests.rs index 027f02c6..af3144d0 100644 --- a/pop-api/examples/fungibles/tests.rs +++ b/pop-api/examples/fungibles/tests.rs @@ -1,4 +1,8 @@ -use drink::{sandbox_api::assets_api::AssetsAPI, session::Session}; +use drink::{ + sandbox_api::assets_api::AssetsAPI, + session::{error::SessionError, Session}, +}; +use frame_support::assert_ok; use helpers::*; use pop_api::{ primitives::TokenId, @@ -50,6 +54,18 @@ fn new_existing_constructor_works(mut session: Session) -> Result<(), Box Result<(), Box> { + let _ = env_logger::try_init(); + + let result = + deploy_with_new_existing_constructor(&mut session, BundleProvider::local()?, TOKEN_ID); + assert!(result.is_err()); + Ok(()) +} + #[drink::test(sandbox = Sandbox)] fn mint_works(mut session: Session) -> Result<(), Box> { let _ = env_logger::try_init(); @@ -62,15 +78,35 @@ fn mint_works(mut session: Session) -> Result<(), Box> { )?; // Mint tokens. const AMOUNT: Balance = 12_000; - mint(&mut session, ALICE, AMOUNT)?; + assert_ok!(mint(&mut session, ALICE, AMOUNT)); // Successfully emit event. let expected = Transfer { from: None, to: Some(account_id_from_slice(ALICE.as_ref())), value: AMOUNT } .encode(); assert_eq!(last_contract_event(&session).unwrap(), expected.as_slice()); // Tokens were minted with the right amount. - assert_eq!(total_supply(&mut session)?, AMOUNT); - assert_eq!(balance_of(&mut session, ALICE)?, AMOUNT); + assert_eq!(total_supply(&mut session), AMOUNT); + assert_eq!(balance_of(&mut session, ALICE), AMOUNT); + Ok(()) +} + +#[drink::test(sandbox = Sandbox)] +fn mint_zero_value_works(mut session: Session) -> Result<(), Box> { + let _ = env_logger::try_init(); + // Deploy a new contract. + deploy_with_new_constructor( + &mut session, + BundleProvider::local()?, + TOKEN_ID, + TOKEN_MIN_BALANCE, + )?; + // Mint tokens. + assert_ok!(mint(&mut session, ALICE, 0)); + // No event emitted. + assert_eq!(last_contract_event(&session), None); + // Tokens were minted with the right amount. + assert_eq!(total_supply(&mut session), 0); + assert_eq!(balance_of(&mut session, ALICE), 0); Ok(()) } @@ -86,16 +122,64 @@ fn burn_works(mut session: Session) -> Result<(), Box> { )?; // Mint tokens. const AMOUNT: Balance = 12_000; - mint(&mut session, ALICE, AMOUNT)?; + assert_ok!(mint(&mut session, ALICE, AMOUNT)); // Burn tokens. - burn(&mut session, ALICE, 1)?; + assert_ok!(burn(&mut session, ALICE, 1)); // Successfully emit event. let expected = Transfer { from: Some(account_id_from_slice(ALICE.as_ref())), to: None, value: 1 }.encode(); assert_eq!(last_contract_event(&session).unwrap(), expected.as_slice()); - assert_eq!(total_supply(&mut session)?, AMOUNT - 1); - assert_eq!(balance_of(&mut session, ALICE)?, AMOUNT - 1); + assert_eq!(total_supply(&mut session), AMOUNT - 1); + assert_eq!(balance_of(&mut session, ALICE), AMOUNT - 1); + Ok(()) +} + +#[drink::test(sandbox = Sandbox)] +fn burn_zero_value_works(mut session: Session) -> Result<(), Box> { + let _ = env_logger::try_init(); + // Deploy a new contract. + deploy_with_new_constructor( + &mut session, + BundleProvider::local()?, + TOKEN_ID, + TOKEN_MIN_BALANCE, + )?; + // Burn tokens. + assert_ok!(burn(&mut session, ALICE, 0)); + // No event emitted. + assert_eq!(last_contract_event(&session), None); + // Tokens were minted with the right amount. + assert_eq!(total_supply(&mut session), 0); + assert_eq!(balance_of(&mut session, ALICE), 0); + Ok(()) +} + +#[drink::test(sandbox = Sandbox)] +fn burn_fails_with_insufficient_amount( + mut session: Session, +) -> Result<(), Box> { + let _ = env_logger::try_init(); + // Deploy a new contract. + deploy_with_new_constructor( + &mut session, + BundleProvider::local()?, + TOKEN_ID, + TOKEN_MIN_BALANCE, + )?; + // Mint tokens. + const AMOUNT: Balance = 12_000; + assert_ok!(mint(&mut session, ALICE, AMOUNT)); + + // Burn tokens reverted with `InsufficientBalance`. + let function: &str = "Psp22Burnable::burn"; + let params: Vec = vec![ALICE.to_string(), (AMOUNT + 1).to_string()]; + let call = session.call::(function, ¶ms, None); + + // TODO: Failed assertion [0, 1, 1] and [1]. + if let Err(SessionError::CallReverted(error)) = call { + assert_eq!(error, PSP22Error::InsufficientBalance.encode()); + } Ok(()) } @@ -112,11 +196,11 @@ fn transfer_works(mut session: Session) -> Result<(), Box // Mint tokens. const AMOUNT: Balance = 12_000; const TRANSFERED: Balance = 500; - mint(&mut session, contract.clone(), AMOUNT)?; - mint(&mut session, BOB, AMOUNT)?; + assert_ok!(mint(&mut session, contract.clone(), AMOUNT)); + assert_ok!(mint(&mut session, BOB, AMOUNT)); // Transfer tokens from `contract` to `account`. session.set_actor(contract.clone()); - transfer(&mut session, BOB, TRANSFERED)?; + assert_ok!(transfer(&mut session, BOB, TRANSFERED)); // Successfully emit event. let expected = Transfer { from: Some(account_id_from_slice(contract.clone().as_ref())), @@ -126,7 +210,7 @@ fn transfer_works(mut session: Session) -> Result<(), Box .encode(); assert_eq!(last_contract_event(&session).unwrap(), expected.as_slice()); - assert_eq!(balance_of(&mut session, contract)?, AMOUNT - TRANSFERED); - assert_eq!(balance_of(&mut session, BOB)?, AMOUNT + TRANSFERED); + assert_eq!(balance_of(&mut session, contract), AMOUNT - TRANSFERED); + assert_eq!(balance_of(&mut session, BOB), AMOUNT + TRANSFERED); Ok(()) } From baab872ce12afae46a01edb7114afe7c6f445021 Mon Sep 17 00:00:00 2001 From: chungquantin <56880684+chungquantin@users.noreply.github.com> Date: Fri, 20 Sep 2024 22:53:39 +0700 Subject: [PATCH 107/112] refactor: call expect error methods & function constant --- pop-api/examples/fungibles/lib.rs | 4 +- pop-api/examples/fungibles/tests.rs | 17 +++---- .../fungibles/{helpers.rs => utils.rs} | 51 ++++++++++++------- 3 files changed, 41 insertions(+), 31 deletions(-) rename pop-api/examples/fungibles/{helpers.rs => utils.rs} (66%) diff --git a/pop-api/examples/fungibles/lib.rs b/pop-api/examples/fungibles/lib.rs index d7dc7d95..b84bec4e 100644 --- a/pop-api/examples/fungibles/lib.rs +++ b/pop-api/examples/fungibles/lib.rs @@ -11,10 +11,10 @@ use pop_api::{ }, }; -#[cfg(test)] -mod helpers; #[cfg(test)] mod tests; +#[cfg(test)] +mod utils; #[ink::contract] mod fungibles { diff --git a/pop-api/examples/fungibles/tests.rs b/pop-api/examples/fungibles/tests.rs index af3144d0..99b97cfd 100644 --- a/pop-api/examples/fungibles/tests.rs +++ b/pop-api/examples/fungibles/tests.rs @@ -3,13 +3,13 @@ use drink::{ session::{error::SessionError, Session}, }; use frame_support::assert_ok; -use helpers::*; use pop_api::{ primitives::TokenId, v0::fungibles::events::{Approval, Created, Transfer}, }; use pop_sandbox::{Balance, Sandbox, ALICE, BOB}; use scale::Encode; +use utils::*; use super::*; @@ -170,16 +170,13 @@ fn burn_fails_with_insufficient_amount( // Mint tokens. const AMOUNT: Balance = 12_000; assert_ok!(mint(&mut session, ALICE, AMOUNT)); - // Burn tokens reverted with `InsufficientBalance`. - let function: &str = "Psp22Burnable::burn"; - let params: Vec = vec![ALICE.to_string(), (AMOUNT + 1).to_string()]; - let call = session.call::(function, ¶ms, None); - - // TODO: Failed assertion [0, 1, 1] and [1]. - if let Err(SessionError::CallReverted(error)) = call { - assert_eq!(error, PSP22Error::InsufficientBalance.encode()); - } + expect_call_reverted( + &mut session, + BURN, + vec![ALICE.to_string(), (AMOUNT + 1).to_string()], + PSP22Error::InsufficientBalance, + ); Ok(()) } diff --git a/pop-api/examples/fungibles/helpers.rs b/pop-api/examples/fungibles/utils.rs similarity index 66% rename from pop-api/examples/fungibles/helpers.rs rename to pop-api/examples/fungibles/utils.rs index 506904b5..baff68e5 100644 --- a/pop-api/examples/fungibles/helpers.rs +++ b/pop-api/examples/fungibles/utils.rs @@ -10,6 +10,19 @@ use scale::{Decode, Encode}; use super::*; +// PSP22 functions. +pub const BALANCE_OF: &str = "Psp22::balance_of"; +pub const TOTAL_SUPPLY: &str = "Psp22::total_supply"; +pub const TRANSFER: &str = "Psp22::transfer"; +// PSP22Metadata functions. +pub const TOKEN_NAME: &str = "Psp22Metadata::token_name"; +pub const TOKEN_SYMBOL: &str = "Psp22Metadata::token_symbol"; +pub const TOKEN_DECIMALS: &str = "Psp22Metadata::token_decimals"; +// PSP22Mintable functions. +pub const MINT: &str = "Psp22Mintable::mint"; +// PSP22Burnable functions. +pub const BURN: &str = "Psp22Burnable::burn"; + /// This is used to resolve type mismatches between the `AccountId` in the quasi testing environment and the /// contract environment. pub(super) fn account_id_from_slice(s: &[u8; 32]) -> AccountId { @@ -21,9 +34,17 @@ pub(super) fn last_contract_event(session: &Session) -> Option> session.record().last_event_batch().contract_events().last().cloned() } -/// Get the last contract execution result. -pub(super) fn last_contract_error(session: &Session) -> Option { - session.record().last_call_result().result.clone().err() +/// Execute a contract method and exepct CallReverted error to be returned. +pub(super) fn expect_call_reverted( + session: &mut Session, + function: &str, + params: Vec, + err: PSP22Error, +) { + let call = session.call::(function, ¶ms, None); + if let Err(SessionError::CallReverted(error)) = call { + assert_eq!(error[1..], Err::<(), PSP22Error>(err).encode()); + } } // Call a contract method and decode the returned data. @@ -72,11 +93,11 @@ pub(super) fn deploy_with_new_existing_constructor( // Test methods for `PSP22`.` pub(super) fn total_supply(session: &mut Session) -> Balance { - decoded_call::(session, "Psp22::total_supply", vec![], None).unwrap() + decoded_call::(session, TOTAL_SUPPLY, vec![], None).unwrap() } pub(super) fn balance_of(session: &mut Session, owner: AccountId32) -> Balance { - decoded_call::(session, "Psp22::balance_of", vec![owner.to_string()], None).unwrap() + decoded_call::(session, BALANCE_OF, vec![owner.to_string()], None).unwrap() } pub(super) fn transfer( @@ -85,21 +106,21 @@ pub(super) fn transfer( amount: Balance, ) -> Result<(), Box> { let data = serde_json::to_string::<[u8; 0]>(&[]).unwrap(); - Ok(session.call("Psp22::transfer", &vec![to.to_string(), amount.to_string(), data], None)??) + Ok(session.call(TRANSFER, &vec![to.to_string(), amount.to_string(), data], None)??) } // Test methods for `PSP22Metadata``. pub(super) fn token_name(session: &mut Session) -> String { - decoded_call::(session, "Psp22Metadata::token_name", vec![], None).unwrap() + decoded_call::(session, TOKEN_NAME, vec![], None).unwrap() } pub(super) fn token_symbol(session: &mut Session) -> String { - decoded_call::(session, "Psp22Metadata::token_symbol", vec![], None).unwrap() + decoded_call::(session, TOKEN_SYMBOL, vec![], None).unwrap() } pub(super) fn token_decimals(session: &mut Session) -> u8 { - decoded_call::(session, "Psp22Metadata::token_decimals", vec![], None).unwrap() + decoded_call::(session, TOKEN_DECIMALS, vec![], None).unwrap() } // Test methods for `PSP22Mintable``. @@ -109,11 +130,7 @@ pub(super) fn mint( account: AccountId32, amount: Balance, ) -> Result<(), Box> { - Ok(session.call( - "Psp22Mintable::mint", - &vec![account.to_string(), amount.to_string()], - None, - )??) + Ok(session.call(MINT, &vec![account.to_string(), amount.to_string()], None)??) } // Test methods for `PSP22MPsp22Burnablentable``. @@ -123,9 +140,5 @@ pub(super) fn burn( account: AccountId32, amount: Balance, ) -> Result<(), Box> { - Ok(session.call( - "Psp22Burnable::burn", - &vec![account.to_string(), amount.to_string()], - None, - )??) + Ok(session.call(BURN, &vec![account.to_string(), amount.to_string()], None)??) } From cb48a4de6f767fd4176a6ac7da6e0ab93e621115 Mon Sep 17 00:00:00 2001 From: chungquantin <56880684+chungquantin@users.noreply.github.com> Date: Sat, 21 Sep 2024 01:31:43 +0700 Subject: [PATCH 108/112] test: add more test cases --- pop-api/examples/fungibles/lib.rs | 7 +- pop-api/examples/fungibles/tests.rs | 198 +++++++++++++++++++++++++++- pop-api/examples/fungibles/utils.rs | 54 +++++++- 3 files changed, 247 insertions(+), 12 deletions(-) diff --git a/pop-api/examples/fungibles/lib.rs b/pop-api/examples/fungibles/lib.rs index b84bec4e..69d22247 100644 --- a/pop-api/examples/fungibles/lib.rs +++ b/pop-api/examples/fungibles/lib.rs @@ -196,9 +196,9 @@ mod fungibles { return Ok(()); } + let allowance = self.allowance(caller, spender); api::increase_allowance(self.id, spender, value).map_err(PSP22Error::from)?; - let allowance = self.allowance(caller, spender).saturating_add(value); - self.emit_approval_event(caller, spender, allowance); + self.emit_approval_event(caller, spender, allowance.saturating_add(value)); Ok(()) } @@ -224,8 +224,7 @@ mod fungibles { } api::decrease_allowance(self.id, spender, value).map_err(PSP22Error::from)?; - let allowance = allowance.saturating_sub(value); - self.emit_approval_event(caller, spender, allowance); + self.emit_approval_event(caller, spender, allowance.saturating_sub(value)); Ok(()) } } diff --git a/pop-api/examples/fungibles/tests.rs b/pop-api/examples/fungibles/tests.rs index 99b97cfd..7046d83f 100644 --- a/pop-api/examples/fungibles/tests.rs +++ b/pop-api/examples/fungibles/tests.rs @@ -66,6 +66,25 @@ fn new_existing_constructor_deployment_fails( Ok(()) } +#[drink::test(sandbox = Sandbox)] +fn balance_of_works(mut session: Session) -> Result<(), Box> { + let _ = env_logger::try_init(); + // Deploy a new contract. + deploy_with_new_constructor( + &mut session, + BundleProvider::local()?, + TOKEN_ID, + TOKEN_MIN_BALANCE, + )?; + // Mint tokens. + const AMOUNT: Balance = 12_000; + assert_ok!(mint(&mut session, ALICE, AMOUNT)); + // Tokens were minted with the right amount. + assert_eq!(balance_of(&mut session, ALICE), AMOUNT); + assert_eq!(balance_of(&mut session, ALICE), session.sandbox().balance_of(&TOKEN_ID, &ALICE)); + Ok(()) +} + #[drink::test(sandbox = Sandbox)] fn mint_works(mut session: Session) -> Result<(), Box> { let _ = env_logger::try_init(); @@ -156,7 +175,7 @@ fn burn_zero_value_works(mut session: Session) -> Result<(), Box Result<(), Box> { let _ = env_logger::try_init(); @@ -170,7 +189,7 @@ fn burn_fails_with_insufficient_amount( // Mint tokens. const AMOUNT: Balance = 12_000; assert_ok!(mint(&mut session, ALICE, AMOUNT)); - // Burn tokens reverted with `InsufficientBalance`. + // Failed with `InsufficientBalance`. expect_call_reverted( &mut session, BURN, @@ -192,22 +211,187 @@ fn transfer_works(mut session: Session) -> Result<(), Box )?; // Mint tokens. const AMOUNT: Balance = 12_000; - const TRANSFERED: Balance = 500; + const TRANSFERRED: Balance = 500; assert_ok!(mint(&mut session, contract.clone(), AMOUNT)); assert_ok!(mint(&mut session, BOB, AMOUNT)); // Transfer tokens from `contract` to `account`. session.set_actor(contract.clone()); - assert_ok!(transfer(&mut session, BOB, TRANSFERED)); + assert_ok!(transfer(&mut session, BOB, TRANSFERRED)); // Successfully emit event. let expected = Transfer { from: Some(account_id_from_slice(contract.clone().as_ref())), to: Some(account_id_from_slice(BOB.as_ref())), - value: TRANSFERED, + value: TRANSFERRED, + } + .encode(); + assert_eq!(last_contract_event(&session).unwrap(), expected.as_slice()); + + assert_eq!(balance_of(&mut session, contract), AMOUNT - TRANSFERRED); + assert_eq!(balance_of(&mut session, BOB), AMOUNT + TRANSFERRED); + Ok(()) +} + +#[drink::test(sandbox = Sandbox)] +fn transfer_zero_value_works(mut session: Session) -> Result<(), Box> { + let _ = env_logger::try_init(); + // Deploy a new contract. + deploy_with_new_constructor( + &mut session, + BundleProvider::local()?, + TOKEN_ID, + TOKEN_MIN_BALANCE, + )?; + assert_ok!(transfer(&mut session, ALICE, 0)); + // No event emitted. + assert_eq!(last_contract_event(&session), None); + Ok(()) +} + +#[drink::test(sandbox = Sandbox)] +fn transfer_fails_with_insufficient_balance( + mut session: Session, +) -> Result<(), Box> { + let _ = env_logger::try_init(); + // Deploy a new contract. + let contract = deploy_with_new_constructor( + &mut session, + BundleProvider::local()?, + TOKEN_ID, + TOKEN_MIN_BALANCE, + )?; + // Mint tokens. + const AMOUNT: Balance = 12_000; + assert_ok!(mint(&mut session, contract.clone(), AMOUNT)); + assert_ok!(mint(&mut session, BOB, AMOUNT)); + + session.set_actor(contract.clone()); + // Failed with `InsufficientBalance`. + expect_call_reverted( + &mut session, + TRANSFER, + vec![BOB.to_string(), (AMOUNT + 1).to_string()], + PSP22Error::InsufficientBalance, + ); + Ok(()) +} + +#[drink::test(sandbox = Sandbox)] +fn approve_works(mut session: Session) -> Result<(), Box> { + let _ = env_logger::try_init(); + // Deploy a new contract. + let contract = deploy_with_new_constructor( + &mut session, + BundleProvider::local()?, + TOKEN_ID, + TOKEN_MIN_BALANCE, + )?; + + const AMOUNT: Balance = 12_000; + // Mint tokens. + assert_ok!(mint(&mut session, contract.clone(), AMOUNT)); + // Successfully apporve. + session.set_actor(contract.clone()); + assert_ok!(approve(&mut session, ALICE, AMOUNT / 2)); + // Successfully emit event. + let expected = Approval { + owner: account_id_from_slice(contract.clone().as_ref()), + spender: account_id_from_slice(ALICE.as_ref()), + value: AMOUNT / 2, + } + .encode(); + assert_eq!(last_contract_event(&session).unwrap(), expected.as_slice()); + assert_eq!(allowance(&mut session, contract, ALICE), AMOUNT / 2); + Ok(()) +} + +#[drink::test(sandbox = Sandbox)] +fn increase_allowance_works(mut session: Session) -> Result<(), Box> { + let _ = env_logger::try_init(); + // Deploy a new contract. + let contract = deploy_with_new_constructor( + &mut session, + BundleProvider::local()?, + TOKEN_ID, + TOKEN_MIN_BALANCE, + )?; + + const AMOUNT: Balance = 12_000; + // Mint tokens. + assert_ok!(mint(&mut session, contract.clone(), AMOUNT)); + // Successfully apporve. + session.set_actor(contract.clone()); + assert_ok!(approve(&mut session, ALICE, AMOUNT / 2)); + assert_ok!(increase_allowance(&mut session, ALICE, AMOUNT / 2)); + // Successfully emit event. + let expected = Approval { + owner: account_id_from_slice(contract.clone().as_ref()), + spender: account_id_from_slice(ALICE.as_ref()), + value: AMOUNT, } .encode(); assert_eq!(last_contract_event(&session).unwrap(), expected.as_slice()); + assert_eq!(allowance(&mut session, contract, ALICE), AMOUNT); + Ok(()) +} - assert_eq!(balance_of(&mut session, contract), AMOUNT - TRANSFERED); - assert_eq!(balance_of(&mut session, BOB), AMOUNT + TRANSFERED); +#[drink::test(sandbox = Sandbox)] +fn decrease_allowance_works(mut session: Session) -> Result<(), Box> { + let _ = env_logger::try_init(); + // Deploy a new contract. + let contract = deploy_with_new_constructor( + &mut session, + BundleProvider::local()?, + TOKEN_ID, + TOKEN_MIN_BALANCE, + )?; + + const AMOUNT: Balance = 12_000; + // Mint tokens. + assert_ok!(mint(&mut session, contract.clone(), AMOUNT)); + // Successfully apporve. + session.set_actor(contract.clone()); + assert_ok!(approve(&mut session, ALICE, AMOUNT / 2)); + assert_ok!(decrease_allowance(&mut session, ALICE, 1)); + // Successfully emit event. + let expected = Approval { + owner: account_id_from_slice(contract.clone().as_ref()), + spender: account_id_from_slice(ALICE.as_ref()), + value: AMOUNT / 2 - 1, + } + .encode(); + assert_eq!(last_contract_event(&session).unwrap(), expected.as_slice()); + assert_eq!(allowance(&mut session, contract, ALICE), AMOUNT / 2 - 1); + Ok(()) +} + +#[drink::test(sandbox = Sandbox)] +fn transfer_from_works(mut session: Session) -> Result<(), Box> { + let _ = env_logger::try_init(); + // Deploy a new contract. + let contract = deploy_with_new_constructor( + &mut session, + BundleProvider::local()?, + TOKEN_ID, + TOKEN_MIN_BALANCE, + )?; + + const AMOUNT: Balance = 12_000; + // Mint tokens. + assert_ok!(mint(&mut session, contract.clone(), AMOUNT)); + // Successfully transfer from `owner`. + session.set_actor(contract.clone()); + assert_ok!(approve(&mut session, ALICE, AMOUNT / 2)); + assert_eq!(allowance(&mut session, contract.clone(), ALICE), AMOUNT / 2); + + session.set_actor(ALICE); + assert_ok!(transfer_from(&mut session, contract, BOB, AMOUNT / 2)); + // Successfully emit event. + let expected = Transfer { + from: Some(account_id_from_slice(ALICE.as_ref())), + to: Some(account_id_from_slice(BOB.as_ref())), + value: AMOUNT / 4, + } + .encode(); + assert_eq!(last_contract_event(&session).unwrap(), expected.as_slice()); Ok(()) } diff --git a/pop-api/examples/fungibles/utils.rs b/pop-api/examples/fungibles/utils.rs index baff68e5..38968afd 100644 --- a/pop-api/examples/fungibles/utils.rs +++ b/pop-api/examples/fungibles/utils.rs @@ -11,9 +11,14 @@ use scale::{Decode, Encode}; use super::*; // PSP22 functions. +pub const ALLOWANCE: &str = "Psp22::allowance"; pub const BALANCE_OF: &str = "Psp22::balance_of"; pub const TOTAL_SUPPLY: &str = "Psp22::total_supply"; pub const TRANSFER: &str = "Psp22::transfer"; +pub const TRANSFER_FROM: &str = "Psp22::transfer_from"; +pub const APPROVE: &str = "Psp22::approve"; +pub const INCREASE_ALLOWANCE: &str = "Psp22::increase_allowance"; +pub const DECREASE_ALLOWANCE: &str = "Psp22::decrease_allowance"; // PSP22Metadata functions. pub const TOKEN_NAME: &str = "Psp22Metadata::token_name"; pub const TOKEN_SYMBOL: &str = "Psp22Metadata::token_symbol"; @@ -90,7 +95,7 @@ pub(super) fn deploy_with_new_existing_constructor( session.deploy_bundle(bundle, "new_existing", &[id.to_string()], NO_SALT, Some(INIT_VALUE)) } -// Test methods for `PSP22`.` +// Test methods for `PSP22`. pub(super) fn total_supply(session: &mut Session) -> Balance { decoded_call::(session, TOTAL_SUPPLY, vec![], None).unwrap() @@ -100,6 +105,15 @@ pub(super) fn balance_of(session: &mut Session, owner: AccountId32) -> decoded_call::(session, BALANCE_OF, vec![owner.to_string()], None).unwrap() } +pub(super) fn allowance( + session: &mut Session, + owner: AccountId32, + spender: AccountId32, +) -> Balance { + decoded_call::(session, ALLOWANCE, vec![owner.to_string(), spender.to_string()], None) + .unwrap() +} + pub(super) fn transfer( session: &mut Session, to: AccountId32, @@ -109,6 +123,44 @@ pub(super) fn transfer( Ok(session.call(TRANSFER, &vec![to.to_string(), amount.to_string(), data], None)??) } +pub(super) fn transfer_from( + session: &mut Session, + from: AccountId32, + to: AccountId32, + amount: Balance, +) -> Result<(), Box> { + let data = serde_json::to_string::<[u8; 0]>(&[]).unwrap(); + Ok(session.call( + TRANSFER_FROM, + &vec![from.to_string(), to.to_string(), amount.to_string(), data], + None, + )??) +} + +pub(super) fn approve( + session: &mut Session, + spender: AccountId32, + value: Balance, +) -> Result<(), Box> { + Ok(session.call(APPROVE, &vec![spender.to_string(), value.to_string()], None)??) +} + +pub(super) fn increase_allowance( + session: &mut Session, + spender: AccountId32, + value: Balance, +) -> Result<(), Box> { + Ok(session.call(INCREASE_ALLOWANCE, &vec![spender.to_string(), value.to_string()], None)??) +} + +pub(super) fn decrease_allowance( + session: &mut Session, + spender: AccountId32, + value: Balance, +) -> Result<(), Box> { + Ok(session.call(DECREASE_ALLOWANCE, &vec![spender.to_string(), value.to_string()], None)??) +} + // Test methods for `PSP22Metadata``. pub(super) fn token_name(session: &mut Session) -> String { From ce009a1c45c782e387649af1e8e2541d7c386513 Mon Sep 17 00:00:00 2001 From: chungquantin <56880684+chungquantin@users.noreply.github.com> Date: Sat, 21 Sep 2024 09:50:04 +0700 Subject: [PATCH 109/112] fix: extension origin --- extension/src/environment.rs | 26 +++++++++++++++++++------- extension/src/functions.rs | 20 ++++++++++---------- extension/src/mock.rs | 4 ++-- pop-api/examples/fungibles/tests.rs | 1 + 4 files changed, 32 insertions(+), 19 deletions(-) diff --git a/extension/src/environment.rs b/extension/src/environment.rs index dc3818e8..08b61625 100644 --- a/extension/src/environment.rs +++ b/extension/src/environment.rs @@ -1,7 +1,10 @@ use core::fmt::Debug; use frame_support::pallet_prelude::Weight; -use pallet_contracts::chain_extension::{BufInBufOutState, ChargedAmount, Result, State}; +use pallet_contracts::{ + chain_extension::{BufInBufOutState, ChargedAmount, Result, State}, + Origin, +}; use sp_std::vec::Vec; use crate::AccountIdOf; @@ -168,14 +171,14 @@ pub trait Ext { type AccountId; /// Returns a reference to the account id of the current contract. - fn address(&self) -> &Self::AccountId; + fn address(&self) -> Self::AccountId; } impl Ext for () { type AccountId = (); - fn address(&self) -> &Self::AccountId { - &() + fn address(&self) -> Self::AccountId { + () } } @@ -185,12 +188,21 @@ pub(crate) struct ExternalEnvironment<'a, T: pallet_contracts::chain_extension:: impl<'a, E: pallet_contracts::chain_extension::Ext> Ext for ExternalEnvironment<'a, E> { type AccountId = AccountIdOf; - fn address(&self) -> &Self::AccountId { - self.0.address() + fn address(&self) -> Self::AccountId { + match self.0.caller() { + Origin::Root => { + log::debug!("origin=root"); + self.0.address().clone() + }, + Origin::Signed(caller) => { + log::debug!("origin=signed({:?}) | contract({:?})", caller, self.0.address()); + caller + }, + } } } #[test] fn default_ext_works() { - assert_eq!(().address(), &()) + assert_eq!(().address(), ()) } diff --git a/extension/src/functions.rs b/extension/src/functions.rs index 73a5fdf9..257efe89 100644 --- a/extension/src/functions.rs +++ b/extension/src/functions.rs @@ -53,7 +53,7 @@ impl< let charged = env.charge_weight(dispatch_info.weight)?; log::debug!(target: Logger::LOG_TARGET, "pre-dispatch weight charged: charged={charged:?}"); // Contract is the origin by default. - let origin = RawOrigin::Signed(env.ext().address().clone()); + let origin = RawOrigin::Signed(env.ext().address()); log::debug!(target: Logger::LOG_TARGET, "contract origin: origin={origin:?}"); let mut origin: Config::RuntimeOrigin = origin.into(); // Ensure call allowed. @@ -323,8 +323,8 @@ mod tests { assert!(DispatchCallWithFilter::::execute(&mut env).is_err()); assert_eq!( env.charged(), - read_from_buffer_weight(encoded_call.len() as u32) + - call.get_dispatch_info().weight + read_from_buffer_weight(encoded_call.len() as u32) + + call.get_dispatch_info().weight ); } @@ -362,8 +362,8 @@ mod tests { assert!(DispatchCall::execute(&mut env).is_ok()); assert_eq!( env.charged(), - read_from_buffer_weight(encoded_call.len() as u32) + - call.get_dispatch_info().weight + read_from_buffer_weight(encoded_call.len() as u32) + + call.get_dispatch_info().weight ); }) } @@ -387,9 +387,9 @@ mod tests { assert_eq!(call.get_dispatch_info().weight, migrate_weight + weight_limit); assert_eq!( env.charged(), - read_from_buffer_weight(encoded_call.len() as u32) + - call.get_dispatch_info().weight - - extra_weight + read_from_buffer_weight(encoded_call.len() as u32) + + call.get_dispatch_info().weight + - extra_weight ); }) } @@ -488,8 +488,8 @@ mod tests { let expected = "pop".as_bytes().encode(); assert_eq!( env.charged(), - read_from_buffer_weight(encoded_read.len() as u32) + - read.weight() + write_to_contract_weight(expected.len() as u32) + read_from_buffer_weight(encoded_read.len() as u32) + + read.weight() + write_to_contract_weight(expected.len() as u32) ); } diff --git a/extension/src/mock.rs b/extension/src/mock.rs index c085aebe..b267b3e3 100644 --- a/extension/src/mock.rs +++ b/extension/src/mock.rs @@ -350,8 +350,8 @@ pub(crate) struct MockExt { impl environment::Ext for MockExt { type AccountId = AccountIdOf; - fn address(&self) -> &Self::AccountId { - &self.address + fn address(&self) -> Self::AccountId { + self.address } } diff --git a/pop-api/examples/fungibles/tests.rs b/pop-api/examples/fungibles/tests.rs index 7046d83f..a0241838 100644 --- a/pop-api/examples/fungibles/tests.rs +++ b/pop-api/examples/fungibles/tests.rs @@ -364,6 +364,7 @@ fn decrease_allowance_works(mut session: Session) -> Result<(), Box Result<(), Box> { let _ = env_logger::try_init(); From e5f84aaf08fbd38cdc57bc8482183f3484f2c70f Mon Sep 17 00:00:00 2001 From: chungquantin <56880684+chungquantin@users.noreply.github.com> Date: Sat, 21 Sep 2024 10:34:05 +0700 Subject: [PATCH 110/112] test: transfer_from --- pop-api/examples/fungibles/lib.rs | 9 +++-- pop-api/examples/fungibles/tests.rs | 51 +++++++++++++++++++++-------- pop-api/examples/fungibles/utils.rs | 3 +- 3 files changed, 44 insertions(+), 19 deletions(-) diff --git a/pop-api/examples/fungibles/lib.rs b/pop-api/examples/fungibles/lib.rs index 69d22247..04b432b9 100644 --- a/pop-api/examples/fungibles/lib.rs +++ b/pop-api/examples/fungibles/lib.rs @@ -67,14 +67,13 @@ mod fungibles { #[ink(constructor, payable)] pub fn new( id: TokenId, - // TODO: If admin is different than the contract address, `NoPermission` thrown for mint, burn - // _admin: AccountId, + admin: AccountId, min_balance: Balance, ) -> Result { let mut contract = Self { id }; let contract_id = contract.env().account_id(); - api::create(id, contract_id, min_balance).map_err(PSP22Error::from)?; - contract.emit_created_event(id, contract_id, contract_id); + api::create(id, admin, min_balance).map_err(PSP22Error::from)?; + contract.emit_created_event(id, contract_id, admin); Ok(contract) } } @@ -161,7 +160,7 @@ mod fungibles { api::transfer_from(self.id, from, to, value).map_err(PSP22Error::from)?; // Emit events. self.emit_transfer_event(Some(caller), Some(to), value); - let allowance = self.allowance(from, to).saturating_sub(value); + let allowance = self.allowance(from, caller).saturating_sub(value); self.emit_approval_event(from, caller, allowance); Ok(()) } diff --git a/pop-api/examples/fungibles/tests.rs b/pop-api/examples/fungibles/tests.rs index a0241838..c04ab566 100644 --- a/pop-api/examples/fungibles/tests.rs +++ b/pop-api/examples/fungibles/tests.rs @@ -27,13 +27,18 @@ fn new_constructor_works(mut session: Session) -> Result<(), Box Result<(), Box Result<(), Box> { &mut session, BundleProvider::local()?, TOKEN_ID, + ALICE, TOKEN_MIN_BALANCE, )?; // Mint tokens. @@ -117,6 +124,7 @@ fn mint_zero_value_works(mut session: Session) -> Result<(), Box Result<(), Box> { &mut session, BundleProvider::local()?, TOKEN_ID, + ALICE, TOKEN_MIN_BALANCE, )?; // Mint tokens. @@ -162,6 +171,7 @@ fn burn_zero_value_works(mut session: Session) -> Result<(), Box Result<(), Box &mut session, BundleProvider::local()?, TOKEN_ID, + ALICE, TOKEN_MIN_BALANCE, )?; // Mint tokens. @@ -239,6 +251,7 @@ fn transfer_zero_value_works(mut session: Session) -> Result<(), Box Result<(), Box> &mut session, BundleProvider::local()?, TOKEN_ID, + ALICE, TOKEN_MIN_BALANCE, )?; @@ -312,6 +327,7 @@ fn increase_allowance_works(mut session: Session) -> Result<(), Box Result<(), Box Result<(), Box Result<(), Box> { let _ = env_logger::try_init(); @@ -373,26 +389,35 @@ fn transfer_from_works(mut session: Session) -> Result<(), Box, bundle: ContractBundle, id: TokenId, + admin: AccountId32, min_balance: Balance, ) -> Result { session.deploy_bundle( bundle, "new", - &[id.to_string(), min_balance.to_string()], + &[id.to_string(), admin.to_string(), min_balance.to_string()], NO_SALT, Some(INIT_VALUE), ) From 6f17c098132e5c46a7d011d60f1a3826422653cc Mon Sep 17 00:00:00 2001 From: chungquantin <56880684+chungquantin@users.noreply.github.com> Date: Sat, 21 Sep 2024 10:35:48 +0700 Subject: [PATCH 111/112] chore: add TODO --- extension/src/environment.rs | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/extension/src/environment.rs b/extension/src/environment.rs index 08b61625..e57c28bf 100644 --- a/extension/src/environment.rs +++ b/extension/src/environment.rs @@ -189,15 +189,10 @@ impl<'a, E: pallet_contracts::chain_extension::Ext> Ext for ExternalEnvironment< type AccountId = AccountIdOf; fn address(&self) -> Self::AccountId { + // TODO: Need to decide which address to return. match self.0.caller() { - Origin::Root => { - log::debug!("origin=root"); - self.0.address().clone() - }, - Origin::Signed(caller) => { - log::debug!("origin=signed({:?}) | contract({:?})", caller, self.0.address()); - caller - }, + Origin::Root => self.0.address().clone(), + Origin::Signed(caller) => caller, } } } From 7e231726671d42b669b447c7f801b6945f365c0e Mon Sep 17 00:00:00 2001 From: chungquantin <56880684+chungquantin@users.noreply.github.com> Date: Sat, 21 Sep 2024 10:39:49 +0700 Subject: [PATCH 112/112] fix: formatting --- extension/src/functions.rs | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/extension/src/functions.rs b/extension/src/functions.rs index 257efe89..0cbfbf48 100644 --- a/extension/src/functions.rs +++ b/extension/src/functions.rs @@ -323,8 +323,8 @@ mod tests { assert!(DispatchCallWithFilter::::execute(&mut env).is_err()); assert_eq!( env.charged(), - read_from_buffer_weight(encoded_call.len() as u32) - + call.get_dispatch_info().weight + read_from_buffer_weight(encoded_call.len() as u32) + + call.get_dispatch_info().weight ); } @@ -362,8 +362,8 @@ mod tests { assert!(DispatchCall::execute(&mut env).is_ok()); assert_eq!( env.charged(), - read_from_buffer_weight(encoded_call.len() as u32) - + call.get_dispatch_info().weight + read_from_buffer_weight(encoded_call.len() as u32) + + call.get_dispatch_info().weight ); }) } @@ -387,9 +387,9 @@ mod tests { assert_eq!(call.get_dispatch_info().weight, migrate_weight + weight_limit); assert_eq!( env.charged(), - read_from_buffer_weight(encoded_call.len() as u32) - + call.get_dispatch_info().weight - - extra_weight + read_from_buffer_weight(encoded_call.len() as u32) + + call.get_dispatch_info().weight - + extra_weight ); }) } @@ -488,8 +488,8 @@ mod tests { let expected = "pop".as_bytes().encode(); assert_eq!( env.charged(), - read_from_buffer_weight(encoded_read.len() as u32) - + read.weight() + write_to_contract_weight(expected.len() as u32) + read_from_buffer_weight(encoded_read.len() as u32) + + read.weight() + write_to_contract_weight(expected.len() as u32) ); }